/* $Id: ProcessDesignView.java,v 1.3 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.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import jp.co.argo21.nautica.commons.util.ResourceManager;
import jp.co.argo21.nautica.tool.wfd.element.ProcessElement;

/**
 * ワークフローイメージを描画するビューを組み込んだ
 * カスタムスクロールコンポーネント。
 * ProcessFlowViewを持ち、フローアイテムのドラッグ＆ドロップ、
 * 編集などの機能を持つ。
 * 
 * @author  Norihiro Itoh(ARGO 21 Corp.)
 * @version $Revision: 1.3 $
 * @since   Nautica Workflow 1.0
 */
public class ProcessDesignView
extends JScrollPane
implements ModeChangeListener, ChangeListener
{
	/** シリアルバージョンID */
	private static final long serialVersionUID = 1L;

	/** フロー描画用ビュー */
	private ProcessFlowView view;
	/** 横軸のルーラ */
	private Ruler topRuler;
	/** 縦軸のルーラ */
	private Ruler leftRuler;
	/** プロセス情報表示ボタン */
	private JButton processInfoButton;
	/** アクティビティ情報表示ボタン */
	private JButton dividerButton;
	
	/**
	 * フローデザイン用のスクロールビューを生成する。
	 * 
	 * @param proc プロセス
	 */
	public ProcessDesignView(ProcessElement proc)
	{
		ResourceManager rm = WorkflowDesignerManager.getResourceManager();

		Dimension resizingSize = new Dimension(15, 15);

		ResizingCorner topResizing = new ResizingCorner(ResizingCorner.TOP);
		topResizing.setToolTipText(rm.getResource("ProcessDesignView.tooltip.0"));
		topResizing.setPreferredSize(resizingSize);
		topResizing.setSize(resizingSize);
		ResizingCorner leftResizing = new ResizingCorner(ResizingCorner.LEFT);
		leftResizing.setToolTipText(rm.getResource("ProcessDesignView.tooltip.1"));
		leftResizing.setPreferredSize(resizingSize);
		leftResizing.setSize(resizingSize);
		ResizingCorner rightResizing = new ResizingCorner(ResizingCorner.RIGHT);
		rightResizing.setToolTipText(rm.getResource("ProcessDesignView.tooltip.2"));
		rightResizing.setPreferredSize(resizingSize);
		rightResizing.setSize(resizingSize);
		ResizingCorner bottomResizing = new ResizingCorner(ResizingCorner.BOTTOM);
		bottomResizing.setToolTipText(rm.getResource("ProcessDesignView.tooltip.3"));
		bottomResizing.setPreferredSize(resizingSize);
		bottomResizing.setSize(resizingSize);
		
		topResizing.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					view.reduceHeight();
				}
			}
		);
		
		leftResizing.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					view.reduceWidth();
				}
			}
		);
		
		rightResizing.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					view.expandWidth();
				}
			}
		);
		
		bottomResizing.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					view.expandHeight();
				}
			}
		);
		
		JPanel urCorner = new JPanel();
		urCorner.setLayout(new BorderLayout());
		urCorner.add(leftResizing, BorderLayout.NORTH);
		urCorner.add(rightResizing, BorderLayout.SOUTH);

		JPanel llCorner = new JPanel();
		llCorner.setLayout(new BorderLayout());
		llCorner.add(topResizing, BorderLayout.WEST);
		llCorner.add(bottomResizing, BorderLayout.EAST);

		processInfoButton = new JButton(IconManager.getIcon("process-mini"));
		processInfoButton.setToolTipText(rm.getResource("ProcessDesignView.tooltip.4"));

		dividerButton = new JButton();
		dividerButton.setBackground(Color.orange);
		dividerButton.setBackground(Color.orange);
		dividerButton.setToolTipText(rm.getResource("ProcessDesignView.tooltip.5"));

		topRuler = new Ruler(Ruler.HORIZONTAL, ProcessFlowView.GRID_SIZE);
		leftRuler = new Ruler(Ruler.VERTICAL, ProcessFlowView.GRID_SIZE);

		setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		setCorner(UPPER_RIGHT_CORNER, urCorner);
		setCorner(LOWER_LEFT_CORNER, llCorner);
		setCorner(UPPER_LEFT_CORNER, processInfoButton);
		setCorner(LOWER_RIGHT_CORNER, dividerButton);

		setColumnHeaderView(topRuler);
		setRowHeaderView(leftRuler);

		view = new ProcessFlowView(proc);
		setViewportView(view);
		viewport.addChangeListener(this);
	}

	/**
	 * ビューポートに変更があった場合に呼ばれる。
	 * 主にルーラの描画更新のため。
	 * 
	 * @param e 変更イベント
	 * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
	 */
	public void stateChanged(ChangeEvent e)
	{
		Dimension viewSize = view.getSize();

		Dimension topSize = topRuler.getPreferredSize();
		topSize.setSize(topSize.width, 30);
		if (topSize.width != viewSize.width) {
			topSize.width = viewSize.width;
			topRuler.setPreferredSize(topSize);
			topRuler.setSize(topSize);
			topRuler.repaint();
		} 

		Dimension leftSize = leftRuler.getPreferredSize();
		leftSize.setSize(30, leftSize.height);
		if (leftSize.height != viewSize.height) {
			leftSize.height = viewSize.height;
			leftRuler.setPreferredSize(leftSize);
			leftRuler.setSize(leftSize);
			leftRuler.repaint();
		}
	}

	/**
	 * モードが変わった場合に呼ばれる。
	 * モードは、編集モードと接続モードがある。
	 * デフォルトは編集モード。
	 * 
	 * @param mode モード
	 * @see jp.co.argo21.nautica.tool.wfd.ModeChangeListener#modeChanged(int)
	 */
	public void modeChanged(int mode)
	{
		if (mode == FlowDesignToolBar.CONNECT_MODE) {
			view.setControllerID(ProcessFlowView.CONNECT_CONTROLLER);
		} else if (mode == FlowDesignToolBar.SIM_MODE) {
			view.setControllerID(ProcessFlowView.SIMULATE_CONTROLLER);
		} else {
			view.setControllerID(ProcessFlowView.POINT_CONTROLLER);
		}
	}

	/**
	 * フロー描画用ビューを返す。
	 * 
	 * @return	フロー描画用ビュー
	 */
	public ProcessFlowView getProcessFlowView()
	{
		return view;
	}
	
	/**
	 * プロセス情報用のリスナーを追加する。
	 * 
	 * 
	 * @param listener	リスナー
	 */
	public void addProcessInfoActionListener(ActionListener listener)
	{
		processInfoButton.addActionListener(listener);
	}
	
	/**
	 * デバイダー用のリスナーを追加する。
	 * 
	 * 
	 * @param listener	リスナー
	 */
	public void addDividerActionListener(ActionListener listener)
	{
		dividerButton.addActionListener(listener);
	}
}
