/*
 * @(#)DocBar.java
 *
 * Copyright 2001 by Intelligent Technology Inc. All rights reserved.
 *
 * Document Toolbar
 */
package jp.co.iti.fagot.doc;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Properties;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JToolBar;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JToggleButton;
import javax.swing.JRadioButton;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;

import jp.co.iti.fagot.ZApp;

import jp.co.iti.fagot.util.ZInstance;
import jp.co.iti.fagot.util.ZProperties;
import jp.co.iti.fagot.util.ZResource;
import jp.co.iti.fagot.util.ZString;
import jp.co.iti.fagot.util.ZDebug;
/**
 * Documentに貼り付けるElementを定義するToolbar<br>
 * 
 * Install Dir\\Conf\\Docbarディレクトリに定義されているElement作成用ツールバーを
 * 作成する。Docbarディレクトリには次のファイル群が格納されている
 * <ui>
 * <li>共通メニュー用ツール定義ファイル(docbar.properties)
 * <li>それぞれのツールに対応するgifイメージ
 * </ul>
 *
 * 定義ファイルには次の情報が格納されている
 * <ui>
 * <li>パネル情報
 *   <ui>
 *   <li>パネル数(panel.count)
 *   <li>パネル毎のツール情報(panel.<i>number</i>)。記号の意味は次のとおり
 *       <center><table>
 *         <tr><th>記号</th><th>意味</th></tr>
 *         <tr><td>()</td><td>ツールのグループ化(横配列)</td></tr>
 *         <tr><td>+</td><td>ボタンをトグルボタンに設定</td></tr>
 *       </table></center>
 *   </ul>
 * <li>ツール定義情報
 *   <ui>
 *   <li>ツール用gifイメージ(<i>tool name</i>.image)
 *   <li>ボタンが押されたときのアクション(<i>tool name</i>.action)
 *   <li>ツールチップ文字列(<i>tool name</i>.tooltip)
 *   </ul>
 * </ul>
 * 
 * @author  福島康治
 * @version 1.01 2002/10/23
 */
public class DocBar extends JToolBar{

	/**
	 * コンストラクタ
	 */
    public DocBar() {
	super();
	}

	/**
	 * アクティブなパネルの切替
	 * @param nPanel パネル番号
	 */
    public void setPanel( int nPanel ) {
	// 一旦全て削除
	removeAll();
	mToolItems	 = new Hashtable();
	mCurrentButton = null;

	// プロパティの読込み
	ZProperties prop = DocManager.loadProperty( DocManager.DOC_BAR );
	String[] szToolKeys=ZString.tokenize(prop.getProperty("panel."+nPanel));
	loadTools(prop,szToolKeys);

	// 下に空白コンポーネントを設定して上詰
//	add(Box.createVerticalGlue());

	// 再描画
	validate();
	repaint();
	}

	/**
	 * ツール項目を取得します。
	 * ボタン以外のUIコンポーネントを変更する場合に使用します。
	 * @param szKey  項目名
	 */
	public Component getToolItem(String szKey) {
	return (Component) mToolItems.get(szKey);
	}

	//## ツールの作成 #################################################
	/**
	 * ツールの読込み
	 * @param prop       プロパティファイル
	 * @param szToolKeys ツール項目の配列
	 */
	public void loadTools( Properties prop, String[] szToolKeys ){

	JPanel tmpPanel = null;
	for (int nIndex = 0; nIndex < szToolKeys.length; nIndex++) {
		Component cmp = null;
	    if (szToolKeys[nIndex].equals("-")) {
//			cmp = Box.createVerticalStrut(5);
			cmp = Box.createHorizontalStrut(5);
//			cmp = new Box.Filler(new Dimension(0,0), new Dimension(0,0), 
//			  new Dimension(0, 1000000));
	    } else if (szToolKeys[nIndex].equals("(")) {
			tmpPanel = new JPanel();
			tmpPanel.setAlignmentX(0.0f);
			tmpPanel.setLayout( new BoxLayout( tmpPanel, BoxLayout.X_AXIS ) );
	    } else if (szToolKeys[nIndex].equals(")")) {
			cmp = tmpPanel;
			tmpPanel = null;
	    } else {
			// 部品の作成
			cmp = createTool(prop, szToolKeys[nIndex]);
			mToolItems.put(szToolKeys[nIndex], cmp);

			// デフォルトボタンの登録
			if ( mCurrentButton == null && cmp instanceof JToggleButton &&
				!(cmp instanceof JRadioButton) ) {
				mCurrentButton = (JToggleButton)cmp;
				mCurrentButton.setSelected(true);
				ZInstance.prop().put(ACTION,szToolKeys[nIndex].substring(1));
			}

			// サブパネルに貼り付ける場合
			if ( cmp == null ) {
				ZDebug.err("Create tool failed.("+szToolKeys[nIndex]+")");
			} else if ( tmpPanel != null ) {
				tmpPanel.add(cmp);
				cmp = null ;
			}
		}
	    if ( cmp != null) {
			add(cmp);
//			ZDebug.trace(cmp.toString());
		}
	}
	}

	/**
	 * ツール項目を作成します。
	 * @param prop      プロパティファイル
	 * @param szToolKey ツール項目
	 */
	public Component createTool(Properties prop, String szToolKey) {
	String szToolClass = prop.getProperty( szToolKey + SFX_CLASS );

	Component cmp = null;
	if ( szToolClass == null ) {
		cmp = createButton(prop, szToolKey);
	} else if ( szToolClass.equals("Label") ){
		cmp = createLabel(prop, szToolKey);
	} else {
		// クラス名の取得
		Class cClass;
		try {
			cClass = Class.forName( szToolClass );
		} catch ( ClassNotFoundException cn ) {
			ZDebug.err ( "ClassNotFound:" + szToolClass ) ;
			return null ;
		}

		// インスタンス化
		Object obj ;
		try {
			obj = cClass.newInstance();
		} catch ( InstantiationException ie ) {
			ZDebug.err ( "Class newInstance Failed:" + szToolClass ) ;
			return null ;
		} catch ( IllegalAccessException ia ) {
			ZDebug.err ( "Class newInstance Failed:" + szToolClass ) ;
			return null ;
		}

		if ( ! ( obj instanceof Component ) ) {
			ZDebug.err ( "Class is not instanceof Compenent:" + szToolClass ) ;
			return null ;
		}
		cmp = (Component) obj;
		initializeComponent( prop, szToolKey, cmp );
	}
	return cmp ;
	}

	/**
	 * ツールボタンを作成します。
	 * @param prop      プロパティファイル
	 * @param szToolKey ツール項目
	 */
	protected Component createButton(Properties prop, String szToolKey) {
	// トグルボタンチェック
	boolean bToggled = false ;
	if ( szToolKey.startsWith(TOGGLED) ) {
		bToggled = true ;
		szToolKey = szToolKey.substring(1);
	}

	// イメージの取得
	String szImage = DocManager.getConfigFile( DocManager.DOC_BAR, 
						prop.getProperty( szToolKey + SFX_IMAGE ) );
    AbstractButton btn ;
	ImageIcon img = new ImageIcon(szImage);
	if ( img == null ) {
		ZDebug.err( "Resouce not found:"+szImage );
		return null;
	}

	// ボタンの作成
	if ( bToggled ) {
		btn = new JToggleButton();
	} else {
		btn = new JButton();
	}
	btn.setAlignmentY(0.5f);
    btn.setRequestFocusEnabled(false);
    btn.setMargin(new Insets(1,1,1,1));

	btn.setText(null);
	btn.setIcon(img);

	// ツールチップの設定
	String szTip = prop.getProperty( szToolKey + SFX_TOOLTIP );
	if (szTip == null) {
		szTip = szToolKey;
	}
	if (szTip != null) {
	    btn.setToolTipText(szTip);
	}
	initializeComponent( prop, szToolKey, btn );
    return btn;
	}

	/**
	 * ラベルを作成します。
	 * @param prop      プロパティファイル
	 * @param szToolKey ツール項目
	 */

	protected Component createLabel(Properties prop, String szToolKey) {
	// イメージの取得
	String szImage = DocManager.getConfigFile( DocManager.DOC_BAR, 
						prop.getProperty( szToolKey + SFX_IMAGE ) );
	ImageIcon img = new ImageIcon(szImage);
	if ( img == null ) {
		ZDebug.err( "Resouce not found:"+szImage );
		return null;
	}

	JLabel label = new JLabel();
	label.setAlignmentY(0.5f);
//    label.setRequestFocusEnabled(false);
//    label.setMargin(new Insets(1,1,1,1));

	label.setText(null);
	label.setIcon(img);

	// ツールチップの設定
	String szTip = prop.getProperty( szToolKey + SFX_TOOLTIP );
	if (szTip == null) {
		szTip = szToolKey;
	}
	if (szTip != null) {
	    label.setToolTipText(szTip);
	}

	Dimension dim = label.getPreferredSize();
	dim.width = 69;
	label.setPreferredSize(dim);
	label.setMinimumSize(dim);
//    ((JComboBox)cmp).setAlignmentX(0.0f);

//	initializeComponent( prop, szToolKey, btn );
    return label;
	}

	/**
	 * コンポーネントの初期化
	 * @param prop      プロパティファイル
	 * @param szToolKey ツール項目
	 * @param cmp コンポーネント
	 */
	protected void initializeComponent(Properties prop, String szToolKey,Component cmp) {
	// 初期化スクリプトの設定
	String szScript = prop.getProperty( szToolKey + SFX_SCRIPT );
	if ( szScript == null ) {
		// トグルボタンなら状態変更を保存
		if ( cmp instanceof JToggleButton ) {
			Action act = new AbstractAction( szToolKey ){
			public void actionPerformed(ActionEvent evt) {
				// ボタン状態のクリア
				if ( mCurrentButton != null ) {
					mCurrentButton.setSelected(false);
				}

				// ボタン状態の設定
				JToggleButton myButton = (JToggleButton)evt.getSource();
				myButton.setSelected(true);
				mCurrentButton = myButton;
//				ZDebug.trace("on:"+getValue(Action.NAME));
				ZInstance.prop().put(ACTION,getValue(Action.NAME));
			}
			};
			((JToggleButton)cmp).addActionListener(act);

		// コンボボックスならサイズ変更
		} else if ( cmp instanceof JComboBox ) {
			Dimension dim = cmp.getPreferredSize();
			dim.width = 69;
			((JComboBox)cmp).setPreferredSize(dim);
			((JComboBox)cmp).setMinimumSize(dim);
		    ((JComboBox)cmp).setAlignmentX(0.0f);
		}
	} else {
		// コンポーネントの初期化
		Object[] iniObjs = { cmp };
		DocManager.invokeDocBarFunction(szToolKey,"initialize",iniObjs);

		// アクションリスナーの登録
		if ( cmp instanceof JComboBox ) {
			Action act = new AbstractAction( szToolKey ){
			public void actionPerformed(ActionEvent evt) {
				String szName = (String)getValue(Action.NAME);
				Object[] actObjs = { evt };
				DocManager.invokeDocBarFunction(szName,"actionPerformed",actObjs);
			}
			};
			((JComboBox)cmp).addActionListener(act);

		// アクションリスナーの登録
		} else if ( cmp instanceof JToggleButton ) {
			if ( szToolKey.startsWith("svg_") ) {
				/**
				 ** SVG系の特殊処理
				 **/
				Action act = new AbstractAction( szToolKey ){
				public void actionPerformed(ActionEvent evt) {
					// ボタン状態のクリア
					if ( mCurrentButton != null ) {
						mCurrentButton.setSelected(false);
					}

					// ボタン状態の設定
					JToggleButton myButton = (JToggleButton)evt.getSource();
					myButton.setSelected(true);
					mCurrentButton = myButton;
//					ZDebug.trace("on:"+getValue(Action.NAME));
					ZInstance.prop().put(ACTION,getValue(Action.NAME));

					String szName = (String)getValue(Action.NAME);
					Object[] actObjs = { new DocBarEvent(evt,szName) };
					DocManager.invokeDocBarFunction(szName,"actionPerformed",actObjs);

				}
				};
				((JToggleButton)cmp).addActionListener(act);

			} else {
				// その他のトグルボタン
				Action act = new AbstractAction( szToolKey ){
				public void actionPerformed(ActionEvent evt) {
					String szName = (String)getValue(Action.NAME);
					Object[] actObjs = { evt };
					DocManager.invokeDocBarFunction(szName,"actionPerformed",actObjs);
				}
				};
				((JToggleButton)cmp).addActionListener(act);
			}
		}
	}
	}
	
	static private Hashtable icons = new Hashtable();
	
	static public ImageIcon getDocBarIcon(String name){
		ImageIcon icon = (ImageIcon)icons.get(name);
		if(null == icon){
			icon = new ImageIcon( DocManager.getConfigFile(DocManager.DOC_BAR, name) );
			icons.put(name, icon);
		}
		
		return icon;
	}

	//## アトリビュート ###############################################
    /**
	 * カレントボタン
     */
    protected JToggleButton mCurrentButton = null;

    /**
	 * ツールハッシュマップ
     */
    protected Hashtable	mToolItems	 = new Hashtable();

    /**
	 * リソース取得用文字列：イメージ
     */
    public static final String SFX_IMAGE   = ".image";

    /**
	 * リソース取得用文字列：スクリプト
     */
    public static final String SFX_SCRIPT  = ".script";

    /**
	 * リソース取得用文字列：ツールチップ
     */
    public static final String SFX_TOOLTIP = ".tooltip";

    /**
	 * リソース取得用文字列：クラス
     */
    public static final String SFX_CLASS   = ".class";

    /**
	 * リソース取得用文字列：トグルボタン
     */
	public static final String TOGGLED		= "+";

    /**
	 * インスタンスマネージャ登録キー
     */
	public  static final String ACTION		= "docbar.action";

    /**
	 * 特殊用途のボタンキー：選択
     */
	public  static final String SELECT_ACTION	= "select";

    /**
	 * 特殊用途のボタンキー：手づかみ移動
     */
	public  static final String MOVE_ACTION		= "move";

    /**
	 * 特殊用途のボタンキー：拡大縮小
     */
	public  static final String ZOOM_ACTION		= "zoom";
}
