/*
 * @(#)GString.java
 *
 * Copyright 2001 by Intelligent Technology Inc. All rights reserved.
 */

package jp.co.iti.fagot.gob;

import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Shape;
import java.awt.Font;
import java.awt.Rectangle;

import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.font.TextAttribute;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import java.text.AttributedString;
import java.text.AttributedCharacterIterator;

import jp.co.iti.fagot.ZApp;

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

import jp.co.iti.fagot.fob.FobManager;
import jp.co.iti.fagot.fob.FInteger;
import jp.co.iti.fagot.fob.FString;

import jp.co.iti.fagot.doc.DocGraphics;
import jp.co.iti.fagot.doc.DocGridControler;

import jp.co.iti.fagot.util.ZGraphicUtil;
import jp.co.iti.fagot.util.ZResource;
import jp.co.iti.fagot.util.ZString;
import jp.co.iti.fagot.util.ZDebug;
/**
 * String
 * 文字列描画の一般的な形式を定義します
 *
 * @author  福島康治
 * @version 1.01 2001/01/07
 */
public class GString extends GRectangle {

	/**
	 * コンストラクタ
	 */
	public GString() {
		super();
		//{{FAGOT_ATTR
		mText       = new FString();
		mFormat     = new FInteger();
		mFontName   = new FString();
		mFontSize   = new FString();
		//}}FAGOT_ATTR
	}

	//## 位置##########################################################
	/**
	 * 描画開始X座標の取得
	 */
	public double getX() {
	return mX;
	}

	/**
	 * 描画開始Y座標の取得
	 */
	public double getY() {
	return mY;
	}

	//## 描画##########################################################
	/**
	 * 描画
	 * @param g グラフィックス
	 */
	public void paintContents(DocGraphics graphics) {
	if ( mTl == null ) {
		createTextLayout(graphics);
	}
	if ( mTl != null ) {
		mTl.draw(graphics.getGraphics(), (float)mX, (float)(mY + mTl.getAscent()));
 	}
	}

	/**
	 * 性能向上のため描画を間引くか否かを判定する。
	 * main gobでのみ判定し、子gobはmain gobに従う
	 * @param graphics グラフィックス
	 */
	protected boolean paintCheck(DocGraphics graphics) {
	boolean bPaint = true;
	createTextLayout(graphics);

	if ( mTl != null ) {
		// クリップ領域に座標が含まれない場合は、描画しない
		DocGridControler grid  = graphics.getGridControler();
		Rectangle clipRect = graphics.getGraphics().getClipBounds();
		if ( grid.getScaleTransform().getScaleY()<0.1 ) {
			bPaint = false;
		} else if (  clipRect != null &&
			( clipRect.x > (mPaintRect.getX()+mPaintRect.getWidth())  || (clipRect.x+clipRect.width)  < mPaintRect.getX() ) &&
			( clipRect.y > (mPaintRect.getY()+mPaintRect.getHeight()) || (clipRect.y+clipRect.height) < mPaintRect.getY() ) ) {
			bPaint = false;
		}
	} else {
		bPaint = false;
	}

	return bPaint;
	}
	
	
	
	/**
	 * テキストレイアウトの作成
	 * @param graphics グラフィックス
	 */
	protected void createTextLayout(DocGraphics graphics) {
	String szText = getText();
	if ( szText == null ) {
		return ;
	}
	int nLen = szText.length() ;
	if ( nLen<0 ) {
		return ;
	}

	// 描画位置のチェック
	DocGridControler grid  = graphics.getGridControler();
	mPaintRect = grid.transform(getRect()).getBounds2D();

	// テキストレイアウトの作成
	ZResource res = ZApp.getTheApp().getResource();
	String szFont = getFontName();
	if ( szFont == null ) {
		szFont = res.getString("app.font.name");
	}
	int nSize = ZString.parseInt( getFontSize(),0 );
	if ( nSize == 0 ) {
		nSize = res.getInt("app.font.size",10);
	}
	
//	ZDebug.trace(getText()+" name:"+szFont+" size="+nSize);
//	Font font = new Font(szFont,0,nSize);
	
	AffineTransform  at    = grid.getScaleTransform();
	// ZDebug.trace(getText()+" "+at.getType()+" "+at.getScaleX()+","+at.getScaleY());
	
	PStyle           style = getStyle();
//	mlbm = ZApp.createLineBreakMeasurer(szText,font,null,style.getFillColor().get(),at);
	mlbm = ZGraphicUtil.createLineBreakMeasurer(szText, szFont, new Float(nSize * at.getScaleX()), null, style.getFillColor().get(), graphics.getGraphics().getFontRenderContext());
	
	// 描画開始位置を設定する
	// 性能改善のため、dimは必要なときに計算する
	ZDimension dim = null;
	float fx = (float)mPaintRect.getX();
	float fy = (float)mPaintRect.getY();
//	ZDebug.trace("GString:trans:"+getText()+" "+fx+","+fy);
	// X座標
	if ( (getFormat() & CENTER)!=0 ) {
		dim = ZGraphicUtil.getTextPreferredSize(mlbm,at,nLen,0);
		fx += (( mPaintRect.getWidth()-dim.getWidth() ) / 2 );
	} else if ( (getFormat() & RIGHT)!=0 ) {
		dim = ZGraphicUtil.getTextPreferredSize(mlbm,at,nLen,0);
		fx += (( mPaintRect.getWidth()-dim.getWidth() ) );
	}

	// Y座標
	if ( (getFormat() & MIDDLE)!=0 ) {
//		if ( dim==null ){dim = ZGraphicUtil.getTextPreferredSize(mlbm,at,nLen,0);}
//		fy += (( mPaintRect.getHeight()-dim.getHeight() ) / 2 );
	} else if ( (getFormat() & BOTTOM)!=0 ) {
		if ( dim==null ){dim = ZGraphicUtil.getTextPreferredSize(mlbm,at,nLen,0);}
		fy += (( mPaintRect.getHeight()-dim.getHeight() ) );
	}

	mTl = mlbm.nextLayout((float)mPaintRect.getWidth());
	
    // テキストの基準点はベースラインにあるので、それを左上にする
//	fy += grid.transformY(mTl.getAscent());

	// 描画開始位置を保存する
	mX = (double)fx;
	mY = (double)fy;



	}

	//## FAGOT ########################################################
	/**
	 * 文字列の設定
	 * @param szText 文字列
	 */
	public void setText(String szText) {
		mText.set( szText );
		mlbm = null;
		mTl  = null;
	}

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

	/**
	 * 表示形式の設定
	 * @param int nFormat 表示形式
	 */
	public void setFormat(int nFormat) {
		mFormat.set( nFormat );
	}

	/**
	 * 表示形式の取得
	 */
	public int getFormat() {
	return mFormat.get();
	}

	/**
	 * フォント名の設定
	 * @param szFontName フォント名
	 */
	public void setFontName(String szFontName) {
		mFontName.set( szFontName );
		mlbm = null;
		mTl  = null;
	}

	/**
	 * フォント名の取得
	 */
	public String getFontName() {
	return mFontName.getString();
	}

	/**
	 * フォントサイズの設定
	 * @param szFontName フォントサイズ
	 */
	public void setFontSize(String szFontSize) {
		mFontSize.set( szFontSize );
		mlbm = null;
		mTl  = null;
	}

	/**
	 * フォントサイズの取得
	 */
	public String getFontSize() {
	return mFontSize.getString();
	}

	/**
	 * Fobマネージャの登録
	 * @param mgr マネージャ
	 */
	public void setFobManager(FobManager mgr) {
		super.setFobManager(mgr);
		//{{FAGOT_ATTR
		mText.setFobManager(mgr,this);
		mFormat.setFobManager(mgr,this);
		mFontName.setFobManager(mgr,this);
		mFontSize.setFobManager(mgr,this);
		//}}FAGOT_ATTR
	}

	//## CLONE ########################################################
	/**
	 * 複製インスタンスの作成
	 * 各実現クラスにおいてインスタンスを生成する
	 * 仮想クラス（およびインスタンス化されないクラス）ではnullを返す
	 */
	public Object createClone() {
	return new GString();
	}

	/**
	 * アトリビュートの複製
	 * @param obj 複製先のオブジェクト
	 */
	public void copyAttribute( Object obj ) {
	super.copyAttribute( obj );
	((GString)obj).setText( getText() );
	((GString)obj).setFormat( getFormat() );
	((GString)obj).setFontName( getFontName() );
	((GString)obj).setFontSize( getFontSize() );
	}

	//##{FAGOT_ATTRIBUTE###############################################
	/**
	 * 文字列
	 */
	protected FString	mText = null;

	/**
	 * 表示形式
	 */
	protected FInteger	mFormat = null;

	/**
	 * 表示形式：左寄せ
	 */
	public final static int LEFT   = 0x0000;

	/**
	 * 表示形式：中央寄せ
	 */
	public final static int CENTER = 0x0001;

	/**
	 * 表示形式：右寄せ
	 */
	public final static int RIGHT  = 0x0002 ;

	/**
	 * 表示形式：上寄せ
	 */
	public final static int TOP    = 0x0000;

	/**
	 * 表示形式：中央寄せ
	 */
	public final static int MIDDLE = 0x0004;

	/**
	 * 表示形式：下寄せ
	 */
	public final static int BOTTOM = 0x0008;

	/**
	 * 表示形式：１行のみ
	 */
	public final static int SINGLE = 0x0010;

	/**
	 * 表示形式：クリップ領域のみ
	 */
	public final static int CLIP   = 0x0020;

	/**
	 * フォント名
	 */
	protected FString	mFontName = null;

	/**
	 * フォントサイズ
	 */
	protected FString	mFontSize = null;

	/**
	 * 描画開始X座標
	 */
	protected double	mX = 0;

	/**
	 * 描画開始Y座標
	 */
	protected double	mY = 0;

	/**
	 * ハッシュ用描画文字列
	 */
	protected LineBreakMeasurer mlbm = null;

	/**
	 * ハッシュ用描画文字列
	 */
	protected TextLayout mTl = null;

	/**
	 * 描画矩形
	 */
	protected Rectangle2D mPaintRect = null;
}
