/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/11/02, 17:08
!  AUTHOR(S): KOGA, Junichiro
!  File : MenuTree.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */

package ciss.phase_viewer.common;

import java.util.LinkedList;
import java.util.Vector;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;

import org.apache.log4j.Logger;

/**
 * JMenuの階層を制御するクラス. InputInterfaceクラスと似た仕組みだけど随分手抜き.
 * 
 * @author
 */
public class MenuTree {
    private Logger logger = Logger.getLogger(MenuTree.class.getName());
    private MenuBlock list = new MenuBlock(null, null);

    /** Creates a new instance of MenuTree */
    public MenuTree() {
        super();
    }

    /**
     * 「現在選択中」のブロックにJMenuを足しこむ.
     * 
     * @param menu
     *            足しこみたいJMenuオブジェクト.
     */
    public void addMenu(JMenu menu) {
        list.add(new MenuBlock(list, menu));
    }

    /**
     * 現在選択中のブロックに関連付けられたJMenuに指定のJMenuItemを足しこむ.
     * 
     * @param menuItem
     *            足しこみたいJMenuItemオブジェクト.
     */
    public void addMenuItem(JMenuItem menuItem) {
        addMenuItem(menuItem, false);
    }

    /**
     * 現在選択中のブロックに関連付けられたJMenuに指定のJMenuItemを足しこむ. 前にJSeparatorを付けたりできる.
     * 
     * @param menuItem
     *            足しこみたいJMenuItemオブジェクト.
     * @param hasSeparator
     *            JSeparatorを前に付けたい場合これを真にする.
     */
    public void addMenuItem(JMenuItem menuItem, boolean hasSeparator) {
        JMenu menu = list.getMenu();
        if (menu != null) {
            if (hasSeparator) {
                menu.add(new JSeparator());
            }
            menu.add(menuItem);
        }
    }

    /**
     * 現ブロックから指定のブロックを選択(存在しない場合作成する)
     * 
     * @param menu
     *            選択したいブロックのJMenuオブジェクト
     */
    public void selectBlock(JMenu menu) {
        String name = menu.getText();
        logger.debug("menu: " + menu);
        logger.debug("size of list: " + list.size());
        for (int i = 1; i < list.size(); i++) {
            MenuBlock bl = (MenuBlock) list.get(i);
            logger.debug("block: " + bl);
            if (name.trim().equals(bl.getName())) {
                list = bl;
                return;
            }
        }
        list.add(new MenuBlock(list, menu));
        selectBlock(menu);
    }

    /**
     * 現ブロックから指定のブロックを選択. この場合は存在することを仮定している が, しない場合一応簡単なJMenuオブジェクトを作成する.
     * 
     * @param name
     *            選択するブロックの名前.
     */
    public void selectBlock(String name) {
        for (int i = 1; i < list.size(); i++) {
            MenuBlock bl = (MenuBlock) list.get(i);
            logger.debug("block: " + bl);
            if (name.trim().equals(bl.getName())) {
                list = bl;
                return;
            }
        }
        JMenu menu = new JMenu(name);
        list.add(new MenuBlock(list, menu));
        selectBlock(menu);
    }

    /**
     * 現在選択中のブロックから, 一つ上のブロックを選択する.
     */
    public void selectParent() {
        list = (MenuBlock) list.get(0);
    }

    /**
     * ルートブロックを選択する.
     */
    public void selectRoot() {
        while (list.get(0) != null) {
            selectParent();
        }
    }

    public JMenu[] getMenus() {
        selectRoot();
        Vector menuvec = new Vector();
        for (int i = 1; i < list.size(); i++) {
            menuvec.addElement(((MenuBlock) list.get(i)).getMenu());
        }
        if (menuvec.size() == 0) {
            return null;
        }
        JMenu[] ret = new JMenu[menuvec.size()];
        menuvec.copyInto(ret);

        return ret;
    }

}

class MenuBlock extends LinkedList {
    private JMenu menu;

    protected MenuBlock(MenuBlock parent, JMenu menu) {
        add(parent);
        this.menu = menu;
        if (parent != null) {
            JMenu parentMenu = parent.getMenu();
            if (parentMenu != null) {
                parentMenu.add(menu);
            }
        }
    }

    protected JMenu getMenu() {
        return menu;
    }

    protected String getName() {
        return menu.getText();
    }

    public String toString() {
        return "name: " + getName();
    }

}
