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

import java.awt.Color;
import java.awt.Dimension;

import java.util.Vector;
import java.util.Properties;

import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.DOMException;

import jp.co.iti.fagot.fob.FobManager;
import jp.co.iti.fagot.fob.xml.XDocument;

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

import jp.co.iti.fagot.gob.PTransform;

import jp.co.iti.fagot.util.ZProperties;
import jp.co.iti.fagot.util.ZString;
import jp.co.iti.fagot.util.ZDebug;
/**
 * 描画部品を保持するドキュメントです。
 *
 * @author  福島康治
 * @version 1.01 2001/03/22
 */
public class DocDocument extends XDocument {
//public class DocDocument extends org.apache.xerces.dom.DeferredDocumentImpl {

	/**
	 * コンストラクタ
	 */
	public DocDocument(){
	}

	/**
	 * コンストラクタ
	 * @param szDocumentId ドキュメント識別子
	 */
	public DocDocument(String szDocumentId){
	this();
	setDocumentId(szDocumentId);
	}

	/**
	 * idの設定
	 * @param szDocumentId ドキュメント識別子
	 */
	public void setDocumentId(String szDocumentId) {
	mDocumentId = szDocumentId;

	// プロパティロード
	ZProperties prop = DocManager.loadProperty( DocManager.DOCUMENT );
	setEncoding(prop.getProperty(mDocumentId+".encoding"));
	mIndenting = prop.getBoolean(mDocumentId+".indenting",true);
	}

	/**
	 * idの取得
	 * @param ドキュメントId
	 */
	public String getDocumentId() {
	return mDocumentId;
	}

	/**
	 * エンコーディングの取得
	 * @param エンコーディング
	 */
//	public String getEncoding() {
//	return mEncoding;
//	}

	/**
	 * インデントの取得
	 * @param インデント
	 */
	public boolean getIndenting() {
	return mIndenting;
	}

	//## パネルから呼び出されるメソッド ###############################
	/**
	 * 背景色の取得
	 * @param szPanelId パネル識別子
	 */
	public Color getBackground(String szPanelId) {
	return new Color(0xFFFFFF);
	}

	/**
	 * コンポーネントに最適なサイズを返します
	 * ルートエレメントの表示倍率と論理サイズをかけ合わせます
	 */
	public Dimension getPreferredSize(String szPanelId) {
	DocElement root = (DocElement)getRootElement(szPanelId);
	if ( root == null ) {
		return getLogicalSize();
	}
	double scale = root.getDisplayScale(szPanelId);
	// 単純な掛け算だが、桁落ちしないようPTransformで計算する
	// offsetが0でないかもしれないので、getDisplayScaledTransformは使用しない
	PTransform trans = new PTransform(scale,0,0,scale,0,0);
	Dimension dim = getLogicalSize();
	ZPoint pttrans = trans.transform(new ZPoint(dim.getWidth(),dim.getHeight()));
	dim = new Dimension((int)pttrans.getX(),(int)pttrans.getY());
//	ZDebug.trace(dim.toString());
	return dim;
	}

	/**
	 * コンポーネントの論理的な最適サイズを返します
	 * この値は拡大縮小表示の有無にかかわらず固定です。
	 *
	 * getPreferredSizeは拡大表示されると大きくなり、縮小表示されると小さくなります
	 */
	public Dimension getLogicalSize() {
	return new Dimension(800,600);
	}

	//## IDocument ####################################################
	/**
	 * 初期化
	 */
	public void initDocument() {
	ZProperties prop = DocManager.loadProperty( DocManager.DOCUMENT );

	// ドキュメントタイプ
	String szRoot   = prop.getProperty(mDocumentId+".doctype.root");
	String szPublic = prop.getProperty(mDocumentId+".doctype.public");
	String szSystem = prop.getProperty(mDocumentId+".doctype.ststem");
	if ( szPublic != null || szSystem != null ) {
		DocumentType doctype = createDocumentType( szRoot, szPublic, szSystem );
		appendChild(doctype);
	}

	// Processing instruction
	for ( int nIndex=1 ; nIndex<100 ; nIndex++ ) {
		String target = prop.getProperty(mDocumentId+".processinginstruction.target."+nIndex);
		String data   = prop.getProperty(mDocumentId+".processinginstruction.data."+nIndex);
		if ( target != null && data != null ) {
			ProcessingInstruction pi = createProcessingInstruction(target, data);
			appendChild(pi);
		} else {
			break;
		}
	}

	// ルートエレメントの作成
	Element elm = createElementNS(null,szRoot);
	appendChild(elm);
	}

	//## 固有 #########################################################
	/**
	 * 現在ルートの取得
	 * @param szPanelId
	 */
	public Element getRootElement(String szPanelId) {
	return getDocumentElement();
	}

	//## オーバライド：DOMファクトリー ################################
	/**
	 * エレメント
	 */
	public Element createElement(String tagName) throws DOMException {
	return createElementNS(null,tagName);
	}

	//## オーバライド：DOM2 NameSpace ファクトリー ####################
	/**
	 * エレメント
	 * @param ns    ネームスペース
	 * @param name  タグ名
	 */
	public Element createElementNS(String ns, String name) throws DOMException {
	Element elm = (Element)DocManager.createElement(this,ns,name);
	// 見つからない場合は親クラスから抽出
	if ( elm == null ) {
		// 詳細タイプがあるか？
		String [] names = ZString.tokenize(name,"@");
		if ( names.length == 2 ) {
			elm = (Element)DocManager.createElement(this,ns,names[0]);
			if ( elm instanceof DocElement ) {
				((DocElement)elm).setSubTag( names[1] );
			}
		} else {
			elm = new DocElement();
			((DocElement)elm).constructElement(this,ns,name);
		}
	}
	return elm;
	}

	//## その他 #######################################################
	/**
	 * 描画エレメントの取得
	 * @param szPanelId パネル識別子
	 */
	public Vector createGobs(String szPanelId) {
	DocElement elm = (DocElement)getRootElement(szPanelId);
	if ( elm != null ) {
		return elm.createGobs(szPanelId,true);
	}
	return new Vector();
	}

	/**
	 * 描画エレメントの取得
	 * @param szPanelId パネル識別子
	 */
	public Vector createSkeltonGobs(String szPanelId) {
	DocElement elm = (DocElement)getRootElement(szPanelId);
	if ( elm != null ) {
		return elm.createSkeltonGobs(szPanelId,true);
	}
	return new Vector();
	}

	//## アトリビュート ###############################################
	/**
	 * ドキュメントID
	 */
	protected String mDocumentId = "default";

	/**
	 * エンコーディング
	 */
//	protected String mEncoding = null;

	/**
	 * インデント
	 */
	protected boolean mIndenting = true;
}
