// Aqsis
// Copyright (c) 1997 - 2001, Paul C. Gregory
//
// Contact: pgregory@aqsis.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

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

import static  net.cellcomputing.himawari.library.EqIntIndex.*;

import java.util.Iterator;

import net.cellcomputing.himawari.accessory.STLVector;
import net.cellcomputing.himawari.accessory.primitive.p_String;
import net.cellcomputing.himawari.accessory.primitive.p_float;
import net.cellcomputing.himawari.library.CqStats;
import net.cellcomputing.himawari.library.EqIntIndex;
import net.cellcomputing.himawari.library.EqVariableClass;
import net.cellcomputing.himawari.library.EqVariableType;
import net.cellcomputing.himawari.library.IqShaderData;
import net.cellcomputing.himawari.library.types.CqColor;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqVector3D;

/**
 * Array of variable pointers.
 * ShaderDataを複数保持できるクラス。
 * 様々なタイプのShaderDataを管理することが出来る。
 * ただし、格納されるShaderDataは同じ型のものが望ましい。
 * 異なる型のShaderDataを格納する場合は予期せぬ動作をする可能性がある。
 * @author NTT DATA Corporation
 */
public strictfp class CqShaderVariableArray extends CqShaderVariable {
	
	private STLVector<IqShaderData>	m_aVariables = new STLVector<IqShaderData>(IqShaderData.class);		///< Array of pointers to variables.
	
	
	/** Default constructor.
	 * 
	 * @param name ShaderDataの名前 Character pointer to the name to use.
	 * @param Count 自分の持つ配列の長さ Count the size of the array.
	 * @param fParmeter シェーダのパラメータであることを示すフラグ fParameter Boolean value, true indicates the shader variable is a shader parameter.
	 */
	CqShaderVariableArray( final String name, int Count, boolean fParameter)
	{
		super(name,fParameter);
		assert( Count > 0 );
		m_aVariables.resize( Count );
		CqStats.STATS_INC( SHD_var_array );
		CqStats.STATS_INC( SHD_var_array_current );
		int cvArr = CqStats.STATS_GETI( SHD_var_array_current );
		int cPeak = CqStats.STATS_GETI( SHD_var_array_peak );
		CqStats.STATS_SETI( SHD_var_array_peak, cvArr > cPeak ? cvArr : cPeak );
	}
	
	/** 
	 * コンストラクタ
	 * @param name ShaderDataの名前 Character pointer to the name to use.
	 * @param Count 自分の持つ配列の長さ the size of the array.
	 * @param fParameter シェーダのパラメータであることを示すフラグ Boolean value, true indicates the shader variable is a shader parameter.
	 */
	CqShaderVariableArray( final String name, int Count)
	{
		this(name,Count,false);
	}
	
	
	/** Copy constructor.
	 * コピーコンストラクタ
	 * @param From コピー元
	 */
	public CqShaderVariableArray( final CqShaderVariableArray From )
	{
		super(From.m_strName);
		//fParameterについてはコピーしない
		m_aVariables.resize( From.m_aVariables.size() );
		for ( int i = 0; i < From.m_aVariables.size(); i++ )
			m_aVariables.setElementAt(From.m_aVariables.elementAt(i).Clone(),i);
		//m_aVariables.elementAt(i) = From.m_aVariables.elementAt(i).Clone();
		CqStats.STATS_INC( SHD_var_array );
		CqStats.STATS_INC( SHD_var_array_current );
		int cvArr = CqStats.STATS_GETI( SHD_var_array_current );
		int cPeak = CqStats.STATS_GETI( SHD_var_array_peak );
		CqStats.STATS_SETI( SHD_var_array_peak, cvArr > cPeak ? cvArr : cPeak );
	}
	
	/**
	 * デストラクタ
	 * 統計情報を更新する。
	 */
	public void destruct()
	{
		CqStats.STATS_DEC( EqIntIndex.SHD_var_array_current );
		super.destruct();
	}
	
	/**
	 * 自分が持つVector内の全ての要素に対し
	 * Initialize(uGridRes,vGridRes)を呼び出し、初期化を行う。
	 * @param uGridRes
	 * @param vGridRes
	 */
	public void	Initialise( final int uGridRes, final int vGridRes )
	{
		for ( Iterator<IqShaderData> i = m_aVariables.iterator(); i.hasNext();)
			i.next().Initialise( uGridRes, vGridRes );
		CqStats.STATS_INC( SHD_var_array_init );
	}
	
	/**
	 * 自分が持つ全てのShaderDataのSetSize()メソッドを呼び出し
	 * サイズを変更する。
	 * @param size サイズ
	 */
	public void	SetSize( final int size )
	{
		for ( Iterator<IqShaderData> i = m_aVariables.iterator(); i.hasNext();)
			( i ).next().SetSize( size );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetFloat(p_float res ,int index)
	{
		assert( false ); 
//		m_aVariables.elementAt(0).GetFloat( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetString( p_String res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetString( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetPoint( CqVector3D res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetPoint( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetVector( CqVector3D res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetVector( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetNormal( CqVector3D res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetNormal( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetColor( CqColor res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetColor( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetMatrix( CqMatrix res,int index)
	{
		assert( false); //m_aVariables.elementAt(0).GetMatrix( res, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetFloatPtr( final STLVector<p_float> res)
	{
		assert( false ); 
//		m_aVariables.elementAt(0).GetFloatPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetStringPtr( final STLVector<p_String> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetStringPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetPointPtr( final STLVector<CqVector3D> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetPointPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetVectorPtr( final STLVector<CqVector3D> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetVectorPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetNormalPtr( final STLVector<CqVector3D> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetNormalPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetColorPtr( final STLVector<CqColor> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetColorPtr( res );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	GetMatrixPtr( final STLVector<CqMatrix> res )
	{
		assert( false); //m_aVariables.elementAt(0).GetMatrixPtr( res );
	}
	
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetFloat( final float f )
	{
		assert( false ); m_aVariables.elementAt(0).SetFloat( f );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetString( final String s )
	{
		assert( false ); m_aVariables.elementAt(0).SetString( s );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetPoint( final CqVector3D p )
	{
		assert( false ); m_aVariables.elementAt(0).SetPoint( p );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetVector( final CqVector3D v )
	{
		assert( false ); m_aVariables.elementAt(0).SetVector( v );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetNormal( final CqVector3D n )
	{
		assert( false ); m_aVariables.elementAt(0).SetNormal( n );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetColor( final CqColor c )
	{
		assert( false ); m_aVariables.elementAt(0).SetColor( c );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetMatrix( final CqMatrix m )
	{
		assert( false ); m_aVariables.elementAt(0).SetMatrix( m );
	}
	
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetFloat( final float f, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetFloat( f, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetString( final String s, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetString( s, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetPoint( final CqVector3D p, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetPoint( p, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetVector( final CqVector3D v, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetVector( v, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetNormal( final CqVector3D n, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetNormal( n, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetColor( final CqColor c, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetColor( c, index );
	}
	
	/**
	 * 常に失敗するメソッド
	 */
	public void	SetMatrix( final CqMatrix m, int index )
	{
		assert( false ); m_aVariables.elementAt(0).SetMatrix( m, index );
	}
	
	/** 
	 * Copy the values from the passed variable into this, taking into account any class differences.<br>
	 * 引数で渡された変数の値を、自分自身が持つVectorの先頭にある
	 * ShaderDataにコピーする。
	 * 
	 * @param pVal コピー元のShaderData The variable to copy from.
	 */
	public void	SetValueFromVariable( final IqShaderData pVal )
	{
		m_aVariables.elementAt( 0 ).SetValueFromVariable( pVal );
	}
	/** Set the all SIMD data ased on a state vector, only indexes whose bit is set are modified.<br>
	 * 引数で渡された変数の指定された値を、自分自身が持つVectorの先頭にある
	 * ShaderDataの指定された場所にコピーする。
	 * 
	 * @param pVal コピー元のShaderData The stack entry to assign.
	 * @param index index値 Integer SIMD index.
	 */
	public void	SetValueFromVariable( final IqShaderData pVal, int index )
	{
		m_aVariables.elementAt( 0 ).SetValueFromVariable( pVal, index );
	}
	
	/**
	 * 自分と同じ値を持つインスタンスを生成する
	 */
	public IqShaderData Clone()
	{
		return ( new CqShaderVariableArray( this ) );
	}
	
	/**
	 * 自分が持つVectorの先頭にあるShaderDataの
	 * EqVariableClassを返す
	 * 
	 * @return 自分が持つVectorの先頭にあるShaderDataのEqVariableClassを返す
	 */
	public EqVariableClass	Class()
	{
		return ( m_aVariables.elementAt(0).Class()  );
	}
	
	/**
	 * 自分が持つVectorの先頭にあるShaderDataの
	 * EqVariableTypeを返す
	 * 
	 * @return 自分が持つVectorの先頭にあるShaderDataのEqVariableTypeを返す
	 */
	public EqVariableType	Type()
	{
		return ( ( m_aVariables.elementAt(0).Type() ) );
	}
	
	/**
	 * 自分が持つVectorの先頭アドレスに格納されている
	 * ShaderDataの持つ要素数を返す。
	 * すなわちm_aVariables[0].Size()で返る値を返す。
	 * 
	 * @return Vectorの先頭アドレスに入っているShaderDataが持つ要素数
	 */
	public long	Size()
	{
		return ( m_aVariables.elementAt(0).Size() );
	}
	
	/**
	 * 自分が持つVectorの長さを返すメソッド
	 * 
	 * @return 自分が持つVector長
	 */
	public int	ArrayLength()
	{
		return ( m_aVariables.size() );
	}
	
	/**
	 * 自分が持つVectorのi番地目の値を返す
	 * 
	 * @int i index値 
	 */
	public  IqShaderData	ArrayEntry( int i )
	{
		assert( i < this.ArrayLength() );
		return ( ( this ).valueAt(i) );
	}
	
	/** Get a reference to the variable array.
	 * 自分が持つVector m_aVariablesのGetter
	 */
	public STLVector<IqShaderData> aVariables()
	{
		return ( m_aVariables );
	}
	
	/** 
	 * Array index access to the values in the array.
	 * 自分が持つVectorのi番地目の値を返す
	 * ＠@param index index値 Integer index intot he array.
	 */
	public IqShaderData valueAt ( long index )
	{
		return( m_aVariables.elementAt((int)index) );
	}
	
	
}
