/*
 * 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.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import jp.co.going.xbrl.common.XbException;
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.XbUnitDao;
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.XbUnitObj;

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

	private Connection conn = null;
	private XbUnitDao unitDao = null;
	private XbEntityDao entityDao = null;
	private XbContextDao contextDao = null;
	private XbContextUnitDao contextUnitDao = null;

	private JFrame window = null;
	private JPanel ContextPanel = null;
	private JPanel panel[] = null;
	private ButtonGroup[] group = new ButtonGroup[1];
	private JRadioButton[] radio = new JRadioButton[2];
	private JComboBox[] cb1 = new JComboBox[3];
	private JComboBox[] cb2 = new JComboBox[6];
	private JTextField[] text = new JTextField[3];
	private JCheckBox[] check = new JCheckBox[2];
	private JButton button = null;

	private ArrayList<XbContextObj> contextList = null;
	private ArrayList<XbEntityObj> entityList = null;
	private ArrayList<XbUnitObj> unitList = null;

	private int combo_year_w = 60;
	private int combo_day_w = 40;
	private int combo_h = 19;

	private long contextID = 0;
	private long entityID = 0;
	private long unitID = 0;
	private int precision = 18;

	/**
	 * コンストラクタ
	 */
	public XbContextInput(Connection conn) {
		this.conn = conn;

		setTitle("XBRL Toolkit : Input " + CONTEXT);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

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

		unitDao = XbUnitDao.getInstance(conn);
		entityDao = XbEntityDao.getInstance(conn);
		contextDao = XbContextDao.getInstance(conn);
		contextUnitDao = XbContextUnitDao.getInstance(conn);


		Container container = getContentPane();
		container.setLayout(new BorderLayout());

		ContextPanel = ContextPanel();
		JPanel SubmitPanel = SubmitPanel();

		submitButton.addActionListener(this);
		submitButton.setEnabled(false);
		closeButton.addActionListener(this);

		container.add(ContextPanel, BorderLayout.NORTH);
		container.add(SubmitPanel, BorderLayout.SOUTH);

		pack();
	}

	/**
	 * Context入力欄の生成
	 */
	private JPanel ContextPanel() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);

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

		JPanel ContextPanel = new JPanel();
		ContextPanel.setLayout(layout);

		try {
			int count = 10;
			JLabel title[] = new JLabel[count];
			panel = new JPanel[count];
			JPanel[] flowPanel = new JPanel[count];

			// コンテキスト型
			int n = 0;
			title[n] = new JLabel(nameList.get(CONTEXT) + "型*");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			radio[0] = new JRadioButton("数値型", true);
			radio[1] = new JRadioButton("非数値型", false);

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

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(radio[0]);
			flowPanel[n].add(new JLabel("　"));
			flowPanel[n].add(radio[1]);

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// コンテキスト日本語名
			n++;
			title[n] = new JLabel(nameList.get(CONTEXT) + "名*");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			contextList = contextDao.selectAll();
			cb1[0] = new JComboBox();
			cb1[0].addItem("");
			int strMax = 0;
			for(int i=0; i<contextList.size(); i++) {
				XbContextObj context = contextList.get(i);
				String temp = context.getContext_name();
				cb1[0].addItem(temp);
				int w = getStringWidth(temp);
				if(strMax < w)  strMax = w;
			}
			cb1[0].setPreferredSize(new Dimension((strMax==0 ? 150 : strMax), combo_h));
			cb1[0].setEditable(true);
			cb1[0].addItemListener(this);

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(cb1[0]);
			flowPanel[n].add(new JLabel("　（日本語でわかりやすい名称を指定して下さい）"));

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// コンテキスト名
			n++;
			title[n] = new JLabel(nameList.get(CONTEXT) + "要素名*");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			text[0] = setField(100);
			text[0].addCaretListener(new CaretListener() {
				public void caretUpdate(CaretEvent e) {
					if(e.getDot() > 0) {
						submitButton.setEnabled(true);
			}	}	});

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(text[0]);
			flowPanel[n].add(new JLabel("　<Context id=\"XXXXX\">"));

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// Entity
			n++;
			title[n] = new JLabel(nameList.get(ENTITY) + "*");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			entityList = entityDao.selectAll();
			cb1[1] = new JComboBox();
			cb1[1].addItem("");
			strMax = 0;
			for(int i=0; i<entityList.size(); i++) {
				XbEntityObj entity = entityList.get(i);
				String temp = entity.getEntity_name();
				cb1[1].addItem(temp);
				int w = getStringWidth(temp);
				if(strMax < w)  strMax = w;
			}
			cb1[1].setPreferredSize(new Dimension(strMax, combo_h));

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(cb1[1]);

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// 会計年度
			n++;
			title[n] = new JLabel("会計年度 （西暦）");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			text[1] = setField(40);

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(text[1]);
			flowPanel[n].add(new JLabel("年度"));

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// 期首日
			n++;
			title[n] = new JLabel("期首日");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			panel[n] = setPanel(dateInput(0, year, 0, 0));
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// 期末日
			n++;
			title[n] = new JLabel("期末日");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			panel[n] = setPanel(dateInput(3, year + 1, 0, 0));
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// ユニット
			n++;
			title[n] = new JLabel(nameList.get(UNIT));
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			unitList = unitDao.selectAll();
			cb1[2] = new JComboBox();
			cb1[2].addItem("");
			strMax = 0;
			for(int i=0; i<unitList.size(); i++) {
				XbUnitObj unit = unitList.get(i);
				String temp = unit.getUnit_name();
				cb1[2].addItem(temp);
				int w = getStringWidth(temp);
				if(strMax < w)  strMax = w;
			}
			cb1[2].setPreferredSize(new Dimension(strMax, combo_h));

			text[2] = setField(30);
			text[2].setText(String.valueOf(precision));
			check[0] = new JCheckBox();

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(cb1[2]);
			flowPanel[n].add(new JLabel("　　　　Precision属性"));
			flowPanel[n].add(text[2]);
			flowPanel[n].add(new JLabel("　CWA属性"));
			flowPanel[n].add(check[0]);

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// ユニット出力フラグ
			n++;
			title[n] = new JLabel(nameList.get(UNIT) + "出力フラグ");
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			check[1] = new JCheckBox();

			flowPanel[n] = new JPanel();
			flowPanel[n].setLayout(new FlowLayout());
			flowPanel[n].add(check[1]);
			flowPanel[n].add(new JLabel("　※非数値型の場合、インスタンス文書に単位を出力するかどうかを指定します。"));

			panel[n] = setPanel(flowPanel[n]);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// シナリオ
			n++;
			title[n] = new JLabel(nameList.get(SCENARIO));
			layout.setConstraints(title[n], setGrid(0, n, gbc));

			button = new JButton("設定");
			button.addActionListener(this);
			button.setEnabled(false);

			JLabel label = new JLabel("　　※コンテキスト情報を登録後、シナリオ情報が登録可能になります。");
			label.setForeground(Color.RED);

			panel[n] = setPanel(button);
			panel[n].add(label);
			layout.setConstraints(panel[n], setGrid(1, n, gbc));

			// Component配置
			for(int i=0; i<count; i++) {
				ContextPanel.add(title[i]);
				ContextPanel.add(panel[i]);
			}

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

		return ContextPanel;
	}

	/**
	 * 日付入力欄の生成
	 */
	private JPanel dateInput(int index, int defaultYear, int defaultMonth, int defaultDay) {
		JPanel panel = new JPanel();
		panel.setLayout(new FlowLayout());

		cb2[index+0] = new JComboBox();
		cb2[index+0].addItem("");
		cb2[index+0].addItem(defaultYear);
		cb2[index+0].setEditable(true);
		cb2[index+0].setSelectedIndex(0);
		cb2[index+0].setPreferredSize(new Dimension(combo_year_w, combo_h));
		panel.add(cb2[index+0]);

		panel.add(new JLabel("年"));

		cb2[index+1] = new JComboBox();
		cb2[index+1].addItem("");
		for(int i=0; i<12; i++) {
			cb2[index+1].addItem((i<9 ? "0" : "") + Integer.toString(i+1));
		}
		cb2[index+1].setSelectedIndex(defaultMonth);
		cb2[index+1].setPreferredSize(new Dimension(combo_day_w, combo_h));
		panel.add(cb2[index+1]);

		panel.add(new JLabel("月"));

		cb2[index+2] = new JComboBox();
		cb2[index+2].addItem("");
		for(int i=0; i<31; i++) {
			cb2[index+2].addItem((i<9 ? "0" : "") + Integer.toString(i+1));
		}
		cb2[index+2].setSelectedIndex(defaultDay);
		cb2[index+2].setPreferredSize(new Dimension(combo_day_w, combo_h));
		panel.add(cb2[index+2]);

		panel.add(new JLabel("日"));

		return panel;
	}

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

		if(source == button) {
			if(window != null) {
				window.dispose();
				window = null;
			}
			window = new XbContextScenarioInput(conn, contextID);
			window.setLocationRelativeTo(null);
			window.setVisible(true);
		}
		else if(source == submitButton){
			try {
				// エンティティの入力チェック
				if(cb1[1].getSelectedItem().toString().equals("")) {
					JOptionPane.showMessageDialog(this, "エンティティを指定して下さい。");
				}
				else {
					// コンテキストの存在チェック
					XbContextObj context = contextDao.selectByName(cb1[0].getSelectedItem().toString());

					if(context==null) {

						// コンテキスト登録
						contextID = contextDao.getNextId();

						for(int i=0; i<entityList.size(); i++) {
							XbEntityObj entity = entityList.get(i);
							if(cb1[1].getSelectedItem().toString().equals(entity.getEntity_name())) {
								entityID = entity.getEntity_id();
								break;
						}	}

						String start_date = cb2[0].getSelectedItem() + "-" + cb2[1].getSelectedItem() + "-" + cb2[2].getSelectedItem();
						if(start_date.equals("--"))  start_date = "";

						String end_date = cb2[3].getSelectedItem() + "-" + cb2[4].getSelectedItem() + "-" + cb2[5].getSelectedItem();
						if(end_date.equals("--"))  end_date = "";

						int fiscal_year = (text[1].getText().equals("") ? 0 : Integer.valueOf(text[1].getText()));
						int precision = (text[2].getText().equals("") ? 0 : Integer.valueOf(text[2].getText()));

						context = new XbContextObj();
						context.setContext_id(contextID);
						context.setContext_type(radio[0].isSelected() ? NUMERIC : NONNUMERIC);
						context.setContext_name(cb1[0].getSelectedItem().toString());
						context.setName(text[0].getText());
						context.setEntity_id(entityID);
						context.setFiscal_year(fiscal_year);
						context.setPeriod_start_date(start_date);
						context.setPeriod_end_date(end_date);
						context.setItem_precision(precision);
						context.setItem_cwa(check[0].isSelected() ? 1 : 0);
						context.setUnit_flag(check[1].isSelected() ? 1 : 0);
						context.setCreation_date(new Date());
						contextDao.insert(context);

						// Context - Unit 登録
						for(int i=0; i<unitList.size(); i++) {
							XbUnitObj unit = unitList.get(i);
							if(unit.getUnit_name().equals(cb1[2].getSelectedItem())) {
								unitID = unit.getUnit_id();
								break;
						}	}

						if(unitID > 0) {
							XbContextUnitObj contextUnit = new XbContextUnitObj();
							contextUnit.setContext_id(contextID);
							contextUnit.setUnit_id(unitID);
							contextUnit.setCreation_date(new Date());
							contextUnitDao.insert(contextUnit);
						}

						conn.commit();
						JOptionPane.showMessageDialog(this, "データを登録しました。");

						submitButton.setEnabled(false);
						button.setEnabled(true);
						cb1[0].addItem(cb1[0].getSelectedItem().toString());
				}	}
			} catch (XbException err) {
				try {
					err.printStackTrace();
					conn.rollback();
				}
				catch (Exception ex) {
					ex.printStackTrace();
				}
			} catch (Exception ex) { 
				ex.printStackTrace();
			}
		}
		else if(source == closeButton){
			this.setVisible(false);
		}
	}

	/**
	 * 画面上の Context 情報を更新
	 */
	public void itemStateChanged(ItemEvent e) {
		if(e.getStateChange() == ItemEvent.SELECTED) {
			int index = ((JComboBox)e.getSource()).getSelectedIndex();
			if(index > 0) {
				XbContextObj context = contextList.get(index - 1);
				contextID = context.getContext_id();

				int entityIndex = 0;
				for(entityIndex=0; entityIndex<entityList.size(); entityIndex++) {
					XbEntityObj entity = entityList.get(entityIndex);
					entityID = context.getEntity_id();
					if(entityID == entity.getEntity_id()) {
						break;
				}	}

				String[] start = new String[]{"", "", ""};
				if(context.getPeriod_start_date() != null && !context.getPeriod_start_date().equals("")) {
					start = context.getPeriod_start_date().split("-");
				}

				String[] end = new String[]{"", "", ""};
				if(context.getPeriod_end_date() != null && !context.getPeriod_end_date().equals("")) {
					end = context.getPeriod_end_date().split("-");
				}

				if(context.getContext_type().equals(NUMERIC))     radio[0].setSelected(true);
				if(context.getContext_type().equals(NONNUMERIC))  radio[1].setSelected(true);
				text[0].setText(context.getName());
				cb1[1].setSelectedIndex(entityIndex + 1);
				text[1].setText(context.getFiscal_year()==0 ? "" : String.valueOf(context.getFiscal_year()));
				cb2[0].setSelectedItem(start[0]);
				cb2[1].setSelectedItem(start[1]);
				cb2[2].setSelectedItem(start[2]);
				cb2[3].setSelectedItem(end[0]);
				cb2[4].setSelectedItem(end[1]);
				cb2[5].setSelectedItem(end[2]);
				text[2].setText(String.valueOf(context.getItem_precision()));
				check[0].setSelected(context.getItem_cwa()==1 ? true : false);
				check[1].setSelected(context.getUnit_flag()==1 ? true : false);
				button.setEnabled(true);

				try {
					ArrayList<XbContextUnitObj> contextUnitList = contextUnitDao.selectAll(contextID);
					for(int i=0; i<unitList.size(); i++) {
						XbUnitObj unit = unitList.get(i);

						for(int j=0; j<contextUnitList.size(); j++) {
							XbContextUnitObj contextUnit = contextUnitList.get(j);
							unitID = contextUnit.getUnit_id();
							if(unitID == unit.getUnit_id()) {
								cb1[2].setSelectedIndex(i + 1);
					}	}	}
				} catch (Exception ex) {
					ex.printStackTrace();
			}	}
			else if(index==0) {
				contextID = 0;
				radio[0].setSelected(true);
				radio[1].setSelected(false);
				text[0].setText("");
				cb1[1].setSelectedIndex(0);
				text[1].setText("");
				cb2[0].setSelectedIndex(0);
				cb2[1].setSelectedIndex(0);
				cb2[2].setSelectedIndex(0);
				cb2[3].setSelectedIndex(0);
				cb2[4].setSelectedIndex(0);
				cb2[5].setSelectedIndex(0);
				text[2].setText("");
				check[0].setSelected(false);
				check[1].setSelected(false);
				cb1[2].setSelectedIndex(0);
				button.setEnabled(false);

				if(window != null) {
					window.dispose();
					window = null;
	}	}	}	}
}