/**
 * Copyright (C) 2006-2007  NTT DATA CORPORATION
 * 
 * Version: 1.0.0 2007/04/01
 *  
 */
package net.cellcomputing.himawari.display;

import static net.cellcomputing.himawari.library.RiGlobal.QGetRenderContext;

import java.awt.image.BufferedImage;

import net.cellcomputing.himawari.library.IqBucket;
import net.cellcomputing.himawari.library.RiGlobal;

/**
 * @author NTT DATA Corporation
 * 光源からの距離情報を管理するクラス
 */
public strictfp class ZFileImage extends ImageData<float[][]> {
	
	/**
	 * コンストラクタ
	 * 2006/11/10 offset用変更
	 */
	protected ZFileImage(int offset){
		super(offset);			// 2006/11/10 offset用変更
	}
	/**
	 * Zframebuffer用のイメージデータ
	 */
	private BufferedImage zImage;
	
	/**
	 * zframebuffer用のpixelデータサイズ
	 */
	public final int DATA_SIZE = 3;
	/**
	 * 最大の深度
	 */
	private float max_depth = RiGlobal.RI_FLOATMIN;
	
	/**
	 * 最小の深度
	 */
	private float min_depth = RiGlobal.RI_FLOATMAX;
	
	private final float[] whiteData = {255,255,255};
	private final float[] blackData = {0,0,0};
	
	/**
	 * RGBのどの色で影を表現するかを判断する
	 * 
	 */
	public final int Z_COLOR = 2;
	
	/**
	 * Bucketからpixel毎のColor情報を取得し、
	 * imageDataに格納する。
	 */
	public void setBucket(IqBucket pBucket) {
		if( (pBucket.Width() == 0) || (pBucket.Height() == 0) )
			return;
		int	xmin = pBucket.XOrigin();
		int	ymin = pBucket.YOrigin();
		int	xmaxplus1 = xmin + pBucket.Width();
		int	ymaxplus1 = ymin + pBucket.Height();
		
		// If completely outside the crop rectangle, don't bother sending.
		//共通のエラー処理
		if( xmaxplus1 <= QGetRenderContext().pImage().CropWindowXMin() ||
			ymaxplus1 <= QGetRenderContext().pImage().CropWindowYMin() ||
			xmin > QGetRenderContext().pImage().CropWindowXMax() ||
			ymin > QGetRenderContext().pImage().CropWindowYMax() )
			return;
		//--ここまで
		
		float depth;
		
		for ( int y = ymin; y < ymaxplus1; y++ )
		{
			for ( int x = xmin; x < xmaxplus1; x++ )
			{
				//描画範囲かどうかのチェックを行う
				//共通のエラー処理
				if(x < QGetRenderContext().pImage().CropWindowXMin() || y < QGetRenderContext().pImage().CropWindowYMin() ||
					x >= QGetRenderContext().pImage().CropWindowXMax() || y >= QGetRenderContext().pImage().CropWindowYMax())
					continue;
				//--ここまで
				depth = pBucket.Depth(x,y);
				imageData[y][x] = depth;

				//--ZFrameBuffer用処理
				if(depth != RiGlobal.RI_FLOATMAX){
					if(depth > max_depth){
						max_depth = depth;
					}else if(min_depth > depth){
						min_depth =depth;
					}
					
					raster.setPixel(x - QGetRenderContext().pImage().CropWindowXMin() , y - QGetRenderContext().pImage().CropWindowYMin(), whiteData);
					
				}else{
					raster.setPixel(x - QGetRenderContext().pImage().CropWindowXMin() , y - QGetRenderContext().pImage().CropWindowYMin(), blackData);
				}
			
			}
		}
	}

	/**
	 * 最小深度を返す関数
	 * @return 最小深度
	 */
	public float getMinDepth(){
		return min_depth;
	}
	
	/**
	 * 最大深度を返す関数
	 * @return 最大深度
	 */
	public float getMaxDepth(){
		return max_depth;
	}

	/**
	 * 深度情報を返す
	 * @return 深度情報が格納されている配列
	 */
	public float[][] getImage() {
		return imageData;
	}
	
	/**
	 * ZImageオブジェクトを返す
	 * @return
	 */
	public BufferedImage getZImage(){
		return zImage;
	}
	
	/** 
	 * フィールドの初期化を行う。
	 * setBucketを行う前に必ず呼ばれる必要がある。
	 */
	public void init() {
		super.init();
		imageData = new float[height][width];

		zImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);				//imageを作成する
		raster = zImage.getRaster();
		this.dataSize = DATA_SIZE;			//pixelのデータサイズを取得
		pixelData = new float[DATA_SIZE];	
	}
	

}
