/*
 * @(#)ViewMenuHandler.java  1.0  2011-01-14
 * 
 * Copyright (c) 2011 Werner Randelshofer
 * Staldenmattweg 2, Immensee, CH-6405, Switzerland.
 * All rights reserved.
 * 
 * The copyright of this software is owned by Werner Randelshofer. 
 * You may not use, copy or modify this software, except in  
 * accordance with the license agreement you entered into with  
 * Werner Randelshofer. For details see accompanying license terms.
 */
package ch.randelshofer.multishow;

import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.activation.CommandInfo;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import org.jhotdraw.app.Application;
import org.jhotdraw.app.Disposable;
import org.jhotdraw.app.View;
import org.jhotdraw.util.ResourceBundleUtil;

/**
 * {@code ViewMenuHandler}.
 *
 * @author Werner Randelshofer
 * @version 1.0 2011-01-14 Created.
 */
public class ViewMenuHandler implements PropertyChangeListener, Disposable {

    private Application app;
    private View view;
    private JMenu viewMenu;
    private JMenu viewAsMenu;
    private JMenu settingsMenu;
    private JMenuItem infoMenu;

    public ViewMenuHandler(Application app, View view, JMenu viewMenu) {
        this.app = app;
        this.view = view;
        this.viewMenu = viewMenu;
        this.viewAsMenu = new JMenu();
        this.settingsMenu = new JMenu();
        ResourceBundleUtil labels = ResourceBundleUtil.getBundle("ch.randelshofer.multishow.Labels");
        labels.configureMenu(viewAsMenu, "view.viewAs");
        labels.configureMenu(settingsMenu, "view.settings");

        this.infoMenu = new JMenuItem(app.getActionMap(view).get(InfoAction.ID));

        if (view == null) {
            app.addPropertyChangeListener(this);
        } else {
            view.addPropertyChangeListener(this);
            view.addDisposable(this);
        }
        updateViewAsMenu();
        updateViewAsSelection();
        updateViewMenu();
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        String name = evt.getPropertyName();
        if (name == Application.ACTIVE_VIEW_PROPERTY) {
            if (evt.getOldValue() instanceof View) {
                ((View) evt.getOldValue()).removePropertyChangeListener(this);
            }
            if (evt.getNewValue() instanceof View) {
                ((View) evt.getNewValue()).addPropertyChangeListener(this);
            }
            updateViewAsMenu();
            updateViewMenu();
        } else if (name == View.URI_PROPERTY) {
            updateViewAsMenu();
            updateViewMenu();
        } else if (name == MultiShowView.COMMAND_OBJECT_PROPERTY) {
            updateViewMenu();
        } else if (name == MultiShowView.SELECTED_COMMAND_INFO_PROPERTY) {
            updateViewAsSelection();
        }
    }

    @Override
    public void dispose() {
    }

    private void updateViewMenu() {
        MultiShowView v = (MultiShowView) (view == null ? app.getActiveView() : view);

        viewMenu.removeAll(); // FIXME - Only remove menus that we added
        viewMenu.add(viewAsMenu);
        viewMenu.add(settingsMenu);

        if (v == null || v.getURI() == null) {
            viewMenu.setEnabled(false);
            settingsMenu.setVisible(false);
        } else {
            viewMenu.setEnabled(true);
            settingsMenu.removeAll();
            viewMenu.add(infoMenu);
            if (view != null) {
                Object commandObject = v.getCommandObject();
                if (commandObject instanceof ch.randelshofer.view.View) {
                    ch.randelshofer.view.View vv = (ch.randelshofer.view.View) commandObject;
                    viewMenu.addSeparator();
                    vv.mergeViewMenuItems(viewMenu);
                    vv.mergeSettingsMenuItems(settingsMenu);
                }
                settingsMenu.setVisible(
                        settingsMenu.getMenuComponentCount() > 0);
            }
        }
    }

    private void updateViewAsMenu() {
        MultiShowView v = (MultiShowView) (view == null ? app.getActiveView() : view);

        if (v == null || v.getURI() == null) {
            viewAsMenu.setEnabled(false);
        } else {
            viewAsMenu.setEnabled(true);
            viewAsMenu.removeAll();

            CommandInfo[] infos = v.getCommandInfos();
            ButtonGroup itemGroup = new ButtonGroup();
            for (int i = 0; i < infos.length; i++) {
                String commandName = infos[i].getCommandName();
                if (commandName.startsWith("View")) {
                    if (commandName.startsWith("View as")) {
                        commandName = commandName.substring(8);
                    } else {
                        commandName = commandName.substring(5);
                    }
                    JCheckBoxMenuItem item = new JCheckBoxMenuItem(commandName);
                    item.putClientProperty("commandInfo", infos[i]);
                    item.addActionListener(new ViewAsAction(v, infos[i]));
                    viewAsMenu.add(item);
                    itemGroup.add(item);
                }
            }
            updateViewAsSelection();
        }

    }

    private void updateViewAsSelection() {
        MultiShowView v = (MultiShowView) (view == null ? app.getActiveView() : view);
        if (v != null) {
            CommandInfo[] infos = v.getCommandInfos();
            CommandInfo selectedInfo = v.getSelectedInfo();
            for (Component c : viewAsMenu.getMenuComponents()) {
                if (c instanceof JCheckBoxMenuItem) {
                    JCheckBoxMenuItem item = (JCheckBoxMenuItem) c;
                    CommandInfo info = (CommandInfo) item.getClientProperty("commandInfo");
                    item.setSelected(selectedInfo != null && info.getCommandClass().equals(selectedInfo.getCommandClass())
                            && info.getCommandName().equals(selectedInfo.getCommandName()));
                }
            }
        }
    }
}
