/*
 * Copyright (c) 2002-2007 TeamDev Ltd. All rights reserved.
 *
 * Use is subject to license terms.
 *
 * The complete licence text can be found at
 * http://www.teamdev.com/winpack/license.jsf
 */
package teamdev.jxcapture.samples.demo;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ResourceBundle;

/**
 * @author Ikryanov Vladimir
 */
public class TrayPopupMenu extends JPopupMenu {

    private ResourceBundle resource = ApplicationSettings.getResourceBundle();
    private CaptureOperations operations = CaptureOperations.getInstance();

    private ObjectCaptureAction objectCaptureAction = new ObjectCaptureAction();
    private RegionCaptureAction regionCaptureAction = new RegionCaptureAction();
    private DesktopCaptureAction desktopCaptureAction = new DesktopCaptureAction();
    private ActiveWindowCaptureAction windowCaptureAction = new ActiveWindowCaptureAction();

    private boolean captureOperationEnabled = true;

    private JxCaptureDemo application;

    public TrayPopupMenu(JxCaptureDemo application) {
        this.application = application;

        configCaptureOperations();
        createGUI();

        addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals("captureOperationEnabled")) {
                    boolean enabled = ((Boolean) evt.getNewValue()).booleanValue();
                    windowCaptureAction.setEnabled(enabled);
                    objectCaptureAction.setEnabled(enabled);
                    regionCaptureAction.setEnabled(enabled);
                    desktopCaptureAction.setEnabled(enabled);
                }
            }
        });
    }

    private void createGUI() {
        JMenuItem activeWindowItem = new JMenuItem(windowCaptureAction);
        JMenuItem objectItem = new JMenuItem(objectCaptureAction);
        JMenuItem regionItem = new JMenuItem(regionCaptureAction);
        JMenuItem desktopItem = new JMenuItem(desktopCaptureAction);
        JMenuItem openImageItem = new JMenuItem(new OpenImageAction());
        JMenuItem settingsItem = new JMenuItem(new SettingsAction());
        JMenuItem aboutItem = new JMenuItem(new AboutAction());
        JMenuItem exitItem = new JMenuItem(new ExitAction());
        JRadioButtonMenuItem toViewerItem = new JRadioButtonMenuItem(new CaptureToViewerAction());
        JMenuItem toFileItem = new JRadioButtonMenuItem(new CaptureToFileAction());
        JMenuItem toClipboardItem = new JRadioButtonMenuItem(new CaptureToClipboardAction());

        ApplicationSettings settings = ApplicationSettings.getInstance();
        toViewerItem.setSelected(settings.isCaptureToViewer());
        toFileItem.setSelected(settings.isCaptureToFile());
        toClipboardItem.setSelected(settings.isCaptureToClipboard());

        JMenu captureToItem = new JMenu("Capture To");
        captureToItem.setIcon(new ImageIcon(ImageViewer.class.getResource("resources/images/empty.png")));
        captureToItem.add(toViewerItem);
        captureToItem.add(toClipboardItem);
        captureToItem.add(toFileItem);

        ButtonGroup group = new ButtonGroup();
        group.add(toViewerItem);
        group.add(toFileItem);
        group.add(toClipboardItem);

        add(activeWindowItem);
        add(objectItem);
        add(regionItem);
        add(desktopItem);
        add(openImageItem);
        addSeparator();
        add(captureToItem);
        addSeparator();
        add(settingsItem);
        add(aboutItem);
        addSeparator();
        add(exitItem);
    }

    private void configCaptureOperations() {
        operations.addCaptureOperationsListener(new CaptureOperations.CaptureOperationsListener() {
            public void operationBegin() {
                setCaptureOperationEnabled(false);
            }

            public void operationComplete(boolean isCanceled) {
                setCaptureOperationEnabled(true);
            }
        });
    }

    public void setCaptureOperationEnabled(boolean captureOperationEnabled) {
        boolean oldValue = this.captureOperationEnabled;
        this.captureOperationEnabled = captureOperationEnabled;
        firePropertyChange("captureOperationEnabled", oldValue, this.captureOperationEnabled);
    }

    private class ActiveWindowCaptureAction extends FullAction {
        public ActiveWindowCaptureAction() {
            super("ActiveWindow");
        }

        public void actionPerformed(ActionEvent event) {
            operations.activeWindowCapture();
        }
    }

    private class ObjectCaptureAction extends FullAction {
        public ObjectCaptureAction() {
            super("Object");
        }

        public void actionPerformed(ActionEvent e) {
            operations.objectCapture();
        }
    }

    private class RegionCaptureAction extends FullAction {
        public RegionCaptureAction() {
            super("Region");
        }

        public void actionPerformed(ActionEvent e) {
            operations.regionCapture();
        }
    }

    private class DesktopCaptureAction extends FullAction {
        public DesktopCaptureAction() {
            super("Screen");
        }

        public void actionPerformed(ActionEvent e) {
            operations.desktopCapture();
        }
    }

    private class OpenImageAction extends SimpleAction {
        private OpenImageAction() {
            super("OpenImage");
        }

        public void actionPerformed(ActionEvent e) {
            ImageFileChooser fileChooser = new ImageFileChooser();
            File imageFile = fileChooser.openImageFile();
            if (imageFile != null) {
                ImageViewer imageViewer = new ImageViewer();
                if (imageViewer.setImage(imageFile)) {
                    imageViewer.setVisible(true);
                    imageViewer.toFront();
                }
            }
        }
    }

    private class SettingsAction extends SimpleAction {
        public SettingsAction() {
            super("Settings");
        }

        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    SettingsDialog settingsDialog = SettingsDialog.getInstance();
                    settingsDialog.setVisible(true);
                    settingsDialog.toFront();
                }
            });
        }
    }

    private class AboutAction extends SimpleAction {
        public AboutAction() {
            super("About");
        }

        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    AboutDialog aboutDialog = AboutDialog.getInstance();
                    aboutDialog.setVisible(true);
                    aboutDialog.toFront();
                }
            });
        }
    }

    private class ExitAction extends SimpleAction {
        public ExitAction() {
            super("Exit");
        }

        public void actionPerformed(ActionEvent e) {
            application.close();
        }
    }

    private class CaptureToViewerAction extends AbstractAction {
        private CaptureToViewerAction() {
            super("ToViewer");
        }

        public void actionPerformed(ActionEvent e) {
            ApplicationSettings.getInstance().setCaptureToViewer();
        }
    }

    private class CaptureToFileAction extends AbstractAction {
        private CaptureToFileAction() {
            super("ToFile");
        }

        public void actionPerformed(ActionEvent e) {
            ApplicationSettings.getInstance().setCaptureToFile();
        }
    }

    private class CaptureToClipboardAction extends BaseAction {
        private CaptureToClipboardAction() {
            super("ToClipboard");
        }

        public void actionPerformed(ActionEvent e) {
            ApplicationSettings.getInstance().setCaptureToClipboard();
        }
    }

    private abstract class BaseAction extends AbstractAction {
        protected BaseAction(String actionName) {
            putValue(Action.NAME, resource.getString("TrayPopupMenu.Action." + actionName + ".Text"));
        }
    }

    private abstract class SimpleAction extends BaseAction {
        protected SimpleAction(String actionName) {
            super(actionName);
            String icon = resource.getString("TrayPopupMenu.Action." + actionName + ".Icon");
            putValue(Action.SMALL_ICON, new ImageIcon(ImageViewer.class.getResource(icon)));
        }
    }

    private abstract class FullAction extends SimpleAction {
        protected FullAction(String actionName) {
            super(actionName);
            String accelerator = resource.getString("TrayPopupMenu.Action." + actionName + ".Accelerator");
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accelerator));
        }
    }
}