/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.chemistry.opencmis.workbench;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URI;
import java.util.prefs.Preferences;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

import org.apache.chemistry.opencmis.commons.SessionParameter;
import org.apache.chemistry.opencmis.workbench.ClientHelper.FileEntry;
import org.apache.chemistry.opencmis.workbench.details.DetailsTabs;
import org.apache.chemistry.opencmis.workbench.icons.ChangeLogIcon;
import org.apache.chemistry.opencmis.workbench.icons.ConnectIcon;
import org.apache.chemistry.opencmis.workbench.icons.ConsoleIcon;
import org.apache.chemistry.opencmis.workbench.icons.CreateObjectIcon;
import org.apache.chemistry.opencmis.workbench.icons.InfoIcon;
import org.apache.chemistry.opencmis.workbench.icons.LogIcon;
import org.apache.chemistry.opencmis.workbench.icons.QueryIcon;
import org.apache.chemistry.opencmis.workbench.icons.RepositoryInfoIcon;
import org.apache.chemistry.opencmis.workbench.icons.TckIcon;
import org.apache.chemistry.opencmis.workbench.icons.TypesIcon;
import org.apache.chemistry.opencmis.workbench.model.ClientModel;
import org.apache.chemistry.opencmis.workbench.model.ClientSession;
import org.apache.chemistry.opencmis.workbench.types.TypesFrame;
import org.apache.chemistry.opencmis.workbench.worker.LoadFolderWorker;
import org.apache.chemistry.opencmis.workbench.worker.LoadObjectWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ClientFrame extends JFrame implements WindowListener {

    private static final long serialVersionUID = 1L;

    private static final Logger LOG = LoggerFactory.getLogger(ClientFrame.class);

    private static final String WINDOW_TITLE = "CMIS Workbench";

    private static final int BUTTON_CONNECT = 0;
    private static final int BUTTON_REPOSITORY_INFO = 1;
    private static final int BUTTON_TYPES = 2;
    private static final int BUTTON_QUERY = 3;
    private static final int BUTTON_CHANGELOG = 4;
    private static final int BUTTON_CONSOLE = 5;
    private static final int BUTTON_TCK = 6;
    private static final int BUTTON_CREATE = 7;
    private static final int BUTTON_LOG = 8;
    private static final int BUTTON_INFO = 9;

    private static final String PREFS_X = "x";
    private static final String PREFS_Y = "y";
    private static final String PREFS_WIDTH = "width";
    private static final String PREFS_HEIGHT = "height";
    private static final String PREFS_DIV = "div";

    private final Preferences prefs = Preferences.userNodeForPackage(this.getClass());

    private LoginDialog loginDialog;
    private LogFrame logFrame;
    private InfoDialog infoDialog;

    private JToolBar toolBar;
    private JButton[] toolbarButton;
    private JPopupMenu toolbarConsolePopup;
    private JPopupMenu toolbarCreatePopup;
    private JMenuItem documentMenuItem;
    private JMenuItem itemMenuItem;
    private JMenuItem folderMenuItem;
    private JMenuItem relationshipMenuItem;
    private JMenuItem policyMenuItem;

    private JSplitPane split;
    private FolderPanel folderPanel;
    private DetailsTabs detailsTabs;

    private final ClientModel model;

    public ClientFrame() {
        super();

        model = new ClientModel();
        createGUI();
        showLoginForm();
    }

    private void createGUI() {
        setTitle(WINDOW_TITLE);

        setIconImages(ClientHelper.getCmisIconImages());

        ImageIcon icon = ClientHelper.getCmisIconImage();
        boolean isDockImageSet = false;

        // Java >= 9 goodies
        try {
            Class<?> taskbarClass = Class.forName("java.awt.Taskbar");
            Object taskbar = taskbarClass.getMethod("getTaskbar").invoke(null);

            if (icon != null) {
                try {
                    taskbarClass.getMethod("setIconImage", Image.class).invoke(taskbar, icon.getImage());
                    isDockImageSet = true;
                } catch (Exception e) {
                    LOG.debug("Could not set taskbar icon!", e);
                }
            }
        } catch (Exception e) {
            // Java < 9
        }

        // Mac OS X goodies
        if (ClientHelper.isMacOSX()) {
            try {
                if (!isDockImageSet && icon != null) {
                    Class<?> macAppClass = Class.forName("com.apple.eawt.Application");
                    Object macApp = macAppClass.getMethod("getApplication").invoke(null);

                    try {
                        macAppClass.getMethod("setDockIconImage", Image.class).invoke(macApp, icon.getImage());
                    } catch (Exception e) {
                        LOG.debug("Could not set dock icon!", e);
                    }
                }

                try {
                    Class<?> fullscreenClass = Class.forName("com.apple.eawt.FullScreenUtilities");
                    fullscreenClass.getMethod("setWindowCanFullScreen", Window.class, Boolean.TYPE)
                            .invoke(fullscreenClass, this, true);
                } catch (Exception e) {
                    LOG.debug("Could not add fullscreen button!", e);
                }
            } catch (Exception e) {
                LOG.debug("Could not get com.apple.eawt.Application object!", e);
            }
        }

        setLayout(new BorderLayout());

        final ClientFrame thisFrame = this;
        loginDialog = new LoginDialog(this);
        logFrame = new LogFrame();
        infoDialog = new InfoDialog(this);

        Container pane = getContentPane();

        toolBar = new JToolBar("CMIS Toolbar", SwingConstants.HORIZONTAL);

        toolbarButton = new JButton[10];

        toolbarButton[BUTTON_CONNECT] = new JButton("Connection",
                new ConnectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_CONNECT].setDisabledIcon(
                new ConnectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_CONNECT].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showLoginForm();
            }
        });

        toolBar.add(toolbarButton[BUTTON_CONNECT]);

        toolBar.addSeparator();

        toolbarButton[BUTTON_REPOSITORY_INFO] = new JButton("Repository Info",
                new RepositoryInfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_REPOSITORY_INFO].setDisabledIcon(
                new RepositoryInfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(false);
        toolbarButton[BUTTON_REPOSITORY_INFO].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new RepositoryInfoFrame(model);
            }
        });

        toolBar.add(toolbarButton[BUTTON_REPOSITORY_INFO]);

        toolbarButton[BUTTON_TYPES] = new JButton("Types",
                new TypesIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_TYPES]
                .setDisabledIcon(new TypesIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_TYPES].setEnabled(false);
        toolbarButton[BUTTON_TYPES].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new TypesFrame(model);
            }
        });

        toolBar.add(toolbarButton[BUTTON_TYPES]);

        toolbarButton[BUTTON_QUERY] = new JButton("Query",
                new QueryIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_QUERY]
                .setDisabledIcon(new QueryIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_QUERY].setEnabled(false);
        toolbarButton[BUTTON_QUERY].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new QueryFrame(model);
            }
        });

        toolBar.add(toolbarButton[BUTTON_QUERY]);

        toolbarButton[BUTTON_CHANGELOG] = new JButton("Change Log",
                new ChangeLogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_CHANGELOG].setDisabledIcon(
                new ChangeLogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_CHANGELOG].setEnabled(false);
        toolbarButton[BUTTON_CHANGELOG].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new ChangeLogFrame(model);
            }
        });

        toolBar.add(toolbarButton[BUTTON_CHANGELOG]);

        toolbarButton[BUTTON_CONSOLE] = new JButton("Console",
                new ConsoleIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_CONSOLE].setDisabledIcon(
                new ConsoleIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_CONSOLE].setEnabled(false);
        toolbarButton[BUTTON_CONSOLE].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                toolbarConsolePopup.show(toolbarButton[BUTTON_CONSOLE], 0, toolbarButton[BUTTON_CONSOLE].getHeight());
            }
        });

        toolBar.add(toolbarButton[BUTTON_CONSOLE]);

        toolbarConsolePopup = new JPopupMenu();
        for (FileEntry fe : ConsoleHelper.readScriptLibrary()) {
            JMenuItem menuItem = new JMenuItem(fe.getName());
            final URI file = fe.getFile();
            menuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    ConsoleHelper.openConsole(ClientFrame.this, model, file);
                }
            });
            toolbarConsolePopup.add(menuItem);
        }

        toolbarButton[BUTTON_TCK] = new JButton("TCK",
                new TckIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_TCK]
                .setDisabledIcon(new TckIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_TCK].setEnabled(false);
        toolbarButton[BUTTON_TCK].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new TckDialog(thisFrame, model);
            }
        });

        toolBar.add(toolbarButton[BUTTON_TCK]);

        toolBar.addSeparator();

        toolbarCreatePopup = new JPopupMenu();
        documentMenuItem = new JMenuItem("Document");
        documentMenuItem.setEnabled(true);
        toolbarCreatePopup.add(documentMenuItem);
        documentMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new CreateDocumentDialog(thisFrame, model);
            }
        });

        itemMenuItem = new JMenuItem("Item");
        itemMenuItem.setEnabled(false);
        toolbarCreatePopup.add(itemMenuItem);
        itemMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new CreateItemDialog(thisFrame, model);
            }
        });

        folderMenuItem = new JMenuItem("Folder");
        folderMenuItem.setEnabled(true);
        toolbarCreatePopup.add(folderMenuItem);
        folderMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new CreateFolderDialog(thisFrame, model);
            }
        });

        relationshipMenuItem = new JMenuItem("Relationship");
        relationshipMenuItem.setEnabled(false);
        toolbarCreatePopup.add(relationshipMenuItem);
        relationshipMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new CreateRelationshipDialog(thisFrame, model);
            }
        });

        policyMenuItem = new JMenuItem("Policy");
        policyMenuItem.setEnabled(false);
        toolbarCreatePopup.add(policyMenuItem);
        policyMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new CreatePolicyDialog(thisFrame, model);
            }
        });

        toolbarButton[BUTTON_CREATE] = new JButton("Create Object",
                new CreateObjectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_CREATE].setDisabledIcon(
                new CreateObjectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_CREATE].setEnabled(false);
        toolbarButton[BUTTON_CREATE].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                toolbarCreatePopup.show(toolbarButton[BUTTON_CREATE], 0, toolbarButton[BUTTON_CREATE].getHeight());
            }
        });

        toolBar.add(toolbarButton[BUTTON_CREATE]);

        toolBar.addSeparator();

        toolbarButton[BUTTON_LOG] = new JButton("Log",
                new LogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_LOG]
                .setDisabledIcon(new LogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_LOG].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                logFrame.showFrame();
            }
        });

        toolBar.add(toolbarButton[BUTTON_LOG]);

        toolbarButton[BUTTON_INFO] = new JButton("Info",
                new InfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
        toolbarButton[BUTTON_INFO]
                .setDisabledIcon(new InfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
        toolbarButton[BUTTON_INFO].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                infoDialog.showDialog();
            }
        });

        toolBar.add(toolbarButton[BUTTON_INFO]);

        pane.add(toolBar, BorderLayout.PAGE_START);

        folderPanel = new FolderPanel(model);
        detailsTabs = new DetailsTabs(model);

        split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, folderPanel, detailsTabs);

        pane.add(split, BorderLayout.CENTER);

        addWindowListener(this);

        setMinimumSize(new Dimension(300, 100));

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int frameWidth = Math.max(prefs.getInt(PREFS_WIDTH, (int) (screenSize.getWidth() / 1.5)),
                (int) getMinimumSize().getWidth());
        int frameHeight = Math.max(prefs.getInt(PREFS_HEIGHT, (int) (screenSize.getHeight() / 1.5)),
                (int) getMinimumSize().getHeight());
        setPreferredSize(new Dimension(frameWidth, frameHeight));

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();

        split.setDividerLocation(prefs.getInt(PREFS_DIV, getPreferredSize().width / 4));

        if (prefs.getInt(PREFS_X, Integer.MAX_VALUE) == Integer.MAX_VALUE) {
            setLocationRelativeTo(null);
        } else {
            setLocation(prefs.getInt(PREFS_X, 0), prefs.getInt(PREFS_Y, 0));
        }

        setVisible(true);
    }

    private void showLoginForm() {
        loginDialog.showDialog();
        if (!loginDialog.isCanceled()) {
            ClientSession clientSession = loginDialog.getClientSession();

            model.setClientSession(clientSession);

            try {
                setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

                folderPanel.clear();

                LoadFolderWorker.loadFolderById(ClientFrame.this, model, clientSession.getStartFolderId());
                LoadObjectWorker.loadObject(ClientFrame.this, model, clientSession.getStartFolderId());

                toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(true);
                toolbarButton[BUTTON_TYPES].setEnabled(true);
                toolbarButton[BUTTON_QUERY].setEnabled(model.supportsQuery());
                toolbarButton[BUTTON_CHANGELOG].setEnabled(model.supportsChangeLog());
                toolbarButton[BUTTON_CONSOLE].setEnabled(true);
                toolbarButton[BUTTON_TCK].setEnabled(true);
                toolbarButton[BUTTON_CREATE].setEnabled(true);

                itemMenuItem.setEnabled(model.supportsItems());
                relationshipMenuItem.setEnabled(model.supportsRelationships());
                policyMenuItem.setEnabled(model.supportsPolicies());

                String user = clientSession.getSessionParameters().get(SessionParameter.USER);
                if (user != null) {
                    user = " - (" + user + ")";
                } else {
                    user = "";
                }

                setTitle(WINDOW_TITLE + user + " - " + clientSession.getSession().getRepositoryInfo().getName());
            } catch (Exception ex) {
                toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(false);
                toolbarButton[BUTTON_TYPES].setEnabled(false);
                toolbarButton[BUTTON_QUERY].setEnabled(false);
                toolbarButton[BUTTON_CHANGELOG].setEnabled(false);
                toolbarButton[BUTTON_CONSOLE].setEnabled(false);
                toolbarButton[BUTTON_TCK].setEnabled(false);
                toolbarButton[BUTTON_CREATE].setEnabled(false);

                ClientHelper.showError(null, ex);

                setTitle(WINDOW_TITLE);
            } finally {
                setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        }
    }

    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        Point p = getLocation();
        prefs.putInt(PREFS_X, p.x);
        prefs.putInt(PREFS_Y, p.y);
        prefs.putInt(PREFS_WIDTH, getWidth());
        prefs.putInt(PREFS_HEIGHT, getHeight());
        prefs.putInt(PREFS_DIV, split.getDividerLocation());
    }

    @Override
    public void windowClosed(WindowEvent e) {
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }
}
