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

import java.awt.Color;

import java.util.Vector;

import org.w3c.dom.Node;
import org.w3c.dom.DOMException;

import jp.co.iti.fagot.geom.ZPoint;
import jp.co.iti.fagot.geom.ZPath;
import jp.co.iti.fagot.geom.ZRectangle;

import jp.co.iti.fagot.fob.FColor;

import jp.co.iti.fagot.fob.xml.XElementNS;

import jp.co.iti.fagot.gob.IGobContainer;
import jp.co.iti.fagot.gob.GobManager;
import jp.co.iti.fagot.gob.GElement;
import jp.co.iti.fagot.gob.GRectangle;
import jp.co.iti.fagot.gob.GOperation;
import jp.co.iti.fagot.gob.PTransform;

import jp.co.iti.fagot.util.ZDebug;
/**
 * Gob Containerエレメント
 *
 * コンテナとして必要なメソッド群を定義する。
 * implements IGobContainer はこのクラスの派生クラスである
 * DefaultElement に実装する
 *
 * @author  福島康治
 * @version 1.01 2001/03/22
 */
public class DocElement extends XElementNS implements IGobContainer {

	/**
	 * デフォルトコンストラクタ
	 */
	protected DocElement() throws DOMException {
	}

	//## 基本操作:Rect #################################################
	/**
	 * 矩形を保持しているか？
	 * @param szKey 位置キー
	 */
	public boolean hasRect(String szKey) {
	XElementNS elm = findChildElement(".ViewInfo."+szKey,null);
	if ( elm != null ) {
		return ( elm.hasAttribute("X") &&
				 elm.hasAttribute("Y") &&
				 elm.hasAttribute("Width") &&
				 elm.hasAttribute("Height") ) ;
	}
	return false;
	}

	/**
	 * 矩形の設定
	 * @param szKey 位置キー
	 * @param rect  矩形
	 */
	public void setRect(String szKey, ZRectangle rect) {
	XElementNS elm = getChildElement(".ViewInfo."+szKey,null);
//	ZDebug.trace("DocElement:setRect:"+rect.toString());
//	if ( !szKey.endsWith("child") ) {
//		ZDebug.printStack();
//	}
	elm.setDoubleAttr("X"		, rect.getX());
	elm.setDoubleAttr("Y"		, rect.getY());
	elm.setDoubleAttr("Width"	, rect.getWidth());
	elm.setDoubleAttr("Height"	, rect.getHeight());
	}

	/**
	 * 矩形の取得
	 * @param szKey 位置キー
	 */
	public ZRectangle getRect(String szKey) {
	XElementNS elm = findChildElement(".ViewInfo."+szKey,null);
	if ( elm == null ) {
		return new ZRectangle();
	}
	double dX      = elm.getDoubleAttr("X",0);
	double dY      = elm.getDoubleAttr("Y",0);
	double dWidth  = elm.getDoubleAttr("Width",0);
	double dHeight = elm.getDoubleAttr("Height",0);
	return new ZRectangle( dX, dY, dWidth, dHeight );
	}

	//## 基本操作:Scale ################################################
	/**
	 * 表示倍率の設定
	 * 基本的にルートエレメントのみ保持するアトリビュート
	 * @param szKey 位置キー
	 * @param scale 表示倍率(1の時、100%)
	 */
	public void setDisplayScale(String szKey, double scale) {
	XElementNS elm = getChildElement(".ViewInfo."+szKey,null);
	elm.setDoubleAttr("DisplayScale", scale);
	}

	/**
	 * 表示倍率の取得
	 * 基本的にルートエレメントのみ保持するアトリビュート
	 * @param szKey 位置キー
	 * @param scale 表示倍率(1の時、100%)
	 */
	public double getDisplayScale(String szKey) {
	XElementNS elm = findChildElement(".ViewInfo."+szKey,null);
	if ( elm == null ) {
		return 1;
	}
	return elm.getDoubleAttr("DisplayScale", 1);
//	return 1;
	}

	/**
	 * 表示倍率の取得
	 * 基本的にルートエレメントのみ保持するアトリビュート
	 *
	 * 通常DisplayOffsetは使用しないが、パンパネルなど特殊なパネルで有効となる
	 *
	 * @param szKey 位置キー
	 */
	public PTransform getDisplayScaledTransform(String szKey) {
	XElementNS elm = getChildElement(".ViewInfo."+szKey,null);
	if ( elm == null ) {
		return new PTransform(1,0,0,1,0,0);
	}
	double dX = elm.getDoubleAttr("DisplayOffsetX",0);
	double dY = elm.getDoubleAttr("DisplayOffsetY",0);
	double dZ = getDisplayScale(szKey);
	return new PTransform(dZ,0,0,dZ,dX,dY);
	}

	//## 基本操作:DOM ##################################################
	/**
	 * Gobの削除
	 * @param gob 削除されたgob
	 */
	public void removeGob(GElement gob) {
	removeFromDocTree();
	}

	/**
	 * DOMから削除
	 */
	public void removeFromDocTree() {
	DocElement parent = (DocElement)getParentNode();
	if ( parent != null ) {
		parent.removeChild(this);
	}
	setStatus( "remove" ) ;
	}

	/**
	 * 状態の設定
	 * @param szStatus 状態
	 */
	public void setStatus(String szStatus) {
//	mStatus = szStatus ;
	setAttribute("DocElementStatus",szStatus);
	for ( int nIndex=0; nIndex<getLength() ; nIndex++ ) {
		Node elm = (Node)item(nIndex);
		if ( elm instanceof DocElement ) {
			((DocElement)elm).setStatus( szStatus );
		}
	}
	}

	/**
	 * 状態の取得
	 */
	public String getStatus() {
	return getAttribute("DocElementStatus");
//	return mStatus ;
	}


	//## オーバライド：ドキュメント操作 ###############################
	/**
	 * エレメントの追加
	 * @param element エレメント
	 */
//	public void addElement( DocElement element ) {
//	appendChild(element);
//	}

	/**
	 * 描画エレメントの取得
	 * @param szPanelId パネル識別子
	 * @param isRoot    ルートの有無
	 */
	public Vector createGobs(String szPanelId,boolean isRoot) {
	Vector gobs = new Vector();
//	gobs.addAll(createChildGobs(szPanelId));
	return gobs;
	}

	/**
	 * 描画エレメントの取得の前処理
	 * @param szPanelId パネル識別子
	 */
	public void preCreateGobs(String szPanelId) {
	// 子ノードの描画
	for ( int nIndex=0; nIndex<getLength() ; nIndex++ ) {
		Node elm = (Node)item(nIndex);
		if ( elm instanceof DocElement ) {
			((DocElement)elm).preCreateGobs( szPanelId );
		}
	}
	}

	/**
	 * スケルトン描画エレメントの取得
	 * @param szPanelId パネル識別子
	 * @param isRoot    ルートの有無
	 */
	public Vector createSkeltonGobs(String szPanelId,boolean isRoot) {
	// とりあえず自分自身の描画オブジェクト全てを返す
	return createGobs(szPanelId,isRoot);
	}

	/**
	 * 子ノードの描画エレメントの取得
	 * @param szPanelId パネル識別子
	 */
	public Vector createChildGobs(String szPanelId) {
	Vector gobs = new Vector();
	// 子ノードの描画
	for ( int nIndex=0; nIndex<getLength() ; nIndex++ ) {
		Node elm = (Node)item(nIndex);
		if ( elm instanceof DocElement ) {
			gobs.addAll(((DocElement)elm).createGobs( szPanelId,false ));
		}
	}
	return gobs;
	}

	/**
	 * コンテキストキーの取得
	 * @param szPanelId パネル識別子
	 */
	public String getContextKey(String szPanelId) {
	return getTagName()+"."+szPanelId;
	}

	//## IGobContainer：ヒット ########################################
	/**
	 * 要素にヒットするか？
	 * @param gob リクエスト元Gob
	 * @param pt  論理座標
	 */
	public byte getHitMode(GElement gob,ZPoint pt) {
	return gob.getHitModeGob(pt);
	}

	/**
	 * 要素の移動モードはなにか？
	 * @param gob リクエスト元Gob
	 * @param pt   論理座標
	 */
	public byte getPreMoveMode(GElement gob,ZPoint pt) {
	return gob.getPreMoveModeGob(pt);
	}

	/**
	 * 要素に接続するか？
	 * @param gob リクエスト元Gob
	 * @param pt  論理座標
	 * @param obj  接続対象
	 */
	public byte getConnectMode(GElement gob,ZPoint pt,Object obj) {
	return gob.getConnectModeGob(pt,obj);
	}

	/**
	 * ダブルクリックの動作
	 * @param gob  リクエスト元Gob
	 * @param mode クリック位置
	 */
	public void verbDblClick(GElement gob,ZPoint pt) {
	gob.verbDblClickGob(pt);
	}

	//## IGobContainer：移動 ##########################################
	/**
	 * 移動の開始
	 * @param gob  リクエスト元Gob
	 * @param grid グリッドコントローラ
	 */
	public void moveStart(GElement gob,DocGridControler grid) {
	gob.moveStartGob(grid);
	}

	/**
	 * 移動中Pathの取得
	 * @param gob  リクエスト元Gob
	 * @param grid グリッドコントローラ
	 */
	public ZPath getMovingPath(GElement gob,DocGridControler grid) {
//	ZDebug.trace();
	return gob.getMovingPathGob(grid);
	}

	/**
	 * 移動の完了
	 * @param gob  リクエスト元Gob
	 * @param grid グリッドコントローラ
	 */
	public void moveEnd(GElement gob,DocGridControler grid) {
	gob.moveEnd(grid);
	}

	//## IGobContainer：選択 ##########################################
	/**
	 * 選択の取得
	 */
	public boolean isSelect() {
	return mSelect;
	}

	/**
	 * 選択の設定
	 * @param gob  リクエスト元Gob
	 * @param bSel 選択状態
	 */
	public boolean setSelect(GElement gob,boolean bSel) {
	mSelect = bSel;
	return mSelect;
	}

	//## 編集 #########################################################
	/**
	 * 文字列の設定
	 */
	public void setText(String szText) {
	}

	/**
	 * 文字列の取得
	 */
	public String getText() {
	return null;
	}

	//## SubTag #######################################################
	/**
	 * サブタグの設定
	 * Docbarから生成するときにattributeも固有のものにするためのキー
	 * @param szText サブタグ
	 */
	public void setSubTag(String szText) {
	}

	//## アトリビュート################################################
	/**
	 * 選択有無
	 */
	protected boolean  mSelect     = false;

}
