/*
 * Copyright (c) 2007, Going Dot Com Inc. All rights reserved.
 */

package jp.co.going.xbrl.sample;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import jp.co.going.xbrl.sample.dao.XbContextScenarioDao;
import jp.co.going.xbrl.sample.dao.XbItemFootnoteDao;
import jp.co.going.xbrl.sample.dao.obj.XbMainEtcObj;

/**
 * @author Masako Okayasu
 */
@SuppressWarnings("serial")
public class XbTreeDataSet extends XbCommon implements ActionListener {

	public String param = null;
	public boolean prefixFlag = false;
	private XbMyTreeNode rootNode = null;

	public JTree tree = null;
	public DefaultTreeModel treeModel = null;
	public XbMyTreeNode selectNode = null;
	public String selectNodeName = null;
	public JPopupMenu popMenu = null;
	public JMenuItem[] popMenuItem = new JMenuItem[10];

	public boolean childFlag = false;
	public int menuFlag = 0;

	/**
	 * コンストラクタ
	 */
	public XbTreeDataSet() {}

	/**
	 * Tree形式入力欄の生成
	 */
	public JPanel TreePanel(
			String param,
			XbMyTreeNode rootNode,
			long contextID,
			boolean prefixFlag,
			Connection conn) {

		this.param = param;
		this.prefixFlag = prefixFlag;
		this.rootNode = rootNode;

		// Treeパネル作成
		JPanel MainPanel = new JPanel();
		MainPanel.setLayout(new BorderLayout());

		try {
			if(contextID != 0) {
				XbContextScenarioDao contextScenarioDao =null;
				XbItemFootnoteDao itemFootnoteDao = null;

				if(param.equals(SCENARIO)) {
					contextScenarioDao = XbContextScenarioDao.getInstance(conn);
				}
				else if(param.equals(FOOTNOTE)) {
					itemFootnoteDao = XbItemFootnoteDao.getInstance(conn);
				}

				HashMap<Long, TreePath> parent_id = new HashMap<Long, TreePath>();
				parent_id.put((long)0, new TreePath(rootNode.getPath()));

				// 枝ノードの生成
				Iterator ite = parent_id.entrySet().iterator();
				while(ite.hasNext()) {
					parent_id = new HashMap<Long, TreePath>();

					while(ite.hasNext()) {
						Entry ent = (Entry)ite.next();
						long key = (Long)ent.getKey();
						TreePath val = (TreePath)ent.getValue();
						XbMyTreeNode parentNode = (XbMyTreeNode)val.getLastPathComponent();

						ArrayList<XbMainEtcObj> list = null;
						if(param.equals(SCENARIO)) {
							list = contextScenarioDao.selectAll(contextID, key);
						}
						else if(param.equals(FOOTNOTE)) {
							list = itemFootnoteDao.selectAll(contextID, key);
						}
						parent_id = makeTreeNode(parent_id, key, parentNode, param, list);
					}

					ite = parent_id.entrySet().iterator();
			}	}

			// Treeの生成
			treeModel = new DefaultTreeModel(rootNode);
			tree = new JTree(treeModel);
			tree.setToggleClickCount(1);
			tree.setSelectionRow(0);
			selectNode = rootNode;

			for(int i=0; i<tree.getRowCount(); i++) {
				tree.expandRow(i);
			}

			JScrollPane scroll = new JScrollPane();
			scroll.getViewport().setView(tree);
			scroll.setPreferredSize(new Dimension(400, 200));
			MainPanel.add(scroll, BorderLayout.NORTH);

			JLabel tooltip = new JLabel(TOOLTIP1);
			tooltip.setFont(setFont(11));
			tooltip.setPreferredSize(new Dimension(400, 26));
			MainPanel.add(tooltip, BorderLayout.SOUTH);

			popTreeMenu();
			setTreeMouseAdapter();

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return MainPanel;
	}

	/**
	 * Tree構造の生成
	 */
	public HashMap<Long, TreePath> makeTreeNode(
			HashMap<Long, TreePath> parent_id,
			long key,
			XbMyTreeNode parentNode,
			String param,
			ArrayList<XbMainEtcObj> list
		) {

		if(list != null) {
			for(int j=0; j<list.size(); j++) {
				XbMainEtcObj obj = list.get(j);

				XbMyTreeNode node = null;
				if(key==0) {
					String nodeTitle = "<" + param + ">";
					if(prefixFlag==true) {
						nodeTitle = nodeTitle + "： Prefix=\"" + obj.getPrefix() + "\"　URI=\"" + obj.getUri() + "\"";
					}
					node = new XbMyTreeNode(nodeTitle);
					node.setID(0);
					parentNode.add(node);
				} else {
					node = parentNode;
				}

				XbMyTreeNode nameNode = new XbMyTreeNode(obj.getEtc_name());
				nameNode.setType(param);
				nameNode.setID(obj.getEtc_id());
				node.add(nameNode);

				parent_id.put(obj.getEtc_id(), new TreePath(nameNode.getPath()));
		}	}

		return parent_id;
	}

	/**
	 * 右クリックメニューの生成
	 */
	public void popTreeMenu() {
		popMenu = new JPopupMenu();

		if(menuFlag==0) {
			popMenuItem[0] = new JMenuItem(param + "追加");
			popMenuItem[0].addActionListener(this);
			popMenu.add(popMenuItem[0]);
		}

		if(prefixFlag==true && (menuFlag==1 || menuFlag==2)) {
			popMenuItem[1] = new JMenuItem("接頭辞の指定");
			popMenuItem[1].addActionListener(this);
			popMenu.add(popMenuItem[1]);
		}

		if(menuFlag==2 || menuFlag==3) {
			popMenuItem[2] = new JMenuItem("アイテム指定");
			popMenuItem[2].addActionListener(this);
			popMenu.add(popMenuItem[2]);
		}

		if(menuFlag==3) {
			popMenuItem[3] = new JMenuItem("子アイテム追加");
			popMenuItem[3].addActionListener(this);
			popMenu.add(popMenuItem[3]);
		}

		if(menuFlag != 0) {
			popMenuItem[4] = new JMenuItem("削除");
			popMenuItem[4].addActionListener(this);
			popMenu.add(popMenuItem[4]);
		}
	}

	/**
	 * MouseAdapterの登録
	 */
	public void setTreeMouseAdapter() {
		tree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				int selectRow = tree.getRowForLocation(e.getX(), e.getY());
				if(selectRow != -1) {
					tree.setSelectionRow(selectRow);
					selectNode = (XbMyTreeNode)tree.getLastSelectedPathComponent();
					selectNodeName = selectNode.getUserObject().toString();

					if(SwingUtilities.isRightMouseButton(e)) {
						if(selectNode == rootNode) {
							menuFlag = 0;
						} else if(selectNodeName.indexOf("　URI=") != -1) {
							menuFlag = 2;
						} else if(selectNodeName.indexOf("<" + param + ">") != -1) {
							if(prefixFlag==true) {
								menuFlag = 1;
							} else {
								menuFlag = 2;
							}
						} else {
							childFlag = true;
							menuFlag = 3;
						}
						popTreeMenu();
						popMenu.show(e.getComponent(), e.getX(), e.getY());
		}	}	}	});
	}

	/**
	 * Button, MenuItem のイベントを取得
	 */
	public void actionPerformed(ActionEvent e) {}

	/**
	 * TreePopMenuAction
	 */
	public void treePopMenuAction(Object source, String[] dataList) {
		if(source == popMenuItem[0]) {
			addNode("<" + param + ">");
		}
		else if(source == popMenuItem[1]) {
			if(setNodePrefix()) {
				submitButton.setEnabled(true);
		}	}
		else if(source == popMenuItem[2]) {
			if(setNodeValue(childFlag, dataList, dataList.length>0 ? dataList[0] : null, param)) {
				submitButton.setEnabled(true);
		}	}
		else if(source == popMenuItem[3]) {
			if(setNodeValue(false, dataList, dataList.length>0 ? dataList[0] : null, param)) {
				submitButton.setEnabled(true);
		}	}
		else if(source == popMenuItem[4]) {
			if(delNode()) {
				submitButton.setEnabled(true);
		}	}

		childFlag = false;

		treeModel.reload();
		tree.expandPath(new TreePath(selectNode));
		tree.setSelectionPath(new TreePath(selectNode.getPath()));
		selectNode = (XbMyTreeNode)tree.getLastSelectedPathComponent();
	}

	/**
	 * TreeNodeの追加
	 */
	public XbMyTreeNode addNode(String title) {
		XbMyTreeNode childNode = new XbMyTreeNode(title);
		childNode.setID(0);
		selectNode.add(childNode);
		return childNode;
	}

	/**
	 * 名前の入力欄の生成
	 */
	public void setNewNodeName() {
		Object newName = JOptionPane.showInputDialog(this, "新しい名前：", "入力", JOptionPane.INFORMATION_MESSAGE, null, null, selectNodeName.substring(selectNodeName.indexOf("： ")+2));
		if(newName != null && !newName.equals("")) {
			selectNode.setUserObject(selectNodeName.substring(0, selectNodeName.indexOf("： ")+2) + newName.toString().trim());
	}	}

	/**
	 * TreeNodeの削除
	 */
	public boolean delNode() {
		boolean rc = false;
		if(JOptionPane.showConfirmDialog(this, "削除してよろしいですか？") == JOptionPane.YES_OPTION) {
			selectNode.removeFromParent();
			rc = true;
		}
		return rc;
	}

	/**
	 * 値の入力欄の生成
	 */
	public boolean setNodeValue(boolean childFlag, String[] datalist, String defaultdata, String type) {
		boolean rc = false;
		Object field = JOptionPane.showInputDialog(this, "値の指定：", "入力", JOptionPane.INFORMATION_MESSAGE, null, datalist, defaultdata);
		if(field != null && !field.equals("")) {
			long ID = 0;
			String val = field.toString().trim();

			if(val.indexOf(". ") != -1) {
				ID = Long.valueOf(val.substring(0, val.indexOf(". ")));
				val = val.substring(val.indexOf(". ")+2);
			}

			if(childFlag==true) {
				selectNode.setUserObject(val);
				selectNode.setID(ID);
			}
			else {
				XbMyTreeNode node = selectNode;
				boolean flag = false;

				while(node.getID() != 0) {
					if(node.getID()==ID)  flag = true;
					node = (XbMyTreeNode)node.getParent();
				}

				if(flag==true) {
					JOptionPane.showMessageDialog(this, "同じ Prefix の中に同一 ID のものは登録できません。");
				}
				else {
					XbMyTreeNode fieldNode = new XbMyTreeNode(val);
					fieldNode.setType(type);
					fieldNode.setID(ID);
					selectNode.add(fieldNode);
			}	}
			rc = true;
		}
		return rc;
	}

	/**
	 * 接頭辞の入力欄の生成
	 */
	public boolean setNodePrefix() {
		String prefix = "", uri = "";
		boolean rc = false;

		if(selectNodeName.indexOf("： ") != -1) {
			String temp = selectNodeName.substring(selectNodeName.indexOf("Prefix=")+7).replace("\"", "");
			prefix = temp.substring(0, temp.indexOf("　"));
			uri = temp.substring(temp.indexOf("　URI=")+5);
		}

		Object newPrefix = JOptionPane.showInputDialog(this, "接頭辞名を入力して下さい：", "入力", JOptionPane.INFORMATION_MESSAGE, null, null, prefix);
		if(newPrefix != null && !newPrefix.equals(""))
		{
			Object newURI = JOptionPane.showInputDialog(this, "接頭辞のＵＲＩを入力して下さい：", "入力", JOptionPane.INFORMATION_MESSAGE, null, null, uri);
			if(newURI != null && !newURI.equals(""))
			{
				String val = "Prefix=\"" + newPrefix.toString().trim() + "\"　URI=\"" + newURI.toString().trim() + "\"";
				selectNode.setUserObject(selectNodeName.substring(0, selectNodeName.indexOf(">")+1) + "： " + val);
				rc = true;
		}	}
		return rc;
	}
}