// 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.library;
import static net.cellcomputing.himawari.library.EqIntIndex.*;
/**
 * 
 * パラメタ名と値を保持する仮想クラス<br>
 * 生成/消滅の度にCqStats.intVars[PRM_created]の値を更新する。
 * <br>
 * prototypeパターン(デザインパターン参照)
 * http://www002.upp.so-net.ne.jp/ys_oota/mdp/Prototype/
 * 
 * Subdivide(分割)、Diceなどのメソッドを持つ。
 * 
 * @author NTT DATA Corporation
 */
public abstract strictfp class CqParameter {
	
	    protected String	m_strName;		///< パラメータの名前
	    protected int	m_Count;		///< 配列の長さ
	    protected long m_hash;			//ハッシュ値？
	    
	   
	    
	    /**
	     * コンストラクタ
	     * 統計情報を保持するCqStatsのm_intVars[PRM_created]
	     * ,m_intVars[PRM_current]をインクリメントし、
	     * m_intVars[PRM_peak]の値をセットする。
	     * 
	     * @param strName 	パラメータ名
	     * @param Count 	配列数
	     * @param myClass Genericsで指定される第1引数のS
	     */
	    public CqParameter(final String strName, int Count){
	    	m_strName = strName;
	    	m_Count = Count;
	    	assert( Count >= 1 );
	        
	        CqStats.STATS_INC( PRM_created );
	        CqStats.STATS_INC( PRM_current );
	        int cPRM = CqStats.STATS_GETI( PRM_current );
	        int cPeak = CqStats.STATS_GETI( PRM_peak );

	        CqStats.STATS_SETI( PRM_peak, cPRM > cPeak ? cPRM : cPeak );
	        m_hash = strName.hashCode();
	        
	    }
	    
	    /**
	     * コンストラクタ
	     * 引数を１つ省略したコンストラクタ
	     * 
	     * @param strName パラメタ名
	     * @param myClass Genericsで指定される第1引数のＳ
	     */
	    public CqParameter(final String strName){
	    	this(strName,1);
	    }
	    
	    /**
	     * コピーコンストラクタ
	     * 統計情報を保持するCqStatsのm_intVars[PRM_created]
	     * ,m_intVars[PRM_current]をインクリメントし、
	     * m_intVars[PRM_peak]の値をセットする。
	     * 
	     * @param From コピー元オブジェクト
	     */
	    public  CqParameter(final CqParameter From ){
	    	m_strName 	= From.m_strName;
	    	m_Count		= From.m_Count;
	    	m_hash		= From.m_hash;
	        /// \note Had to remove this as paramters are now created as part of the Renderer construction, so the
	        ///		  renderer context isn't ready yet.
	        //	QGetRenderContext() ->Stats().IncParametersAllocated();
	        CqStats.STATS_INC( PRM_created );
	        CqStats.STATS_INC( PRM_current );
	        int cPRM = CqStats.STATS_GETI( PRM_current );
	        int cPeak = CqStats.STATS_GETI( PRM_peak );

	        CqStats.STATS_SETI( PRM_peak, cPRM > cPeak ? cPRM : cPeak );
	    }
	    /**
	     * デストラクタ
	     * CqStats.m_intVars[PRM_current]をデクリメントする。
	     * 
	     */
	    public	void destruct(){
	        /// \note Had to remove this as paramters are now created as part of the Renderer construction, so the
	        ///		  renderer context isn't ready yet.
	        //	QGetRenderContext() ->Stats().IncParametersAllocated();
	    	CqStats.STATS_DEC( PRM_current );
	    }

	    /** 
	     * 自分自身と同じTypeで、データを持たないParameterを返す
	     * @return 自分と同じTypeをもつCqParameter
	     */
	    public abstract CqParameter CloneType(final String Name, int Count);
	    
	    //新規作成 2005/08/02
	    /**
	     * CloneType(Name,1)をコールする。
	     * @param Name
	     */
	    public CqParameter CloneType(final String Name){
	    	return CloneType(Name,1);
	    }
	    /**
	     * 同じ名前と、値を持つ新しいParameterを返す関数
	     * @return 同じ値を持つCqParameter
	     */
	    public abstract CqParameter Clone();
	    /** 
	     * EqVariableClassを返す関数
	     * @return EqVariableClass
	     */
	    public abstract EqVariableClass	Class();
	    /** 
	     * EqVariableTypeを返す関数
	     */
	    public abstract EqVariableType	Type();
	    /** 
	     * 配列でない可変/頂点のサイズをセットする。
	     * 
	     */
	    public abstract void SetSize( int size );
	    /** 
	     * 配列でない可変/頂点のサイズを返す。
	     * @return 可変/頂点のサイズ
	     */
	    public abstract int Size();
	    /** 
	     * 値をクリアする。
	     */
	    public abstract void Clear();

	    /* attention
	     * The subdivide functions perform common splitting and interpolation on primitive variables
	     * they are only of use if the variable is a bilinear quad (the most common kind)
	     * any other type of splitting or interpolation must be performed by the surface which 
	     * instantiates special types (i.e. polygons).
	     * <br><br>
	     * Subdivide機能は共通の分割、プリミティブの補完を行う。
	     * プリミティブは双対の四辺形(最も共通な種類の)のもののみを扱う。
	     * 他のタイプの分割や補完には必ず特別なタイプにインスタンス化されたSurfaceによって
	     * 行わなければならない。(即ちPolygons)
	     */
	    
	    /** 
	     * u の方向の値を、半分に分割する。他の値を指定の変数で分割する。
	     * Subdivide the value in the u direction, place one half in this and the other in the specified parameter.
	     * @param pResult1 前半の分割を持つParameterクラスへのポインタ
	     * @param pResult2 前半の分割を持つParameterクラスへのポインタ
	     * @param u u方向で分割するのかv方向で分割するのかどうかを指し示すフラグ。falseならvで分割
	     * @param pSurface パラメタがどの所属かを示すSurface。 特別なパラメタ分割を持つ場合、使われる。
	     */
	    public abstract void	Subdivide( CqParameter pResult1, CqParameter pResult2, boolean u, IqSurface pSurface);
	    //新規作成 2005/08/02
	    public final void Subdivide(CqParameter pResult1,CqParameter pResult2,boolean u){
	    	Subdivide(pResult1,pResult2,u,null);
	    }
	    /** 
	     * 値をそのクラスの適切な補完を用いてグリッドに切り出す(Dice)
	     * 
	     * @param u U方向のダイスの数(dice count)。
	     * @param v V方向のダイスの数(dice count)。
	     * @param pResult 結果を保存するポインタ
	     * @param pSurface 現在処理しているSurface　vertexの変数を自然補完するために使われる。
	     */
	    public abstract	void	Dice( int u, int v, IqShaderData pResult, IqSurface pSurface);
	    
	    //新規作成 2005/08/02
	    /**
	     * Dice(u,v,pResult,null)をコールする。
	     */
	    public final void Dice( int u, int v, IqShaderData pResult){
	    	Dice(u,v,pResult,null);
	    }
	    /** Pure virtual, 
	     * 配列の単一の要素値をそのクラスの適切な補完を用いてグリッドに切り出す(Dice)
	     * 
	     * @param u Integer dice count for the u direction.
	     * @param v Integer dice count for the v direction.
	     * @param pResult Pointer to storage for the result.
	     * @param pSurface Pointer to the surface we are processing used for vertex class variables to perform natural interpolation.
	     */
	    public abstract	void	DiceOne(int u, int v, IqShaderData pResult, IqSurface pSurface, int ArrayIndex);
	    //新規作成 2005/08/02
	    /**
	     * DiceOneメソッドのオーバーロード<br>
	     * DiceOne(u,v,pResult,null,0)をコールする。
	     * 
	     */
	    public final void DiceOne( int u, int v, IqShaderData pResult){
	    	DiceOne(u,v,pResult,null,0);
	    }
	    //新規作成 2005/08/12
	    /**
	     * DiceOneメソッドのオーバーロード<br>
	     * DiceOne(u,v,pResult,pSurface,0)をコールする。
	     * 
	     */
	    public final void DiceOne( int u, int v, IqShaderData pResult,IqSurface pSurface){
	    	DiceOne(u,v,pResult,pSurface,0);
	    }

	    /** Pure virtual, set an indexed value from another parameter (must be the same type).
	     * 他のパラメタ値からindexをセットする。
	     * 必ず同じtypeでなければならない。
	     * 
	     * @param pFrom ポインタ
	     * @param idxTarget セットする値のindex値
	     * @param idxSource セットする値
	     */
	    public abstract void	SetValue( CqParameter pFrom, int idxTarget, int idxSource );

	    /** Get a reference to the parameter name.
	     * パラメタ名のgetter
	     */
	    public final String strName()
	    {
	        return ( m_strName );
	    }
	    /**
	     * ハッシュ値を返すgetter
	     * @return ハッシュ値
	     */
	    public final long hash()
	    {
	        return m_hash;
	    }

	    /** Get the array size.
	     * arraysizeを返す。getter。
	     */
	    public int Count()
	    {
	        return ( m_Count );
	    }



}
