// 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 net.cellcomputing.himawari.library.types.CqRefCount;
import net.cellcomputing.himawari.library.types.CqVector3D;

/**
 * Base class from which all MicroPolyGrids are derived.
 * MicroPolyGrids から派生されたクラス。
 * 
 * @author NTT DATA Corporation
 */
public abstract strictfp class CqMicroPolyGridBase extends CqRefCount {
	
	/**
	 * コンストラクタ。
	 */
	public CqMicroPolyGridBase()
	{
		m_fCulled = false ;
		m_fTriangular = false;
	}
	
	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.library.types.CqRefCount#destruct()
	 */
	public void	destruct()
	{}
	
	/** 
	 * Pure virtual function, splits the grid into micropolys.
	 * 純粋仮想関数。グリッドをマイクロポリゴンに分割。
	 * @param pImage レンダリングしているイメージバッファへの参照。
	 * @param xmin	クリッピング(切り取り)を考慮に入れた場合の、最小のx画素。
	 * @param xmax	クリッピング(切り取り)を考慮に入れた場合の、最大のx画素。
	 * @param ymin	クリッピング(切り取り)を考慮に入れた場合の、最小のy画素。
	 * @param ymax	クリッピング(切り取り)を考慮に入れた場合の、最大のy画素。
	 */
	abstract public	void	Split( CqImageBuffer pImage, long xmin, long xmax, long ymin, long ymax );
	
	/**
	 * 純粋仮想関数。
	 * グリッドをシェーディングする。
	 */
	abstract public	void Shade();
	
	abstract public	void	TransferOutputVariables();
	
	/**
	 * Delete all the variables per grid <br>
	 * 各グリッドの持つ変数を全て消去する。
	 * 
	 * @param all	
	 */
	abstract public void DeleteVariables( boolean all );
	
	
	/**
	 * Pure virtual, get a pointer to the surface this grid belongs.<br>
	 * 純粋仮想関数。
	 * 現在のグリッドが属する、サーフェスの参照を取得。
	 * @return　グリッドをシャーディングする間の、サーフェスへの参照。<br>Pointer to surface, only valid during grid shading.
	 */
	abstract public CqSurface pSurface();
	
	
	/**
	 * 現在のグリッドが属する、アトリビュートの参照を取得。
	 * @return	アトリビュートの参照。
	 */
	abstract public	IqAttributes pAttributes();
	
	
	/**
	 * 現在のグリッドが持つ、CSGノードの参照を取得。
	 * @return　CSGノードの参照。
	 */
	abstract public	CqCSGTreeNode pCSGNode();
	
	
	/**
	 * m_fCulledのゲッタ。
	 * 
	 * @return	m_fCulled	全体グリッドが呼ばれたかどうかを示す。
	 */
	public boolean vfCulled()
	{
		return m_fCulled;
	}
	
	
	/**
	 * Query whether this grid is being rendered as a triangle.
	 * 現在のグリッドが三角形としてレンダリングされているかどうかを問う。
	 * 
	 * @return	m_fTriangular　三角形としてレンダリングされているか。
	 */
	public boolean fTriangular()
	{
		return ( m_fTriangular );
	}


	/**
	 * Set this grid as being rendered as a triangle or not.
	 * 現在のグリッドを三角形としてレンダリングするかしないかをセットする。
	 * 
	 * @param fTriangular	三角形としてレンダリングするかどうか。
	 */
	public void SetfTriangular( boolean fTriangular )
	{
		m_fTriangular = fTriangular;
	}
	
	
	abstract public	int	uGridRes();
	abstract public	int	vGridRes();
	abstract public	int	GridSize();
	abstract public IqShaderData pVar(int index);
	
	
	/**
	 * Get the points of the triangle split line if this grid represents a triangle.
	 * 現在のグリッドが三角形を表しているなら、三角形を分割する点を取得。
	 * 
	 * @param v1	三角形を分割する点1
	 * @param v2	三角形を分割する点2
	 * @param Time	
	 */
	public void	TriangleSplitPoints(CqVector3D v1, CqVector3D v2, float Time )
	{
		// Workout where in the keyframe sequence the requested point is.
		SqTriangleSplitLine sl = m_TriangleSplitLine.GetMotionObjectInterpolated( Time );
		v1.assignment( sl.m_TriangleSplitPoint1 );
		v2.assignment( sl.m_TriangleSplitPoint2 );
	}
	
	
	public class SqTriangleSplitLine
	{	
		CqVector3D	m_TriangleSplitPoint1;
		CqVector3D  m_TriangleSplitPoint2;
		
		/**
		 * デフォルトコンストラクタ
		 */
		public SqTriangleSplitLine() {
			m_TriangleSplitPoint1 = new CqVector3D();
			m_TriangleSplitPoint2 = new CqVector3D();
		}
		
		/**
		 * コピーコンストラクタ
		 */
		public SqTriangleSplitLine( SqTriangleSplitLine From ) {
			m_TriangleSplitPoint1 = new CqVector3D( From.m_TriangleSplitPoint1 );
			m_TriangleSplitPoint2 = new CqVector3D( From.m_TriangleSplitPoint2 );
		}
	};
	
	
	/**
	 * CqMicroPolygonGridBaseが持つ内部クラス。 <br>
	 * CqMotionSpecを継承。
	 * 
	 * @author NTT DATA Corporation
	 */
	public class CqTriangleSplitLine extends CqMotionSpec<SqTriangleSplitLine>
	{
		
		/**
		 * コンストラクタ。
		 */
		public CqTriangleSplitLine()
		{
			super( new SqTriangleSplitLine() );
		}
		
		
		/**
		 *　コピーコンストラクタ。
		 * @param def
		 */
		public CqTriangleSplitLine( final SqTriangleSplitLine def )
		{
			super( new SqTriangleSplitLine(def) );
		}
		
		
		public	void	ClearMotionObject( SqTriangleSplitLine A )
		{}
		
		public	SqTriangleSplitLine	ConcatMotionObjects( final SqTriangleSplitLine A, final SqTriangleSplitLine B )
		{
			return( A );
		}
		
		public	SqTriangleSplitLine	LinearInterpolateMotionObjects( float Fraction, final SqTriangleSplitLine A, final SqTriangleSplitLine B )
		{
			SqTriangleSplitLine sl = new SqTriangleSplitLine();
			sl.m_TriangleSplitPoint1.assignment( ( A.m_TriangleSplitPoint1.mul(1.0f - Fraction ).add( B.m_TriangleSplitPoint1.mul(Fraction) ) ) );
			sl.m_TriangleSplitPoint2.assignment( ( A.m_TriangleSplitPoint2.mul(1.0f - Fraction ).add( B.m_TriangleSplitPoint2.mul(Fraction) ) ) );
			return( sl );
		}
	};
	
	abstract public	IqShaderData FindStandardVar( final String pname );
	
	
	public boolean m_fCulled; 				///< Boolean indicating the entire grid is culled.
	public CqTriangleSplitLine	m_TriangleSplitLine = new CqTriangleSplitLine();	///< Two endpoints of the line that is used to turn the quad into a triangle at sample time.
	public boolean	m_fTriangular;			///< Flag indicating that this grid should be rendered as a triangular grid with a phantom fourth corner.
	
}
