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

package jp.co.going.xbrl.sample;

import java.awt.BorderLayout;
import java.awt.Color;
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.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.ProgressMonitor;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;

import jp.co.going.xbrl.base.XbBaseschema;
import jp.co.going.xbrl.common.XbException;
import jp.co.going.xbrl.sample.dao.XbItemTopDao;
import jp.co.going.xbrl.sample.dao.obj.XbItemTopObj;
import jp.co.going.xbrl.taxonomy.XbTaxonomy;
import jp.co.going.xbrl.taxonomy.XbTaxonomyFactory;

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

	private Connection conn = null;
	private XbItemTopDao instanceDao = null;

	private JButton[] button = new JButton[14];
	private JRadioButton[] radio = new JRadioButton[2];
	private JComboBox instanceCombo = null;
	private ArrayList<XbItemTopObj> instanceList = null;

	private Object taxonomyGroupName = null;
	private String filePath = null;
	private ProgressMonitor progressBar = null;
	private Timer progressTimer = null;
	private int progressCount = 0;
	private boolean finishFlag = false;

	static private Color backGround = Color.LIGHT_GRAY;
	static private int progressMin = 0;
	static private int progressMax = 100;

	public static void main(String[] args) {
		JFrame frame = new XbSample();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public XbSample() {
		setTitle("XBRL Toolkit : Main Form");
		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();
				}
				System.exit(0);
			}
		});

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

		conn = getConnection();
		instanceDao = XbItemTopDao.getInstance(conn);


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

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

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

		JPanel InstParamPanel = InstParamPanel();
		layout.setConstraints(InstParamPanel, setGrid(0, 1, gbc));

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

		JPanel InstancePanel = InstancePanel();
		layout.setConstraints(InstancePanel, setGrid(0, 3, gbc));

		JPanel FrameFooter = FrameFooter();
		layout.setConstraints(FrameFooter, setGrid(0, 4, gbc));

		container.add(TaxonomyPanel);
		container.add(InstParamPanel);
		container.add(InstContextPanel);
		container.add(InstancePanel);
		container.add(FrameFooter);

		progressTimer = new Timer(500, this);

		pack();
	}

	/**
	 * Taxonomy入力欄の生成
	 */
	private JPanel TaxonomyPanel() {
		JPanel TaxonomyPanel = new JPanel();
		TaxonomyPanel.setLayout(new BorderLayout());
		TaxonomyPanel.setBorder(setBorder("タクソノミー設定"));
		TaxonomyPanel.setBackground(backGround);

		JPanel specPanel = new JPanel();
		specPanel.setLayout(new FlowLayout());
		specPanel.setBackground(backGround);

		JLabel label = new JLabel("スペック：");
		label.setFont(setFont(16));

		radio[0] = new JRadioButton("Spec2.0", false);
		radio[0].setFont(setFont(16));
		radio[0].setBackground(backGround);

		radio[1] = new JRadioButton("Spec2.1", true);
		radio[1].setFont(setFont(16));
		radio[1].setBackground(backGround);

		ButtonGroup group = new ButtonGroup();
		group.add(radio[0]);
		group.add(radio[1]);

		specPanel.add(label);
		specPanel.add(radio[0]);
		specPanel.add(radio[1]);

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

		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(layout);
		buttonPanel.setBackground(backGround);

		button[0] = setButton("基本スキーマ登録", "基本スキーマ を登録します。スペック（2.0 または 2.1）を指定して下さい。");
		button[0].addActionListener(this);
		layout.setConstraints(button[0], setGrid(0, 0, gbc));

		button[1] = setButton("タクソノミー登録", "タクソノミー を登録します。スペック（2.0 または 2.1）を指定して下さい。");
		button[1].addActionListener(this);
		layout.setConstraints(button[1], setGrid(1, 0, gbc));

		for(int i=0; i<2; i++) {
			buttonPanel.add(button[i]);
		}

		TaxonomyPanel.add(specPanel, BorderLayout.NORTH);
		TaxonomyPanel.add(buttonPanel, BorderLayout.SOUTH);

		return TaxonomyPanel;
	}

	/**
	 * パラメータ入力欄の生成
	 */
	private JPanel InstParamPanel() {
		GridBagLayout layout = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		JPanel InstParamPanel = new JPanel();
		InstParamPanel.setLayout(layout);
		InstParamPanel.setBorder(setBorder("インスタンス・パラメータ設定"));
		InstParamPanel.setBackground(backGround);

		button[3] = setButton("<html>" + nameList.get(IDENTIFIER) + "登録<br>＜" + IDENTIFIER + "＞</html>", "インスタンス文書の " + IDENTIFIER + " を登録します。");
		button[3].addActionListener(this);
		layout.setConstraints(button[3], setGrid(0, 0, gbc));

		button[4] = setButton("<html>" + nameList.get(SEGMENT) + "登録<br>＜" + SEGMENT + "＞</html>", "インスタンス文書の " + SEGMENT + " を登録します。");
		button[4].addActionListener(this);
		layout.setConstraints(button[4], setGrid(1, 0, gbc));

		button[5] = setButton("<html>" + nameList.get(SCENARIO) + "登録<br>＜" + SCENARIO + "＞</html>", "インスタンス文書の " + SCENARIO + " を登録します。");
		button[5].addActionListener(this);
		layout.setConstraints(button[5], setGrid(2, 0, gbc));

		button[6] = setButton("<html>" + nameList.get(FOOTNOTE) + "登録<br>＜" + FOOTNOTE + "＞</html>", "インスタンス文書の " + FOOTNOTE + " を登録します。");
		button[6].addActionListener(this);
		layout.setConstraints(button[6], setGrid(3, 0, gbc));

		button[7] = setButton("<html>" + nameList.get(REF) + "登録<br>＜" + REF + "＞</html>", "インスタンス文書の " + REF + " を登録します。");
		button[7].addActionListener(this);
		layout.setConstraints(button[7], setGrid(0, 1, gbc));

		button[8] = setButton("<html>" + nameList.get(MEASURE) + "登録<br>＜" + MEASURE + "＞</html>", "インスタンス文書の " + MEASURE + " を登録します。");
		button[8].addActionListener(this);
		layout.setConstraints(button[8], setGrid(1, 1, gbc));

		for(int i=3; i<9; i++) {
			InstParamPanel.add(button[i]);
		}

		return InstParamPanel;
	}

	/**
	 * インスタンス作成準備欄の生成
	 */
	private JPanel InstContextPanel() {
		GridBagLayout layout = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		JPanel InstContextPanel = new JPanel();
		InstContextPanel.setLayout(layout);
		InstContextPanel.setBorder(setBorder("インスタンス作成準備"));
		InstContextPanel.setBackground(backGround);

		button[9] = setButton("マッピング情報登録", "お客様のシステム環境と XBRL Toolkit 環境のマッピングを行います。");
		button[9].addActionListener(this);
		layout.setConstraints(button[9], setGrid(0, 0, gbc));

		button[10] = setButton(nameList.get(ENTITY) + "定義", "インスタンス文書の " + ENTITY + " を定義します。");
		button[10].addActionListener(this);
		layout.setConstraints(button[10], setGrid(1, 0, gbc));

		button[11] = setButton(nameList.get(UNIT) + "定義", "インスタンス文書の " + UNIT + " を定義します。");
		button[11].addActionListener(this);
		layout.setConstraints(button[11], setGrid(2, 0, gbc));

		button[12] = setButton(nameList.get(CONTEXT) + "作成", "インスタンス文書の " + CONTEXT + " を作成します。");
		button[12].addActionListener(this);
		layout.setConstraints(button[12], setGrid(3, 0, gbc));

		for(int i=9; i<13; i++) {
			InstContextPanel.add(button[i]);
		}

		return InstContextPanel;
	}

	/**
	 * インスタンス作成欄の生成
	 */
	private JPanel InstancePanel() {
		JPanel InstancePanel = new JPanel();
		InstancePanel.setLayout(new FlowLayout());
		InstancePanel.setBorder(setBorder("インスタンス作成"));
		InstancePanel.setBackground(backGround);

		instanceCombo = new JComboBox();
		setInstanceCombo();
		instanceCombo.setPreferredSize(new Dimension(180, 20));
		InstancePanel.add(instanceCombo);

		button[13] = setButton("インスタンス作成", "プルダウンで選択されたインスタンス文書を作成します。");
		button[13].addActionListener(this);
		InstancePanel.add(button[13]);

		return InstancePanel;
	}

	/**
	 * インスタンス文書プルダウン欄の生成
	 */
	private void setInstanceCombo() {
		try {
			instanceList = instanceDao.selectAll();

            instanceCombo.removeAllItems();
			for(int i=0; i<instanceList.size(); i++) {
				XbItemTopObj obj = instanceList.get(i);
				instanceCombo.addItem(obj.getItem_name());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
	}	}

	/**
	 * 画面Footer欄の生成
	 */
	private JPanel FrameFooter() {
		JPanel FrameFooter = new JPanel();
		FrameFooter.setLayout(new BorderLayout());

		closeButton = setButton("閉　じ　る", "Main Form を終了します。");
		closeButton.addActionListener(this);

		JPanel panel = new JPanel();
		panel.setBackground(backGround);
		panel.add(closeButton, BorderLayout.EAST);

		FrameFooter.add(panel, BorderLayout.CENTER);

		return FrameFooter;
	}

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

		if(source == button[0]) {
			JFileChooser fileChooser = new JFileChooser();
			fileChooser.setDialogTitle("基本スキーマフォルダの選択");
			fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

			if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
				File file = fileChooser.getSelectedFile();
				filePath = file.getPath();

				if(filePath != null) {
					if(JOptionPane.showConfirmDialog(this,
							"基本スキーマファイルの取り込みを開始します。よろしいですか？\n\n" + filePath) == JOptionPane.YES_OPTION) {

						finishFlag = false;
						Thread thread = new Thread(new Runnable() {
							public void run() {
								try {
									// 基本スキーマ取り込みクラスの呼び出し
									String ver = (radio[1].isSelected() ? "2.1" : "2.0");
									XbBaseschema base = new XbBaseschema(conn);
									base.registerBaseSchema(filePath, ver);
									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();
			}	}	}
		}
		else if(source == button[1]) {
			taxonomyGroupName = JOptionPane.showInputDialog(this,
					"登録する帳票名を入力して下さい。", "入力", JOptionPane.INFORMATION_MESSAGE);

			if(taxonomyGroupName != null && !taxonomyGroupName.equals("")) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setDialogTitle("タクソノミーファイルの選択");
				fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				fileChooser.addChoosableFileFilter(new FileFilter() {
					public boolean accept(File file) {
						if(file.isDirectory()) return true;
						return file.getName().toLowerCase().endsWith(".xsd");
					}
					public String getDescription() {
						return "XSDファイル(*.xsd)";
					}
				});

				if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
					File file = fileChooser.getSelectedFile();
					filePath = file.getPath();

					if(filePath != null) {
						if(JOptionPane.showConfirmDialog(this,
								"タクソノミーファイルの取り込みを開始します。よろしいですか？\n\n" + filePath) == JOptionPane.YES_OPTION) {

							finishFlag = false;
							Thread thread = new Thread(new Runnable() {
								public void run() {
									try {
										// タクソノミー取り込みクラスの呼び出し
										String ver = (radio[1].isSelected() ? "2.1" : "2.0");
										XbTaxonomy taxonomy = XbTaxonomyFactory.createTaxonomy(conn, ver);
										taxonomy.registerTaxonomy(taxonomyGroupName.toString(), "", filePath);
										conn.commit();
										setInstanceCombo();
										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();
			}	}	}	}
		}
		else if(source == button[3]) {
			window = new XbTableParamInput(conn, IDENTIFIER);
		}
		else if(source == button[4]) {
			window = new XbTableParamInput(conn, SEGMENT);
		}
		else if(source == button[5]) {
			window = new XbTableParamInput(conn, SCENARIO);
		}
		else if(source == button[6]) {
			window = new XbTableParamInput(conn, FOOTNOTE);
		}
		else if(source == button[7]) {
			window = new XbRefInput(conn);
		}
		else if(source == button[8]) {
			window = new XbTableParamInput(conn, MEASURE);
		}
		else if(source == button[9]) {
			window = new XbMapping(conn);
		}
		else if(source == button[10]) {
			window = new XbEntityInput(conn);
		}
		else if(source == button[11]) {
			window = new XbUnitInput(conn, radio[1].isSelected() ? true : false);
		}
		else if(source == button[12]) {
			window = new XbContextInput(conn);
		}
		else if(source == button[13]) {
			if(instanceCombo.getSelectedItem() != null) {

				long instanceID = 0;
				String instanceName = "";
				String itemLang = "";

				for(int i=0; i<instanceList.size(); i++) {
					XbItemTopObj obj = instanceList.get(i);
					instanceName = instanceCombo.getSelectedItem().toString();

					if(obj.getItem_name().equals(instanceName)) {
						instanceID = obj.getTaxonomy_group_id();
						itemLang = obj.getItem_lang();
						break;
				}	}

				String ver = (radio[1].isSelected() ? "2.1" : "2.0");
				window = new XbCreateInstance(instanceID, instanceName, itemLang, ver);
		}	}
		else if(source == closeButton) {
			try {
				// 接続をクローズ
				conn.close();
			} catch (SQLException ex) {
				ex.printStackTrace();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			System.exit(0);
		}
		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(window != null) {
			window.setLocationRelativeTo(null);
			window.setVisible(true);
		}
	}
}