/// 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.accessory.STLVector;
import net.cellcomputing.himawari.library.types.CqMatrix;

/**
 * Abstract base surface class, which provides interfaces to geometry.  
 * 
 * 
 * @author NTT DATA Corporation
 */
abstract public strictfp class IqSurface {
	
	/** 
	 * Transform this GPrim using the specified matrices.
	 * @param matTx Reference to the transformation matrix.
	 * @param matITTx Reference to the inverse transpose of the transformation matrix, used to transform normals.
	 * @param matRTx Reference to the rotation only transformation matrix, used to transform vectors.
	 * @param iTime Float value representing the frame time at which to perform the transformation.
	 */
//	public void	Transform( final CqMatrix matTx, final CqMatrix matITTx, final CqMatrix matRTx, int iTime = 0 );
	abstract public void	Transform( final CqMatrix matTx, final CqMatrix matITTx, final CqMatrix matRTx, int iTime );
	
	public void	Transform( final CqMatrix matTx, final CqMatrix matITTx, final CqMatrix matRTx ){
		Transform( matTx, matITTx, matRTx, 0 );
	}
	
	
	/** 
	 * Get the number of uniform parameters required for this GPrim.
	 * @return
	 */
	abstract public	int cUniform();
	
	/** 
	 * Get the number of varying parameters required for this GPrim.
	 * @return
	 */
	abstract public	int cVarying();
	
	/** 
	 * Get the number of vertex parameters required for this GPrim.
	 * @return
	 */
	abstract public	int cVertex();
	
	/** 
	 * Get the number of facearying parameters required for this GPrim.
	 * @return
	 */
	abstract public	int cFaceVarying();
	
	abstract public String		strName();
	abstract public	int	Uses();
	
	/** 
	 * Get a pointer to the attributes state associated with this GPrim.
	 * @return A pointer to a CqAttributes class.
	 */
	abstract public IqAttributes pAttributes();
	
	/** 
	 * Get a pointer to the transformation state associated with this GPrim.
	 * @return A pointer to a CqTransform class.
	 */
	abstract public IqTransform pTransform();
	
	/** 
	 * Perform any precalculation required before dicing.
	 * @param uDiceSize Size that the surface will be diced to in u.
	 * @param vDiceSize Size that the surface will be diced to in u.
	 */
	abstract public void	PreDice( int uDiceSize, int vDiceSize );
	
	/** 
	 * Fill in any primitive variables the surface can in one go.
	 * @param pGrid
	 * @return A bitvector representing the standard primitive variables initialised.
	 */
	abstract public int	DiceAll( CqMicroPolyGrid pGrid );
	
	/**
	 * Interpolate the specified value using the natural interpolation method for the surface.<br>
	 * Fills in the given shader data with the resulting data.
	 * 
	 * 
	 * @param pParameter
	 * @param uDiceSize
	 * @param vDiceSize
	 * @param pData
	 */
	abstract public void	NaturalDice( CqParameter pParameter, int uDiceSize, int vDiceSize, IqShaderData pData );
	
	/**
	 * Perform any post cleanup after dicing.
	 * 
	 * 
	 * @param pGrid
	 */
	abstract public void	PostDice(CqMicroPolyGrid pGrid);
	
	/** 
	 * Perform any precalculation required before subdividing.
	 * @param u Flag indicating if we are subdividing in u, if false we are doing v.
	 * @param aSplits Vector which can be filled with surfaces generated by the split operation.
	 * @return
	 */
	abstract public int	PreSubdivide( STLVector<CqBasicSurface> aSplits, boolean u );
	
	/** 
	 * Interpolate the specified value using the natural interpolation method for the surface.
	 * @param pParam Pointer to the primitive variable we are subdividing.
	 * @param pParam1 Pointer to the new primitive variable to store the first half.
	 * @param pParam2 Pointer to the new primitive variable to store the second half.
	 * @param u Flag indicating if we are subdividing in u, if false we are doing v.
	 */
	abstract public void	NaturalSubdivide( CqParameter pParam, CqParameter pParam1, CqParameter pParam2, boolean u );
	
	/**
	 * Perform any post cleanup after dicing.
	 * 
	 * 
	 * @param aSplits
	 */
	abstract public void	PostSubdivide( STLVector<CqBasicSurface> aSplits );
	
	/** 
	 * The main processing loop is finished with this surface now, so clean up any data it doesn't need anymore.
	 */
	abstract public void	RenderComplete();
	
	/** 
	 * Get the gemoetric bound of this GPrim.
	 * @return
	 */
	abstract public	CqBound	Bound();
}
