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

package jp.co.going.xbrl.sample;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import jp.co.going.xbrl.common.XbContextIdList;
import jp.co.going.xbrl.common.XbRef;
import jp.co.going.xbrl.common.XbRefList;
import jp.co.going.xbrl.common.XbException;
import jp.co.going.xbrl.instance.XbCreator;
import jp.co.going.xbrl.sample.dao.XbContextDao;
import jp.co.going.xbrl.sample.dao.XbContextUnitDao;
import jp.co.going.xbrl.sample.dao.XbEntityDao;
import jp.co.going.xbrl.sample.dao.XbItemDao;
import jp.co.going.xbrl.sample.dao.XbRefDao;
import jp.co.going.xbrl.sample.dao.XbTupleDataDao;
import jp.co.going.xbrl.sample.dao.obj.XbContextObj;
import jp.co.going.xbrl.sample.dao.obj.XbContextUnitObj;
import jp.co.going.xbrl.sample.dao.obj.XbEntityObj;
import jp.co.going.xbrl.sample.dao.obj.XbItemInterfaceObj;
import jp.co.going.xbrl.sample.dao.obj.XbItemObj;
import jp.co.going.xbrl.sample.dao.obj.XbRefObj;
import jp.co.going.xbrl.sample.dao.obj.XbTupleDataObj;

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

	private Connection conn = null;
	private XbItemDao itemDao = null;
	private XbTupleDataDao tupleDataDao = null;
	private XbContextDao contextDao = null;
	private XbEntityDao entityDao = null;
	private XbContextUnitDao contextUnitDao = null;
	private XbRefDao refDao = null;

	private XbMyTreeNode rootNode = new XbMyTreeNode("（登録済リスト）");
	private XbMyTreeNode nonTupleNode = new XbMyTreeNode("（ﾀﾌﾟﾙ以外で使用する Context の指定 （複数可））");
	private JButton expButton = new JButton("展開");
	private JButton upButton = new JButton("▲");
	private JButton downButton = new JButton("▼");
	private JButton fileButton = null;
	private JTextField fileNameField = null;

	private String tooltip0 = "　※ Ctrl + クリック で複数選択できます。";
	private JLabel contextToolTip = null;

	private JList contextList = null;
	private JList refList = null;
	private JList userDataList = null;
	private DefaultListModel contextListModel = null;
	private DefaultListModel userDataListModel = null;
	private TreeMap<Long, Integer> ContextIdSet = new TreeMap<Long, Integer>();
	private int[] nonTupleContext = null;
	private XbContextIdList XbContextIdList = null;
	private XbRefList XbRefList = null;

	private HashMap<String, String[]> userDataMap = new HashMap<String, String[]>();
	private XbMyTreeNode parentNode = null;
	private int parentRow = 0;
	private int selectRow = 0;

	private long instanceID = 0;
	private String version = null;
	private HashMap<Long, Integer> tupleCount = new HashMap<Long, Integer>();
	private boolean nodeFlag = false;

	private ProgressMonitor progressBar = null;
	private Timer progressTimer = null;
	private int progressCount = 0;
	private boolean finishFlag = false;

	static private int progressMin = 0;
	static private int progressMax = 100;

	/**
	 * コンストラクタ
	 */
	public XbCreateInstance(long instanceID, String instanceName, String itemLang, String version) {
		this.instanceID = instanceID;
		this.version = version;

		setTitle("XBRL Toolkit : Output Instance");
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		addWindowListener(new WindowAdapter() {
			public void windowClosed(WindowEvent e) {
				try {
						// 接続をクローズ
						conn.close();
					} catch (SQLException ex) {
						ex.printStackTrace();
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			});

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		conn = getConnection();
		itemDao = XbItemDao.getInstance(conn);
		tupleDataDao = XbTupleDataDao.getInstance(conn);
		contextDao = XbContextDao.getInstance(conn);
		entityDao = XbEntityDao.getInstance(conn);
		contextUnitDao = XbContextUnitDao.getInstance(conn);
		refDao = XbRefDao.getInstance(conn);


		GridBagLayout layout = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		Container container = getContentPane();
		container.setLayout(layout);

		JPanel TaxPanel = TuplePanel(instanceName, itemLang);
		gbc = setGrid(0, 0, gbc);
		gbc.gridwidth = 1;
		gbc.gridheight = 2;
		layout.setConstraints(TaxPanel, gbc);

		JPanel DataPanel = DataPanel();
		gbc = setGrid(1, 0, gbc);
		gbc.gridwidth = 1;
		gbc.gridheight = 2;
		layout.setConstraints(DataPanel, gbc);

		JPanel ContextPanel = ContextPanel();
		layout.setConstraints(ContextPanel, setGrid(2, 0, gbc));

		JPanel RefPanel = RefPanel();
		layout.setConstraints(RefPanel, setGrid(2, 1, gbc));

		JPanel FileNamePanel = FileNamePanel();
		gbc = setGrid(0, 2, gbc);
		gbc.gridwidth = 3;
		gbc.gridheight = 1;
		layout.setConstraints(FileNamePanel, gbc);

		JPanel SubmitPanel = SubmitPanel();
		gbc = setGrid(0, 3, gbc);
		gbc.gridwidth = 3;
		gbc.gridheight = 1;
		layout.setConstraints(SubmitPanel, gbc);

		submitButton.setText("作　　成");
		submitButton.addActionListener(this);
		closeButton.addActionListener(this);

		container.add(TaxPanel);
		container.add(DataPanel);
		container.add(ContextPanel);
		container.add(RefPanel);
		container.add(FileNamePanel);
		container.add(SubmitPanel);

		progressTimer = new Timer(500, this);

		pack();
	}

	/**
	 * タプルツリーHeader欄の生成
	 */
	private JPanel TupleHeader() {
		JPanel HeaderPanel = new JPanel();
		HeaderPanel.setLayout(new BorderLayout());

		HeaderPanel.add(new JLabel("　【 指定済タプル一覧 】"), BorderLayout.WEST);

		JPanel flowPanel = new JPanel();
		flowPanel.setLayout(new FlowLayout());
		flowPanel.add(upButton);
		flowPanel.add(downButton);
		flowPanel.add(expButton);
		upButton.addActionListener(this);
		downButton.addActionListener(this);
		expButton.addActionListener(this);

		HeaderPanel.add(flowPanel, BorderLayout.EAST);

		return HeaderPanel;
	}

	/**
	 * タプルツリーの生成
	 */
	private JPanel TuplePanel(String instanceName, String itemLang) {
		JPanel TuplePanel = new JPanel();
		TuplePanel.setLayout(new BorderLayout());

		TuplePanel.add(TupleHeader(), BorderLayout.NORTH);

		try {
			rootNode = new XbMyTreeNode("（" + instanceName + "）");
			rootNode.setItemOrder(0);
			rootNode.setType("root");
			rootNode.setContextID(0);

			HashMap<Long, TreePath> parent_id = new HashMap<Long, TreePath>();
			ArrayList<XbItemObj> list1 = itemDao.selectTuple(instanceID, itemLang);
			XbMyTreeNode parentNode = null;

			for(int i=0; i<list1.size(); i++) {
				XbItemObj obj = list1.get(i);

				if(tupleCount.get(obj.getTaxonomy_item_id())==null) {
					tupleCount.put(obj.getTaxonomy_item_id(), 0);
				}
				int nowCount = tupleCount.get(obj.getTaxonomy_item_id());

				XbMyTreeNode tupleNode = new XbMyTreeNode(obj.getItem_name());
				tupleNode.setItemOrder(obj.getItem_order());
				tupleNode.setType(obj.getItem_type());
				tupleNode.setID(obj.getTaxonomy_item_id());
				tupleNode.setSeq(nowCount + 1);
				tupleNode.setUserItemID(obj.getUser_item_id());
				tupleNode.setContextID(0);

				parent_id.put(obj.getTaxonomy_item_id(), new TreePath(tupleNode.getPath()));
				tupleCount.put(obj.getTaxonomy_item_id(), nowCount + 1);

				// 親ノード積み上げ
				do {
					if(parent_id.get(obj.getParent_taxonomy_item_id()) != null) {
						parentNode = (XbMyTreeNode)parent_id.get(obj.getParent_taxonomy_item_id()).getLastPathComponent();
						parentNode.add(tupleNode);
						break;
					}
					else {
						obj = itemDao.select(instanceID, obj.getParent_taxonomy_item_id(), itemLang);
						if(obj != null) {
							if(tupleCount.get(obj.getTaxonomy_item_id())==null) {
								tupleCount.put(obj.getTaxonomy_item_id(), 0);
							}
							nowCount = tupleCount.get(obj.getTaxonomy_item_id());

							parentNode = new XbMyTreeNode(obj.getItem_name());
							parentNode.setItemOrder(obj.getItem_order());
							parentNode.setType(obj.getItem_type());
							parentNode.setID(obj.getTaxonomy_item_id());
							parentNode.setSeq(nowCount + 1);
							parentNode.setUserItemID(obj.getUser_item_id());
							parentNode.setContextID(0);
							parentNode.add(tupleNode);

							parent_id.put(obj.getTaxonomy_item_id(), new TreePath(parentNode.getPath()));
							tupleCount.put(obj.getTaxonomy_item_id(), nowCount + 1);
							rootNode.add(parentNode);
							tupleNode = parentNode;
						}
					}
				}
				while(obj != null);
			}

			// タプル以外のデータで使用するコンテキストの指定
			nonTupleNode.setItemOrder(0);
			nonTupleNode.setType("nonTuple");
			nonTupleNode.setContextID(0);
			rootNode.add(nonTupleNode);

			treeModel = new DefaultTreeModel(rootNode);
			tree = new JTree(treeModel);
			tree.setScrollsOnExpand(true);
			tree.setToggleClickCount(1);
			tree.setSelectionRow(0);
			selectNode = rootNode;

			JScrollPane scroll = new JScrollPane();
			scroll.getViewport().setView(tree);
			scroll.setPreferredSize(new Dimension(320, 290));
			TuplePanel.add(scroll, BorderLayout.CENTER);

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

			popMenu();
			setMouseAdapter();

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

		return TuplePanel;
	}

	/**
	 * ユーザデータ Header欄の生成
	 */
	private JPanel DataHeader() {
		JPanel DataHeader = new JPanel();
		DataHeader.setLayout(new BorderLayout());

		JPanel title = setPanel(new JLabel("（データマッチング）"));
		title.setPreferredSize(new Dimension(90, 30));
		DataHeader.add(title, BorderLayout.NORTH);

		return DataHeader;
	}

	/**
	 * ユーザデータリスト欄の生成
	 */
	private JPanel DataPanel() {
		JPanel DataPanel = new JPanel();
		DataPanel.setLayout(new BorderLayout());

		DataPanel.add(DataHeader(), BorderLayout.NORTH);

		userDataListModel = new DefaultListModel();
		userDataList = new JList(userDataListModel);
		userDataList.addListSelectionListener(this);

		JScrollPane scroll = new JScrollPane();
		scroll.getViewport().setView(userDataList);
		scroll.setPreferredSize(new Dimension(90, 100));
		DataPanel.add(scroll, BorderLayout.CENTER);

		JLabel tooltip = new JLabel("<html>実データを表示します。<br>左のフォルダとマッチング<br>させてください。</html>");
		tooltip.setFont(setFont(11));
		DataPanel.add(tooltip, BorderLayout.SOUTH);

		return DataPanel;
	}

	/**
	 * Context Header欄の生成
	 */
	private JPanel ContextHeader() {
		JPanel ContextHeader = new JPanel();
		ContextHeader.setLayout(new BorderLayout());

		JPanel title = setPanel(new JLabel("　【 Context 一覧 】"));
		title.setPreferredSize(new Dimension(200, 30));
		ContextHeader.add(title, BorderLayout.NORTH);

		return ContextHeader;
	}

	/**
	 * Contextリスト欄の生成
	 */
	private JPanel ContextPanel() {
		JPanel ContextPanel = new JPanel();
		ContextPanel.setLayout(new BorderLayout());

		ContextPanel.add(ContextHeader(), BorderLayout.NORTH);

		try {
			contextListModel = new DefaultListModel();

			ArrayList<XbContextObj> list = contextDao.selectAll();
			for(int i=0; i<list.size(); i++) {
				XbContextObj obj = list.get(i);
				contextListModel.addElement(obj.getContext_id() + ". " + obj.getContext_name());
			}

			contextList = new JList(contextListModel);
			contextList.addListSelectionListener(this);
			contextList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

			JScrollPane scroll = new JScrollPane();
			scroll.getViewport().setView(contextList);
			ContextPanel.add(scroll, BorderLayout.CENTER);

			contextToolTip = new JLabel(" ");
			contextToolTip.setFont(setFont(11));
			ContextPanel.add(contextToolTip, BorderLayout.SOUTH);

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

		return ContextPanel;
	}


	/**
	 * Ref Header欄の生成
	 */
	private JPanel RefHeader() {
		JPanel RefHeader = new JPanel();
		RefHeader.setLayout(new BorderLayout());

		JPanel title = setPanel(new JLabel("　【 Ref 一覧 】"));
		title.setPreferredSize(new Dimension(200, 30));
		RefHeader.add(title, BorderLayout.NORTH);

		return RefHeader;
	}

	/**
	 * Refリスト欄の生成
	 */
	private JPanel RefPanel() {
		JPanel RefPanel = new JPanel();
		RefPanel.setLayout(new BorderLayout());

		RefPanel.add(RefHeader(), BorderLayout.NORTH);

		try {
			ArrayList<XbRefObj> list = refDao.selectAll();
			String[] dataList = new String[list.size()];

			for(int i=0; i<list.size(); i++) {
				XbRefObj obj = list.get(i);

				Iterator ite = refType.entrySet().iterator();
				while(ite.hasNext()) {
					Entry ent = (Entry)ite.next();
					String key = (String)ent.getKey();
					int val = (Integer)ent.getValue();

					if(val == obj.getRef_type()) {
						dataList[i] = key + "  /  " + obj.getRef_id() + ". " + obj.getRef_name();
						break;
			}	}	}

			refList = new JList(dataList);

			JScrollPane scroll = new JScrollPane();
			scroll.getViewport().setView(refList);
			RefPanel.add(scroll, BorderLayout.CENTER);

			JLabel tooltip = new JLabel(tooltip0);
			tooltip.setFont(setFont(11));
			RefPanel.add(tooltip, BorderLayout.SOUTH);

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

		return RefPanel;
	}

	/**
	 * インスタンス文書ファイルパス指定欄の生成
	 */
	private JPanel FileNamePanel() {
		JPanel FileNamePanel = new JPanel();
		FileNamePanel.setLayout(new BorderLayout());

		fileNameField = new JTextField();
		fileNameField.setFocusAccelerator('d');

		fileButton = new JButton("参照");
		fileButton.addActionListener(this);

		FileNamePanel.add(new JLabel("　【 インスタンス文書ファイルパス 】　"), BorderLayout.WEST);
		FileNamePanel.add(fileNameField, BorderLayout.CENTER);
		FileNamePanel.add(fileButton, BorderLayout.EAST);

		return FileNamePanel;
	}

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

		if(menuFlag==2 && contextListModel.getSize() > 0 && contextList.getSelectedValue() != null) {
			popMenuItem[0] = new JMenuItem("データ指定");
			popMenuItem[0].addActionListener(this);
			popMenu.add(popMenuItem[0]);
		}

		if(menuFlag==1) {
			popMenuItem[1] = new JMenuItem("コピー");
			popMenuItem[1].addActionListener(this);
			popMenu.add(popMenuItem[1]);
		}

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

	/**
	 * MouseAdapterの登録
	 */
	private void setMouseAdapter() {
		tree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				selectRow = tree.getRowForLocation(e.getX(), e.getY());
				if(selectRow > 0) {
					tree.setSelectionRow(selectRow);
					selectNode = (XbMyTreeNode)tree.getLastSelectedPathComponent();
					selectNodeName = selectNode.getUserObject().toString();

					parentNode = (XbMyTreeNode)selectNode.getParent();
					parentRow = tree.getRowForPath(new TreePath(parentNode.getPath()));

					if(contextList.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) {
						contextList.removeSelectionInterval(0, contextListModel.getSize() - 1);
					}

					if(selectNode == nonTupleNode) {
						contextList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
						contextToolTip.setText(tooltip0);
						if(nonTupleContext != null)  contextList.setSelectedIndices(nonTupleContext);
					}
					else {
						contextList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
						contextToolTip.setText(" ");
					}

					if(contextListModel.getSize() > 0 && contextList.getSelectedValue() != null) {
						String contextName = contextList.getSelectedValue().toString();
						long contextID = Long.valueOf(contextName.substring(0, contextName.indexOf(". ")));
						selectNode.setContextID(contextID);

						userDataListModel.clear();
					}

					if(SwingUtilities.isRightMouseButton(e)) {
						if(selectNode.getType().equals(TAX_TUPLE)) {
							menuFlag = 1;
						} else if(selectNode.isLeaf()==true && selectNode != nonTupleNode) {
							menuFlag = 2;
						} else {
							menuFlag = 3;
						}
						popMenu();
						popMenu.show(e.getComponent(), e.getX(), e.getY());
		}	}	}	});
	}

	/**
	 * JList イベント
	 */
	public void valueChanged(ListSelectionEvent e) {
		Object source = e.getSource();

		if(e.getValueIsAdjusting()==true) {
			if(source == userDataList) {
				if(parentNode.getType().equals(TAX_TUPLE) && selectNode.getType().equals(TAX_ITEM)) {
					Object[] tempObj = userDataList.getSelectedValues();
					String[] tempStr = new String[tempObj.length];

					for(int i=0; i<tempObj.length; i++) {
						tempStr[i] = tempObj[i].toString();
					}
					userDataMap.put(String.valueOf(selectNode.getID() + "-" + selectNode.getSeq()), tempStr);
			}	}
			else if(source == contextList) {
				if(selectNode != nonTupleNode) {
					String contextName = contextList.getSelectedValue().toString();
					long contextID = Long.valueOf(contextName.substring(0, contextName.indexOf(". ")));
					selectNode.setContextID(contextID);
				}
				else {
					Object[] tempObj = contextList.getSelectedValues();
					nonTupleContext = new int[tempObj.length];

					for(int i=0; i<tempObj.length; i++) {
						for(int j=0; j<contextListModel.getSize(); j++) {
							if(tempObj[i].toString().equals(contextListModel.get(j))) {
								nonTupleContext[i] = j;
								break;
	}	}	}	}	}	}	}

	/**
	 * Button のイベントを取得
	 */
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		if(source == popMenuItem[0]) {
			try {
				XbContextObj context = contextDao.select(selectNode.getContextID());
				XbEntityObj entity = entityDao.select(context.getEntity_id());
				ArrayList<XbContextUnitObj> unitList = contextUnitDao.selectAll(selectNode.getContextID());

				ArrayList<XbItemInterfaceObj> list = tupleDataDao.selectItemInt(
						selectNode.getUserItemID(),
						entity.getEntity_name(),
						context.getPeriod_start_date(),
						context.getPeriod_end_date(),
						unitList.get(0).getUnit_name()
				);

				int[] index = new int[]{};
				int n = 0;
				for(int i=0; i<list.size(); i++) {
					XbItemInterfaceObj obj = list.get(i);
					userDataListModel.addElement(obj.getItem_value());

					String[] temp = userDataMap.get(String.valueOf(selectNode.getID() + "-" + selectNode.getSeq()));
					if(temp != null) {
						index = new int[temp.length];

						for(int j=0; j<temp.length; j++) {
							if(temp[j].equals(obj.getItem_value())) {
								index[n] = i;
								n++;
								break;
				}	}	}	}

				userDataList.setSelectedIndices(index);

			} catch (Exception ex) {
				ex.printStackTrace();
		}	}
		else if(source == popMenuItem[1]) {
			XbMyTreeNode tempNode = (XbMyTreeNode)selectNode.clone();
			tempNode.setSeq(selectNode.getSeq() + 1);
			copyNode(selectNode, tempNode);

			parentNode.add(tempNode);
			reSelectNode(tempNode);
		}
		else if(source == popMenuItem[2]) {
			if(delNode()) {
				reSelectNode(parentNode);
		}	}
		else if(source == upButton) {
			moveNode(true);
		}
		else if(source == downButton){
			moveNode(false);
		}
		else if(source == fileButton) {
			JFileChooser fileChooser = new JFileChooser();
			fileChooser.setDialogTitle("インスタンス文書ファイルの選択");
			fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

			if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
				File file = fileChooser.getSelectedFile();
				fileNameField.setText(file.getPath());
		}	}
		else if(source == submitButton){
			try {
				/**
				 * インスタンス文書作成処理
				 * XbCreator creator = new XbCreator(conn);
				 * creator.createInstance(taxGroupId, contextIdList, refList, version)
				 * creator.createXbrlFile(fileName)
				 */
				tupleDataDao.delete();
				getNodeValue(rootNode);
				conn.commit();

				// 選択済の Context リスト
				XbContextIdList = new XbContextIdList();

				Iterator ite = ContextIdSet.entrySet().iterator();
				while(ite.hasNext()) {
					Entry ent = (Entry)ite.next();
					long key = (Long)ent.getKey();
					XbContextIdList.add(String.valueOf(key));
				}

				for(int i=0; i<nonTupleContext.length; i++) {
					String temp = contextListModel.get(nonTupleContext[i]).toString();
					String id = temp.substring(0, temp.indexOf(". "));
					if(!XbContextIdList.contains(id))  XbContextIdList.add(id);
				}

				// 入力チェック
				if(XbContextIdList.size()==0) {
					JOptionPane.showMessageDialog(this, "Contextを指定して下さい。");
				}
				else if(fileNameField.getText().equals("")) {
					JOptionPane.showMessageDialog(this, "インスタンス文書ファイルパスを指定して下さい。");
				}
				else {
					// 選択済の Ref リスト
					XbRefList = new XbRefList();
					for(int i=0; i<refList.getSelectedValues().length; i++) {
						String temp = refList.getSelectedValues()[i].toString();
						String type = temp.substring(0, temp.indexOf("  /  "));
						temp = temp.substring(temp.indexOf("  /  ") + 5);
						String id = temp.substring(0, temp.indexOf(". "));

						XbRef obj = new XbRef();
						obj.setRefType(String.valueOf(refType.get(type)));
						obj.setRefId(id);
						XbRefList.add(obj);
					}

					// インスタンス文書の作成
					if(JOptionPane.showConfirmDialog(this,
							"インスタンス文書作成を開始します。よろしいですか？\n\n" + fileNameField.getText()) == JOptionPane.YES_OPTION) {

						finishFlag = false;
						Thread thread = new Thread(new Runnable() {
							public void run() {
								try {
									// インスタンス文書作成クラスの呼び出し
									XbCreator creator = new XbCreator(conn);
									creator.createInstance(String.valueOf(instanceID), XbContextIdList, XbRefList, version);
									creator.createXbrlFile(fileNameField.getText());
									conn.commit();
									finishFlag = true;
								}
								catch (XbException err) {
									try {
										err.printStackTrace();
										conn.rollback();
									}
									catch (Exception ex) {
										ex.printStackTrace();
								}	}
								catch (Exception ex) {
									ex.printStackTrace();
							}	}
						});
						thread.start();

						progressCount = progressMin;
						progressBar = new ProgressMonitor(this, "インスタンス文書 ：", "作成中 ...", progressMin, progressMax);
						progressTimer.start();
				}	}
			} catch (Exception ex) { 
				ex.printStackTrace();
		}	}
		else if(source == closeButton){
			this.setVisible(false);
		}
		else if(source == progressTimer){
			if(finishFlag==true) {
				progressTimer.stop();
				progressBar.close();
				JOptionPane.showMessageDialog(this, "インスタンス文書の作成を完了しました。");
			}
			else if(progressBar.isCanceled()) {
				progressTimer.stop();
				try {
					conn.rollback();
				}
				catch (Exception ex) {
					ex.printStackTrace();
				}
				JOptionPane.showMessageDialog(this, "キャンセルされました。");
			}
			else if(progressCount < progressMax) {
				progressBar.setProgress(progressCount);
				progressCount++;
		}	}

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

	/**
	 * ノードのコピー
	 */
	private void copyNode(XbMyTreeNode parentNode, XbMyTreeNode copyNode) {
		for(int i=0; i<parentNode.getChildCount(); i++) {
			XbMyTreeNode childNode = (XbMyTreeNode)parentNode.getChildAt(i);
			XbMyTreeNode copyChildNode = (XbMyTreeNode)childNode.clone();

			int nowCount = tupleCount.get(childNode.getID());
			copyChildNode.setSeq(nowCount + 1);
			copyNode.add(copyChildNode);
			tupleCount.put(childNode.getID(), nowCount + 1);

			// さらに深部へ
			if(childNode.getChildCount() > 0) {
				copyNode(childNode, copyChildNode);
	}	}	}

	/**
	 * ノードの移動
	 */
	private void moveNode(boolean flag) {
		if(selectNode.getType().equals(TAX_TUPLE)) {
			int index = 0;

			if(flag==true) {
				if(selectRow <= (parentRow + 1))  return;
				index = selectRow - parentRow - 2;
				selectRow--;
			} else {
				if(selectRow >= (parentNode.getChildCount() + parentRow))  return;
				index = selectRow - parentRow;
				selectRow++;
			}

			parentNode.insert(selectNode, index);
			reSelectNode(selectNode);
	}	}

	/**
	 * ノードの再選択
	 */
	private void reSelectNode(XbMyTreeNode Node) {
		treeModel.reload();
		tree.expandPath(new TreePath(Node.getPath()));
		tree.setSelectionPath(new TreePath(Node.getPath()));

		selectNode = (XbMyTreeNode)tree.getLastSelectedPathComponent();
		selectRow = tree.getSelectionRows()[0];
	}

	/**
	 * ノードの値を取得
	 */
	private void getNodeValue(XbMyTreeNode Node) {
		try {
			for(int i=0; i<Node.getChildCount(); i++) {
				XbMyTreeNode childNode = (XbMyTreeNode)Node.getChildAt(i);

				if(Node.getType().equals(TAX_ITEM) && childNode.getType().equals(TAX_TUPLE)) {
					nodeFlag = true;
				}

				if((Node.getType().equals(TAX_ITEM) && childNode.getType().equals(TAX_ITEM))
						|| childNode.getType().equals("nonTuple")) {
					nodeFlag = false;
				}

				if(nodeFlag==true) {

					// コンテキストIDの設定
					if(childNode.getContextID() > 0) {
						ContextIdSet.put(childNode.getContextID(), 0);
					}

					// TupleData の設定
					String[] userData = userDataMap.get(String.valueOf(childNode.getID() + "-" + childNode.getSeq()));
					if(userData==null) {
						userData = new String[1];
						userData[0] = null;
					}

					for(int j=0; j<userData.length; j++) {
						XbTupleDataObj obj = new XbTupleDataObj();
						obj.setItem_order(childNode.getItemOrder());
						obj.setTaxonomy_group_id(instanceID);
						obj.setTaxonomy_item_id(childNode.getID());
						obj.setTaxonomy_item_seq(childNode.getSeq());
						obj.setItem_value(userData[j]);
						obj.setContext_id(childNode.getContextID());

						if(Node.getType().equals(TAX_ITEM) && childNode.getType().equals(TAX_TUPLE)) {
							obj.setParent_taxonomy_item_id(childNode.getID());
							obj.setParent_taxonomy_item_seq(childNode.getSeq());
						} else {
							obj.setParent_taxonomy_item_id(Node.getID());
							obj.setParent_taxonomy_item_seq(Node.getSeq());
						}

						tupleDataDao.insert(obj);
				}	}

				// さらに深部へ
				if(childNode.getChildCount() > 0) {
					getNodeValue(childNode);
				}
			}
		} catch (Exception ex) { 
			ex.printStackTrace();
		}
	}
}