/* $Id: ValidationResultView.java,v 1.2 2007/12/11 09:54:58 nito Exp $
 * 
 * Copyright (c)ARGO 21, Corporation. 2005, 2006.  All rights reserved.
 * 
 * This file is part of Nautica Workflow.
 * 
 *  Nautica Workflow is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 * 
 *  Nautica Workflow is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with Nautica Workflow; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 */
package jp.co.argo21.nautica.tool.wfd;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

import jp.co.argo21.nautica.commons.util.ResourceManager;
import jp.co.argo21.nautica.tool.wfd.element.ActivityElement;
import jp.co.argo21.nautica.tool.wfd.element.ApplicationElement;
import jp.co.argo21.nautica.tool.wfd.element.Element;
import jp.co.argo21.nautica.tool.wfd.element.PackageElement;
import jp.co.argo21.nautica.tool.wfd.element.ParameterElement;
import jp.co.argo21.nautica.tool.wfd.element.ParticipantElement;
import jp.co.argo21.nautica.tool.wfd.element.ProcessElement;
import jp.co.argo21.nautica.tool.wfd.element.TransitionElement;
import jp.co.argo21.nautica.tool.wfd.element.VariableElement;

/**
 * 検証結果表示用ビュー
 * 
 * @author  Norihiro Itoh(ARGO 21 Corp.)
 * @version $Revision: 1.2 $
 * @since   Nautica Workflow 1.0
 */
public class ValidationResultView extends JTabbedPane
{
	/** シリアルバージョンID */
	private static final long serialVersionUID = 1L;

	/** 検証結果 */
	private List<ValidationResult> results;
	/** テーブルの列名 */
	private static String[] columnNames;
	/** テーブルの列幅 */
	private static int[] columnWidths;
	/** 結果の種類名 */
	private static String[] resultKinds;
	/** 枠線 */
	protected static final Border border = BorderFactory.createEtchedBorder();
	/** 検証結果リスト */
	private JTable resultTable;
	
	/**
	 * 定数の初期化
	 */
	static
	{
		ResourceManager rm = WorkflowDesignerManager.getResourceManager();

		columnNames = new String[3];
		columnNames[0] = rm.getResource("ValidationResultTableModel.columnName.0");
		columnNames[1] = rm.getResource("ValidationResultTableModel.columnName.1");
		columnNames[2] = rm.getResource("ValidationResultTableModel.columnName.2");

		columnWidths = new int[3];
		columnWidths[0] = 50;
		columnWidths[1] = 150;
		columnWidths[2] = 400;

		resultKinds = new String[2];
		resultKinds[0] = rm.getResource("ValidationResultTableModel.resultKind.0");
		resultKinds[1] = rm.getResource("ValidationResultTableModel.resultKind.1");
	}

	/**
	 * 検証結果表示用ビューを生成する。
	 */
	public ValidationResultView()
	{
		ResourceManager rm = WorkflowDesignerManager.getResourceManager();

		JPanel panel1 = createResultPanel(rm);
		addTab(rm.getResource("ValidationResultView.tab.0"), panel1);

		validate();
	}
	
	
	/**
	 * パラメータ情報のパネルを生成する。
	 * 
	 * @param rm リソースマネージャ
	 * @return パネル
	 */
	private JPanel createResultPanel(ResourceManager rm)
	{
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.setBorder(border);
		Dimension size = new Dimension(420, 250);
		panel.setSize(size);
		panel.setPreferredSize(size);

		resultTable = new JTable(new ResultTableModel());
		resultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		resultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		resultTable.setRowHeight(35);
		TableColumn column = null;
		for (int i = 0; i < columnWidths.length; i++) {
			column = resultTable.getColumnModel().getColumn(i);
			if (i == 1) column.setCellRenderer(new ElementRenderer());
			column.setPreferredWidth(columnWidths[i]);
		}
		JScrollPane sp = new JScrollPane();
		sp.setViewportView(resultTable);

		panel.add(sp, CENTER);

		validate();
		
		return panel;
	}

	/**
	 * 指定されたコンポーネントの属性を指定の大きさと座標で更新する。
	 * 
	 * @param component 対象コンポーネント
	 * @param x 左上のX座標
	 * @param y 左上のY座標
	 * @param w 幅
	 * @param h 高さ
	 * @return 変更されたコンポーネント
	 */
	protected Component locate(Component component, int x, int y, int w, int h)
	{
		component.setLocation(x, y);
		component.setSize(w, h);
		return  component;
	}
	
	/**
	 * 検証結果を設定する。
	 * 
	 * @param list	検証結果
	 */
	public void setResults(List<ValidationResult> list)
	{
		results = list;
	}

	/**
	 * パラメータテーブル制御モデル
	 */
	class ResultTableModel extends AbstractTableModel
	{
		/** シリアルバージョンID */
		private static final long serialVersionUID = 1L;

		/**
		 * パラメータテーブル制御モデルを生成する。
		 */
		ResultTableModel()
		{
		}

		/**
		 * データソースオブジェクトが管理する列数を返す。
		 * JTableはこのメソッドを使って、初期化時に作成および表示する
		 * 必要のある列数を判断する。
		 *
		 * @return	モデルの列数
		 */
		public int getColumnCount()
		{
			return columnNames.length;
		}

		/**
		 * データソースオブジェクトが管理するレコード数を返す。
		 * JTableはこのメソッドを使って、作成および表示する必要のある行数を判断する。
		 *
		 * @return	モデルの行数
		 */
		public int getRowCount()
		{
			if (results == null) return 0;
			
			return results.size();
		}

		/**
		 * colにある列の名前を返す。
		 * このメソッドは、テーブルの列ヘッダ名を初期化するために使われる。
		 *
		 * @param	col		列のインデックス
		 * @return	列ヘッダ名
		 */
		public String getColumnName(int col)
		{
			return columnNames[col];
		}

		/**
		 * セルの内容を返す。
		 *
		 * @param	row		値が参照される行
		 * @param	col		値が参照される列
		 * @return	指定されたセルにある値
		 */
		public Object getValueAt(int row, int col)
		{
			if (results == null) return "";
			ValidationResult result = (ValidationResult)results.get(row);

			if (col == 0) {
				return resultKinds[result.getKind()];
			} else if (col == 1) {
				return result.getElement();
			} else if (col == 2) {
				return result.getMessage();
			}
			return "";
		}

		/**
		 * 列のClassを返す。
		 *
		 * @param	col		列
		 * @return	モデルのオブジェクト値の共通の上位クラス
		 */
		public Class<?> getColumnClass(int col)
		{
			if (col == 1) return Element.class;
			else return String.class;
		}

		/**
		 * rowとcolにあるセルが編集可能な場合はtrueを返す。
		 * そうでない場合、セルでsetValueAt()を呼び出しても、そのセルの値は変更されない。
		 *
		 * @param	row		値が参照される行
		 * @param	col		値が参照される列
		 * @return	セルが編集可能な場合はtrue
		 */
		public boolean isCellEditable(int row, int col)
		{
			return false;
		}
	}

	/**
	 * 要素セルのレンダラー
	 */
	public class ElementRenderer extends DefaultTableCellRenderer
	{
		/** シリアルバージョンID */
		private static final long serialVersionUID = 1L;

		/**
		 * セルのレンダリングを行う。
		 * 
		 * @param table	テーブル
		 * @param o	セル内容
		 * @param isSelected	選択状態
		 * @param hasFocus	フォーカス状態
		 * @param row	行
		 * @param column	列
		 * @return	レンダリングされたセル
		 * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
		 */
		public Component getTableCellRendererComponent(
		JTable table,
		Object o,
		boolean isSelected,
		boolean hasFocus,
		int row,
		int column)
		{
			super.getTableCellRendererComponent(table, o, isSelected, hasFocus, row, column);

			Element elem = (Element)o;
			setText(getName(elem));
			Icon icon = getIcon(elem);
			if (icon != null) setIcon(icon);
			setToolTipText(getTooltipText(elem));
			return this;
		}

		/**
		 * 要素名を返す。
		 * 
		 * @param e	要素
		 * @return	要素名
		 */		
		private String getName(Element e)
		{
			if (e instanceof TransitionElement) {
				return ((TransitionElement)e).getSource().getName();
			} else {
				return e.getName();
			}
		}
		
		/**
		 * ツールチップ文字列を返す。
		 * 
		 * @param e	要素
		 * @return	ツールチップ文字列
		 */
		private String getTooltipText(Element e)
		{
			ResourceManager rm = WorkflowDesignerManager.getResourceManager();

			if (e instanceof TransitionElement) {
				return ((TransitionElement)e).getSource().getTooltipText(rm);
			} else {
				return e.getTooltipText(rm);
			}
		}

		/**
		 * アイコンを返す。
		 * 
		 * @param e	要素
		 * @return	アイコン
		 */		
		private Icon getIcon(Element e)
		{
			String name = null;
			if (e instanceof PackageElement) {
				name = WorkflowDesignerConstants.EL_PACKAGE + "-cur";
			} else if (e instanceof ParticipantElement) {
				name = WorkflowDesignerConstants.EL_PARTICIPANT + "-cur";
			} else if (e instanceof ApplicationElement) {
				name = WorkflowDesignerConstants.EL_APPLICATION + "-cur";
			} else if (e instanceof VariableElement) {
				name = WorkflowDesignerConstants.EL_VARIABLE + "-cur";
			} else if (e instanceof ProcessElement) {
				name = WorkflowDesignerConstants.EL_PROCESS + "-cur";
			} else if (e instanceof ParameterElement) {
				name = WorkflowDesignerConstants.EL_PARAMETER + "-cur";
			} else if (e instanceof ActivityElement) {
				name = ((ActivityElement)e).getActivityState().getIconName() + "-cur";
			} else if (e instanceof TransitionElement) {
				name = ((TransitionElement)e).getSource().getActivityState().getIconName() + "-cur";
			}
			
			if (name != null) return IconManager.getIcon(name);
			else return null;
		}
	}
}
