/**
 * 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 static net.cellcomputing.himawari.library.RiGlobal.QGetRenderContextI;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.util.HimawariLogger;
/**
 * @author NTT DATA Corporation
 *
 */
public strictfp class ZFileRequest extends DisplayRequest {
	/**
	 * SHADOWのHEADER情報のスタート
	 */
	public static final String START_SHADOW_HEADER = "START_SHADOW_HEADER";

	/**
	 * SHADERのヘッダ情報のエンド
	 */
	public static final String END_SHADOW_HEADER = "END_SHADOW_HEADER";
	
	/**
	 * 画面サイズ
	 */
	public static final String SHADOW_WIDTH ="SHADOW_WIDTH";
	
	/**
	 * 画面の高さ
	 */
	public static final String SHADOW_HEIGHT = "SHADOW_HEIGHT";
	
	/**
	 * カメラの位置情報
	 */
	public static final String SHADOW_CAMERA_POINT = "SHADOW_CAMERA_POINT";
	
	/**
	 * スクリーンの位置情報
	 */
	public static final String SHADOW_SCREEN_POINT = "SHADOW_SCREEN_POINT";
	/**
	 * 扱う画像データの幅
	 */
	private int imageWidth;
	/**
	 * 扱う画像データの高さ
	 */
	private int imageHeight;
	
	/**
	 * Screenの位置
	 */
	CqMatrix matWorldToScreen;
	
	/**
	 * Cameraの位置
	 */
	CqMatrix matWorldToCamera;
	
	
	/**
	 * コンストラクタ
	 * Request
	 * @param name pngファイルの名前
	 * @param type 保存形式
	 * @param mode RGB,RGBAなどのカラー情報がはいる
	 * @param modeID modeのhash
	 * @param dataOffset 
	 * @param dataSize
	 * @param imageData このRequestが管理するImageData (BufferedImage)
	 */
	public ZFileRequest(String name, final String type,final String mode,
			int modeID, int dataOffset, int dataSize ,ImageData imageData){
		super(name,type,mode,modeID,dataOffset,dataSize,imageData);
	}
	
	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.display.DisplayRequest#openRequest()
	 */
	@Override
	public void openRequest() {
		imageWidth = QGetRenderContext() .optCurrent().GetIntegerOptionIndex( "System", "Resolution" , 0 ).value;		//imageの幅を取得
		imageHeight = QGetRenderContext() .optCurrent().GetIntegerOptionIndex( "System", "Resolution" , 1 ).value;	//imageの高さを取得
		//カメラなどの位置を取得しておく
		matWorldToCamera = QGetRenderContext().matSpaceToSpace( "world", "camera", new CqMatrix(), new CqMatrix(), QGetRenderContextI().Time() );
		matWorldToScreen = QGetRenderContext().matSpaceToSpace( "world", "screen", new CqMatrix(), new CqMatrix(), QGetRenderContextI().Time() );

	}

	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.display.DisplayRequest#display()
	 */
	@Override
	public void display() {

	}

	private void writeHeader(RandomAccessFile file)throws IOException{
		String ret = "\n";
		//ヘッダの書き出し
		file.write(START_SHADOW_HEADER.getBytes());
		
		file.write(ret.getBytes());
		
		//画像の幅を書き出す
		file.write(SHADOW_WIDTH.getBytes());
		file.write((" "  + imageWidth).getBytes());
		file.write(ret.getBytes());

		//画像の高さを書き出す
		file.write(SHADOW_HEIGHT.getBytes());
		file.write((" "  + imageWidth).getBytes());
		file.write(ret.getBytes());
		
		//カメラの位置情報を書き出す
		file.write(SHADOW_CAMERA_POINT.getBytes());
		file.write(ret.getBytes());
		writeMatrix(file,matWorldToCamera);
		file.write(ret.getBytes());
		
		//スクリーンの位置情報を書き出す
		file.write(SHADOW_SCREEN_POINT.getBytes());
		file.write(ret.getBytes());
		writeMatrix(file,matWorldToScreen);
		file.write(ret.getBytes());
		
		file.write(END_SHADOW_HEADER.getBytes());
		file.write(ret.getBytes());
	}
	
	private void writeMatrix (RandomAccessFile file,CqMatrix matrix)throws IOException{
		for(int i=0; i < 4;i++)
			for(int j=0;j<4 ;j++)
				file.writeFloat(matrix.m_aaElement[i][j]);
	}
	
	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.display.DisplayRequest#closeRequest()
	 */
	@Override
	public void closeRequest() {
		RandomAccessFile file = null;
		float[][] bucketList = (float[][])imageData.getImage();
		
		try {
			file = new RandomAccessFile(name,"rw");
			//ヘッダー情報を書く
			file.seek(0);
			file.setLength(0);
			writeHeader(file);
			//ここまで
			for(int y = 0; y < bucketList.length ; y++){
				for(int x = 0; x < bucketList[0].length;x++){
					//色情報が入っているかチェックする
//					if(bucketList[y][x])
//						continue;
					
					//深度をファイルに書き出す
					file.writeFloat(bucketList[y][x]);
				}
			}

		} catch (FileNotFoundException e) {
			HimawariLogger.outputException(e);
			HimawariLogger.getLogger().error( "Cannot open output image file: " + name + "\n");
			
		} catch (IOException e) {
			HimawariLogger.outputException(e);
			HimawariLogger.getLogger().error( "Cannot open output image file: " + name + "\n");
			
		}finally{
			//全てのBucketを書き終えたのでファイルを閉じる。
			try {
				if(file != null)
					file.close();
			} catch (IOException e) {
				HimawariLogger.outputException(e);
			}
		}
		imageData = null;
	}

}
