package com.ftinc.si.assist.test.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
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.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.AbstractAction;
import javax.swing.Action;
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.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ListUI;

import com.ftinc.si.assist.run.Messages;
import com.ftinc.si.assist.run.TestCommander;
import com.ftinc.si.assist.run.TestSubMain;
import com.ftinc.si.assist.test.AssertRecord;
import com.ftinc.si.assist.test.FakeMethodRecord;
import com.ftinc.si.assist.test.ObjectRecord;
import com.ftinc.si.assist.test.Record;
import com.ftinc.si.assist.test.TestCaseRecord;
import com.ftinc.si.assist.test.TestCommandRecord;
import com.ftinc.si.assist.test.Tool;

public class TestCaseBrowser extends JFrame {
	@SuppressWarnings("unused")
	private static String copyright = "Copy Right Toyoaki Furusawa, 2014-."; //$NON-NLS-1$
	private JTextField beginText;
	private JTextField endText;
	private JTextField caseName;
	private JTextArea txtDesc;
	private JTextArea txtStatus;
	private JList<String> testcase_list;
	private JMenuItem mntmCreateTable;
	private JMenuItem mntmAll;

	private ArrayList<TestCaseRecord> m_caselist = null;
	private TestCaseRecord m_curcase;
	private int m_begin;
	private int m_end;
	private boolean checkedBegin;
	private boolean checkedEnd;
	private String m_title;

	private EnvironmentData m_env;
	private boolean db_created = false;

	private DefaultListModel<String> testcase_model;
	public static JFrame s_curFrame = null;

	public TestCaseBrowser() {
		//終了処理
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				closing();
			}
		});
		if (s_curFrame == null) {
			s_curFrame = this;
		}
		setResizable(false);
		m_title = Messages.getString("TestCaseBrowser.0"); //$NON-NLS-1$
		setTitle(m_title);
		Tool.init(true);

		m_caselist = new ArrayList<TestCaseRecord>();

		testcase_model = new DefaultListModel<String>();
		txtDesc = new JTextArea();

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		JMenu mnFile = new JMenu(Messages.getString("TestCaseBrowser.1")); //$NON-NLS-1$
		menuBar.add(mnFile);

		//終了処理
		JMenuItem mntmExit = new JMenuItem(Messages.getString("TestCaseBrowser.2")); //$NON-NLS-1$
		mntmExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				closing();
				setVisible(false);
			}
		});

		mntmCreateTable = new JMenuItem(Messages.getString("TestCaseBrowser.55")); //$NON-NLS-1$
		//テーブル生成。未定義の場合だけ可能。
		mntmCreateTable.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				tryCreateTable();
			}
		});

		//環境設定のイクスポート
		JMenuItem mntmExportEnviroment = new JMenuItem(Messages.getString("TestCaseBrowser.57")); //$NON-NLS-1$
		mntmExportEnviroment.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser t_fc = new JFileChooser(Tool.getPrevPath());
				t_fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				if (t_fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
					File t_file = t_fc.getSelectedFile();
					String t_path =t_file.getAbsolutePath();

					Tool.setPrevPath(t_file.getAbsolutePath());
					t_path += "\\tclenv.json"; //$NON-NLS-1$

					m_env.prevPath = Tool.getPrevPath();
					String envJSON = Tool.getJSONfromObject(m_env);

					File t_env = new File(t_path);
					if (!t_env.exists()) {
						try {
							t_env.createNewFile();

							FileWriter t_w;
							t_w = new FileWriter(t_env);
							t_w.write(envJSON);
							t_w.close();
						} catch (IOException e1) {
							Tool.alertMSG(null, e1.getMessage());
						}
					}
			    }
			}
		});


		mnFile.add(mntmExportEnviroment);
		mnFile.add(mntmCreateTable);
		mnFile.add(mntmExit);

		JMenu mnExecute = new JMenu(Messages.getString("TestCaseBrowser.22")); //$NON-NLS-1$
		menuBar.add(mnExecute);

		//全てのテストケースを実行
		mntmAll = new JMenuItem(Messages.getString("TestCaseBrowser.23")); //$NON-NLS-1$
		mntmAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
					// イベントから抜けた後に実行。
						execTestCase(null, false);
					}
				});
			}
		});
		mnExecute.add(mntmAll);

		//（編集モード）選択中のテストケースを実行
		JMenuItem mntmTestcase1 = new JMenuItem(Messages.getString("TestCaseBrowser.4")); //$NON-NLS-1$
		mntmTestcase1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int i = testcase_list.getSelectedIndex();
				if (i >= 0 && m_caselist.get(i) != null) {
					m_curcase = m_caselist.get(i);
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
						// イベントから抜けた後に実行。
							execTestCase(m_curcase, true);
						}
					});
				} else {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.25")); //$NON-NLS-1$
				}
			}

		});
		mnExecute.add(mntmTestcase1);

		//(非編集モード)選択中のテストケースを実行
		JMenuItem mntmTestcase2 = new JMenuItem(Messages.getString("TestCaseBrowser.13")); //$NON-NLS-1$
		mntmTestcase2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int i = testcase_list.getSelectedIndex();
				if (i >= 0 && m_caselist.get(i) != null) {
					m_curcase = m_caselist.get(i);
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
						// イベントから抜けた後に実行。
							execTestCase(m_curcase, false);
						}
					});
				} else {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.25")); //$NON-NLS-1$
				}
			}

		});
		mnExecute.add(mntmTestcase2);

		JMenu mnOption = new JMenu(Messages.getString("TestCaseBrowser.26")); //$NON-NLS-1$
		menuBar.add(mnOption);

		//Environment:環境設定
		JMenuItem mntmDatabase = new JMenuItem(Messages.getString("TestCaseBrowser.27")); //$NON-NLS-1$
		mntmDatabase.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				EnvironmentData t_dat = Tool.openEnvironmentDialog(s_curFrame, m_env);

				//閉じるボタンを押した時だけ保存する。
				if (t_dat != null) {
					//変更がある場合はnull以外が返る
					if (t_dat.hiddenMode != m_env.hiddenMode) {
						if (t_dat.hiddenMode) {
							//不活性なCaseで出ているものを隠す。
							testcase_list.removeAll();
							for (int i = 0; m_caselist.size() > i; i++) {
								if (m_caselist.get(i).enable == true) {
									testcase_list.add(m_caselist.get(i).name, null);
								}
							}
						} else {
							//隠しているもの(不活性なCase)を出す。
							testcase_list.removeAll();
							for (int i = 0; m_caselist.size() > i; i++) {
								testcase_list.add(m_caselist.get(i).name, null);
							}
						}
					} else if (!Tool.version.equals(t_dat.version)) {
						//版数に変更あり
						Tool.version = t_dat.version;
						for (int i = m_caselist.size() - 1; i >= 0; i--) {
							m_caselist.remove(i);
						}
						testcase_model.removeAllElements();
					}
					m_env = t_dat;
					connectDB();
				}
				if (!db_created && Tool._db().isReady()) {
					//再定義はしないので不可とする。
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.65")); //$NON-NLS-1$
					mntmCreateTable.setEnabled(false);
					db_created = true;
				}
			}
		});
		mnOption.add(mntmDatabase);

		//Fakeの再構成
		JMenuItem mntmRefleshFakeclass = new JMenuItem(Messages.getString("TestCaseBrowser.28")); //$NON-NLS-1$
		mntmRefleshFakeclass.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//全Fake Classのbodyを更新する。
				if (Tool.refleshFakes()) {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.44")); //$NON-NLS-1$
				}
			}
		});

		//Fakeのメソッド編集
		JMenuItem mntmEditFakemethod = new JMenuItem(Messages.getString("TestCaseBrowser.29")); //$NON-NLS-1$
		mntmEditFakemethod.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				MethodEditor.s_owner = null;	//JDialogから呼ぶのではないため。これにより、削除ボタンの有無が決まる。
				MethodEditor t_dlg = new MethodEditor(null, null, null, null, null); //$NON-NLS-1$
				t_dlg.setVisible(true);

				FakeMethodRecord t_rec = t_dlg.getFakeMethodRecord();
				if (t_dlg.is_OK) {
					if (t_rec != null) {
						if (Tool.existClass(t_rec.className)) {
							try {
								Tool._db().updateRecordBySQL(t_rec.getUpdateSQL(), true);
								Tool.alertMSG(null, Messages.getString("TestCaseBrowser.52") + t_rec.className + "#" + t_rec.methodName); //$NON-NLS-1$ //$NON-NLS-2$
							} catch (SQLException e1) {
								Tool.alertMSG(null, Messages.getString("TestCaseBrowser.37")+ e1.getMessage()); //$NON-NLS-1$
							}
						}
					} else {
						Tool.alertMSG(null, Messages.getString("TestCaseBrowser.18")); //$NON-NLS-1$
					}
				}
			}
		});

		//JSON編集
		JMenuItem mntmEditJson = new JMenuItem(Messages.getString("TestCaseBrowser.30")); //$NON-NLS-1$
		mntmEditJson.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//何も設定していない状態から編集する。
				JSONEditor t_ed = new JSONEditor(null, null, null, null);
				t_ed.setVisible(true);
			}
		});
		mnOption.add(mntmEditJson);
		mnOption.add(mntmEditFakemethod);
		mnOption.add(mntmRefleshFakeclass);
		getContentPane().setLayout(null);

		//Fake編集とJson編集のためにGroupID権限とVersionをチェックする。全てのVersionが見られるのは管理者のみ。
		if (Tool.group_code != null && Tool.group_code.length() > 0 && (Tool.version == null || Tool.version.length() == 0)) {
			//versionが無指定なので編集不可
			mntmEditJson.setEnabled(false);
			mntmEditFakemethod.setEnabled(false);
		} else {
			mntmEditJson.setEnabled(true);
			mntmEditFakemethod.setEnabled(true);
		}

		JLabel lblUsecase = new JLabel(Messages.getString("TestCaseBrowser.31")); //$NON-NLS-1$
		lblUsecase.setBounds(12, 10, 50, 13);
		getContentPane().add(lblUsecase);


		txtDesc.setBounds(171, 66, 601, 167);
		getContentPane().add(txtDesc);

		JLabel lblDescription = new JLabel(Messages.getString("TestCaseBrowser.32")); //$NON-NLS-1$
		lblDescription.setBounds(171, 48, 93, 13);
		getContentPane().add(lblDescription);

		JLabel lblTestcommands = new JLabel(Messages.getString("TestCaseBrowser.33")); //$NON-NLS-1$
		lblTestcommands.setBounds(171, 241, 91, 13);
		getContentPane().add(lblTestcommands);

		beginText = new JTextField();
		beginText.setText("0"); //$NON-NLS-1$
		beginText.setBounds(239, 7, 96, 19);
		getContentPane().add(beginText);
		beginText.setColumns(10);
		beginText.setHorizontalAlignment(JTextField.RIGHT);
		beginText.enableInputMethods(false);
		beginText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				checkedBegin = Tool.checkInteger(beginText.getText(), e, 200, 0);
				if (!checkedBegin) {
					e.consume();
				}
			}
			@Override
			public void keyReleased(KeyEvent e) {
				if (!checkedBegin) {
					e.consume();
				}
			}
			@Override
			public void keyTyped(KeyEvent e) {
				if (!checkedBegin) {
					e.consume();
				}
			}
		});

		JLabel lblBeginid = new JLabel(Messages.getString("TestCaseBrowser.35")); //$NON-NLS-1$
		lblBeginid.setBounds(186, 10, 50, 13);
		getContentPane().add(lblBeginid);

		JLabel lblEndid = new JLabel(Messages.getString("TestCaseBrowser.36")); //$NON-NLS-1$
		lblEndid.setToolTipText(""); //$NON-NLS-1$
		lblEndid.setBounds(359, 10, 50, 13);
		getContentPane().add(lblEndid);

		endText = new JTextField();
		endText.setText("0"); //$NON-NLS-1$
		endText.setBounds(398, 7, 96, 19);
		getContentPane().add(endText);
		endText.setColumns(10);
		endText.setHorizontalAlignment(JTextField.RIGHT);
		endText.enableInputMethods(false);
		endText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				checkedEnd = Tool.checkInteger(endText.getText(), e, 200, 0);
				if (!checkedEnd) {
					e.consume();;
				}
			}
			@Override
			public void keyReleased(KeyEvent e) {
				if (!checkedEnd) {
					e.consume();;
				}
			}
			@Override
			public void keyTyped(KeyEvent e) {
				if (!checkedEnd) {
					e.consume();;
				}
			}
		});


		//検索：TestCaseList取得
		JButton btnSearch = new JButton(Messages.getString("TestCaseBrowser.39")); //$NON-NLS-1$
		btnSearch.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!db_created) {
					//未接続
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.40")); //$NON-NLS-1$
					return;
				}
				//検索時にGroupID権限とVersionをチェックする。全てのVersionが見られるのは管理者のみ。
				if (Tool.group_code != null && Tool.group_code.length() > 0 && (Tool.version == null || Tool.version.length() == 0)) {
					Tool.alertMSG(null, Messages.getString("TestMain.16")); //$NON-NLS-1$
					return;
				}

				if (caseName.getText() == null) {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.41")); //$NON-NLS-1$
					return;
				}
				if (caseName.getText().matches("^.*?['\"\\s=].*$")) { //$NON-NLS-1$
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.67")); //$NON-NLS-1$
				}

				m_begin = -1;
				if (!beginText.getText().equals("")) { //$NON-NLS-1$
					try {
						m_begin = Integer.valueOf(beginText.getText());
					} catch (NumberFormatException e2) {
						m_begin = 0;
					}
				}
				m_end = -1;
				if (!endText.getText().equals("")) { //$NON-NLS-1$
					try {
						m_end = Integer.valueOf(endText.getText());
					} catch (NumberFormatException e2) {
						m_end = 0;
					}
				}
				m_caselist.clear();
				testcase_model.removeAllElements();;

				//GroupCodeは指定しない。見るだけなので。
				m_caselist = Tool._db().getTestCaseList(caseName.getText(), m_begin, m_end, "", Tool.version); //$NON-NLS-1$

				if (m_caselist.size() > 50) {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.50")); //$NON-NLS-1$
				} else if (m_caselist.size() == 0) {
					Tool.alertMSG(null, Messages.getString("TestCaseBrowser.42")); //$NON-NLS-1$
				}
				for (int i = 0; m_caselist.size() > i && 51 > i; i++) {
					TestCaseRecord t_case = m_caselist.get(i);
					testcase_model.addElement(t_case.name);
				}
			}
		});
		btnSearch.setBounds(511, 6, 91, 21);
		getContentPane().add(btnSearch);

		JSeparator separator = new JSeparator();
		separator.setBounds(12, 33, 770, 2);
		getContentPane().add(separator);

		caseName = new JTextField();
		caseName.setText("%"); //$NON-NLS-1$
		caseName.setBounds(74, 7, 96, 19);
		getContentPane().add(caseName);
		caseName.setColumns(10);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 47, 147, 373);
		getContentPane().add(scrollPane);

		testcase_list = new JList<String>(testcase_model);
		scrollPane.setViewportView(testcase_list);

		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(171, 264, 611, 156);
		getContentPane().add(scrollPane_1);

		txtStatus = new JTextArea();
		scrollPane_1.setViewportView(txtStatus);
		txtStatus.setEditable(false);

		// TestCaseListクリック
		testcase_list.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(SwingUtilities.isRightMouseButton(e)){
					//右クリックならポップアップを開く。
					ListUI t_ui = testcase_list.getUI();
					int j = t_ui.locationToIndex(testcase_list, e.getPoint());
					if (j >= 0) {
						String label = (String)testcase_model.get(j);
						if (label != null) {
							goTestCasePopUp(e, label);
						}
					} else {
						goTestCasePopUp(e, null);
					}
				} else if (e.getClickCount() == 2) {
					//ダブルクリック
					ListUI t_ui = testcase_list.getUI();
					int j = t_ui.locationToIndex(testcase_list, e.getPoint());
					if (j >= 0) {
						String label = (String)testcase_model.get(j);
						if (label != null) {
							editCase(label);
						}
					}
				} else {
					//マウスによる選択時の処理
					displayCaseStatus();
				}
			}
		});

		//初期化
		initEnv();
	}

	//Caseの状況表示の更新
	private void displayCaseStatus() {
		int i = testcase_list.getSelectedIndex();
		//通常の選択操作
		if (i >= 0) {
			TestCaseRecord t_case = m_caselist.get(i);
			txtDesc.setText("name=" + t_case.name + "\n" + t_case.description);
			String t_snap = Integer.toString(t_case.snapshot);

			String t_status = Messages.getString("TestCaseBrowser.14") + Integer.toString(t_case.begin) + Messages.getString("TestCaseBrowser.15") + Integer.toString(t_case.end); //$NON-NLS-1$ //$NON-NLS-2$
			t_status += Messages.getString("TestCaseBrowser.20") + Boolean.toString(t_case.loggable) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
			if (t_snap != null && t_snap.length() > 0) {
				Integer n = Integer.valueOf(t_snap);
				if (n > 0) {
					//snapshotが指定されているなら
					t_status += Messages.getString("TestCaseBrowser.43") + t_snap + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
				}
			}

			t_status += Tool._db().getCaseStatus(t_case.name, Integer.toString(t_case.begin), Integer.toString(t_case.end));
			txtStatus.setText(t_status);
		}
	}

	private void initEnv() {
		m_env = Tool.readEnvironment(false);
		connectDB();
	}

	private void closing() {
		try {
			Tool.saveEnvironment(m_env);
			Tool.destroy();
		} catch (Exception e) {
			String t_msg = e.getMessage() + "\n"; //$NON-NLS-1$
			t_msg += Tool.getStackMessage(e, 0, 10);
			Tool.alertMSG(null, t_msg);
		}
	}


	//DBに接続する。
	private void connectDB() {
		if (m_env != null) {
			Tool.setEnvironment(m_env);

			//この時点でToolは接続を試行済。
			if (Tool._db() != null) {
				if (!db_created) {
					JOptionPane.showMessageDialog(null, Messages.getString("TestCaseBrowser.49"));//$NON-NLS-1$

					//テーブル未定義の場合、定義できるようにする。
					if (!Tool._db().isReady()) {
						//失敗
						mntmCreateTable.setEnabled(true);
						db_created = false;
						Tool.alertMSG(null, Messages.getString("TestCaseBrowser.64")); //$NON-NLS-1$
					} else {
						mntmCreateTable.setEnabled(false);
						db_created = true;
					}
				}
			} else {
				//エラーメッセージはDBService.initで出力済み
				db_created = false;
				mntmCreateTable.setEnabled(true);
				return;
			}

			String gcode = ""; //$NON-NLS-1$
			if (Tool.group_code.length() > 0) {
				gcode = "GroupCode=" + Tool.group_code; //$NON-NLS-1$
			}
			setTitle(m_title + "   " + gcode); //$NON-NLS-1$
		} else {
			Tool.alertMSG(null, Messages.getString(Messages.getString("TestCaseBrowser.45"))); //$NON-NLS-1$
		}
	}

	//編集したCase配下の情報をDBに格納する。
	private boolean updateCaseData(TestCaseRecord rec, ArrayList<Record> removings, HashMap<Integer,TestCommandRecord> cmd, HashMap<String,ObjectRecord> objs, HashMap<Integer,AssertRecord> asrts) {
		//TestCase, TestCommand、ObjectRecord、AssertをDBに保存。（insert/update）
		try {
			if (!Tool._db().saveTestCase(rec, removings, cmd, objs, asrts)) {
				return false;
			}
			rec.saved();
		} catch (SQLException e) {
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.46")+ e.getMessage()); //$NON-NLS-1$
			return false;
		}
		JOptionPane.showMessageDialog(null, Messages.getString("TestCaseBrowser.34")); //$NON-NLS-1$
		return true;
	}

	//指定したCaseを別プロセスで実行する。
	//cNameは"%"を含むことは可能。DBにあるTestCaseのすべてを実行。
	private void execTestCase(TestCaseRecord cdata, boolean editmode) {
		ArrayList<String> t_list = new ArrayList<String>();
		t_list.add(Boolean.toString(editmode));

		if (!m_env.process_mode) {
			if (cdata == null) {
				//全テストケース実行。process_modeでのみdataがnullで渡される。
				t_list.add("[]"); //$NON-NLS-1$
			} else {
				t_list.add(m_curcase.getCmdArgsStyle());
			}
			boolean cur_emode = Tool.editMode();
			Tool.setEditMode(editmode);

			//デバッグできるように同じプロセスで実行する。
			TestCommander.execute(t_list);
			Tool.setEditMode(cur_emode);

		} else {
			if (cdata == null) {
				//全テストケース実行。process_modeでのみdataがnullで渡される。
				t_list.add("-caseName:%"); //$NON-NLS-1$
			} else {
				t_list.add("-caseName:" + m_curcase.name); //$NON-NLS-1$
			}

			//各テストケースを子プロセスで実行。
			t_list.add(0, "-exec&wait"); //$NON-NLS-1$
			TestSubMain.main(t_list.toArray(new String[t_list.size()]));
		}
	}


	//Listで右クリックした時のポップアップメニュー表示
	private void goTestCasePopUp(MouseEvent e, String label) {
		JPopupMenu t_pop = new JPopupMenu();

		//New
		t_pop.add(new JMenuItem(new TestCaseAction(Messages.getString("TestCaseBrowser.9"), this, label))); //$NON-NLS-1$

		if (label != null) {
			//edit
			t_pop.add(new JMenuItem(new TestCaseAction(Messages.getString("TestCaseBrowser.58"), this, label))); //$NON-NLS-1$

			//remove
			t_pop.add(new JMenuItem(new TestCaseAction(Messages.getString("TestCaseBrowser.5"), this, label))); //$NON-NLS-1$
		}

		t_pop.show(e.getComponent(), e.getX(), e.getY());
	}

	//新規テストケース
	private void addTestCase() {
		if (!db_created) {
			//DBに未接続
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.11")); //$NON-NLS-1$
			return;
		}
		if (m_env.rootDirs.size() == 0) {
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.12")); //$NON-NLS-1$
			return;
		}

		TestCaseRecord t_case = Tool._db().getNewTestCase(Tool.version);//DBに登録しているのではない。範囲を取得している。

		TestCaseEditor t_ed = new TestCaseEditor(this, t_case, m_env.hiddenMode); //$NON-NLS-1$
		t_ed.setVisible(true);

		TestCaseRecord t_rec = new TestCaseRecord(2);
		t_ed.copyData(t_rec);

		if (t_ed.isOK()) { //$NON-NLS-1$
			//m_caselistに名前を登録。
			testcase_model.addElement(t_rec.name);
			m_caselist.add(t_rec);

			updateCaseData(t_rec, t_ed.m_removings, t_ed.m_cmds, t_ed.obj_table, t_ed.m_assert);
		}
	}


	//Case名などを変更する。
	private void editCase(String clabel) {
		if (clabel != null && !clabel.startsWith("//")) { //$NON-NLS-1$
			int pos = -1;
			for (int i = 0; i < testcase_model.getSize(); i++) {
				if (testcase_model.get(i) == clabel) {
					pos = i;
					break;
				}
			}

			if (pos >= 0) {
				TestCaseRecord t_rec = m_caselist.get(pos);
				TestCaseEditor t_ed = new TestCaseEditor(this, t_rec, m_env.hiddenMode);
				t_ed.setVisible(true);

				String cur_name = t_rec.name;
				if (t_ed.isOK()) {
					//編集なのでupdateである。case自体は、念のためにUpdateしていても１レコードなので問題ない。
					TestCaseRecord t_rec2 = t_rec._dup();
					t_ed.copyData(t_rec);
					if (!t_rec2.isEquivalentTo(t_rec)) {
						//状態が変わっていたら、変わっていることを示すフラグを立てる。
						t_rec.changed();
					}

					testcase_model.setElementAt(t_rec.name, pos);	//上書き
					txtDesc.setText(t_rec.description);

					if (!t_rec.name.equals(cur_name)) {
						//名前が変更されたなら、情報を書き込む
						t_rec.name += "\t" + cur_name;
					}

					//データ更新
					updateCaseData(t_rec, t_ed.m_removings, t_ed.m_cmds, t_ed.obj_table, t_ed.m_assert);
					if (!t_rec.name.equals(cur_name)) {
						//元に戻す。
						t_rec.name = t_rec.name.replaceFirst("\t.*$","");
					}

					displayCaseStatus();
				}
			}
		}
	}

	//テーブルが未定義ならば生成する。
	private void tryCreateTable() {
		if (Tool._db() == null) {
			//環境設定の内容で、接続を試みる。
			Tool.setEnvironment(m_env);
		}
		if (!db_created) {
			//テーブル生成を試みる。
			Tool._db().createTable();
		} else {
			//接続できていないなら、エラーメッセージは既出のはず。
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.64")); //$NON-NLS-1$
			return;
		}
		if (!Tool._db().isReady()) {
			//テーブル生成に失敗
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.61")); //$NON-NLS-1$
			mntmCreateTable.setEnabled(true);
			db_created = false;
		} else {
			//再定義はしないので不可とする。
			Tool.alertMSG(null, Messages.getString("TestCaseBrowser.65")); //$NON-NLS-1$
			mntmCreateTable.setEnabled(false);
			db_created = true;
		}
	}

	//TesrCase配下のレコードを削除する。
	public void removeCase(String label) {
		int i = testcase_list.getSelectedIndex();
		if (i >= 0) {
			TestCaseRecord t_rec = m_caselist.get(i);
			if (Tool.group_code.length() == 0 || (t_rec.groupCode != null && t_rec.groupCode.equals(Tool.group_code))) {
				//削除する資格を確認
				int t_res = JOptionPane.showConfirmDialog(this, t_rec.name + Messages.getString("TestCaseBrowser.53")); //$NON-NLS-1$
				if(t_res == JOptionPane.YES_OPTION) {
					if (t_rec.name.equals(label)) {
						try {
							Tool._db().removeCase(label, Tool.version);
							JOptionPane.showMessageDialog(null, Messages.getString("TestCaseBrowser.38")); //$NON-NLS-1$
						} catch (SQLException e) {
							Tool.alertMSG(null, Messages.getString("TestCaseBrowser.51")+ e.getMessage()); //$NON-NLS-1$
						}
						m_caselist.remove(i);
						testcase_model.removeElementAt(i);
					}
				}
			} else {
				Tool.alertMSG(null, Messages.getString("TestCaseBrowser.60")); //$NON-NLS-1$
			}
		}
	}


	//popupのコマンド文字列を受けて、TestMasterGUIのメソッドに中継する。
	//中継だけなので、アクションはこのクラスのみ。
	class TestCaseAction extends AbstractAction {
		 String m_name;
		TestCaseBrowser m_master;
		String m_label;

		TestCaseAction(String name, TestCaseBrowser master, String cname) {
			putValue(Action.NAME, name);
			m_name = name;
			m_master = master;
			m_label = cname;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if  (m_name.equals(Messages.getString("TestCaseBrowser.62"))) { //$NON-NLS-1$
				m_master.editCase(m_label);
			} else if (m_name.equals(Messages.getString("TestCaseBrowser.9"))) { //$NON-NLS-1$
				m_master.addTestCase();
			} else if (m_name.equals(Messages.getString("TestCaseBrowser.6"))) { //$NON-NLS-1$
				m_master.removeCase(m_label);
			}
		}
	}

}
