// 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.RiGlobal.Attribute_Stack;
import static net.cellcomputing.himawari.library.RendermanInterface.RiBezierBasis;
import static net.cellcomputing.himawari.library.ShadingInterpolation.*;
import static net.cellcomputing.himawari.library.EqVariableType.*;

import java.util.ArrayList;
import java.util.Iterator;

import net.cellcomputing.himawari.accessory.STLArray;
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.accessory.primitive.p_int;
import net.cellcomputing.himawari.library.types.CqColor;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqRefCount;
import net.cellcomputing.himawari.library.types.CqVector3D;


/**
 * 
 * 
 * 
 * @author NTT DATA Corporation
 */
public strictfp class CqAttributes extends CqRefCount implements IqAttributes {
	
	private CqHashTable	m_aAttributes = new CqHashTable();		///< a vector of user defined attribute pointers.
	
	private IqShader m_pshadDisplacement;            ///< a pointer to the current displacement shader.
	private IqShader m_pshadAreaLightSource;         ///< a pointer to the current area ligthsource shader.
	private IqShader m_pshadSurface;                 ///< a pointer to the current surface shader.
	private IqShader m_pshadAtmosphere;              ///< a pointer to the current atmosphere shader.
	private IqShader m_pshadInteriorVolume;          ///< a pointer to the current interior shader.
	private IqShader m_pshadExteriorVolume;          ///< a pointer to the current exterior shader.
	
	private CqTrimLoopArray m_TrimLoops = new CqTrimLoopArray();	///< the array of closed trimcurve loops.
	private STLVector< CqLightsource > m_apLightsources = new STLVector< CqLightsource >(CqLightsource.class);	///< a vector of currently available lightsources.
	
//	private Iterator<CqAttributes>	m_StackIterator;	///< the index of this attribute state in the global stack, used for destroying when last reference is removed.
	
	
	//************************************************************************//
	//*** 内部クラスの定義
	//************************************************************************//
	
	private class CqHashTable
	{
		private static final int tableSize = 127;
		//private STLVector< ArrayList<CqNamedParameterList> > m_aLists = new STLVector< ArrayList<CqNamedParameterList> >( ArrayList.class, tableSize );
		private STLArray< ArrayList<CqNamedParameterList> > m_aLists = new STLArray< ArrayList<CqNamedParameterList> >( (Class<? extends ArrayList<CqNamedParameterList>>) ArrayList.class, tableSize );

		public CqHashTable()
		{
			m_aLists.setSize( tableSize );
		}
		
		public CqNamedParameterList Find( final String pname )
		{
			int hash = pname.hashCode();
			int i = _hash( hash);
			
			if ( m_aLists.get( i ).isEmpty() )
			{
				CqNamedParameterList retval = null;
				return ( retval );
				// return ( CqNamedParameterList() );
			}
			
			
//			std::list<CqNamedParameterList >::const_iterator iEntry = m_aLists[ i ].begin();
//			if ( iEntry == m_aLists[ i ].end() )
//			return ( *iEntry );
//			else
//			{
//			while ( iEntry != m_aLists[ i ].end() )
//			{
//			if ( ( *iEntry ) .hash() == hash )
//			return ( *iEntry );
//			++iEntry;
//			}
//			}
			int iEntry = 0;
			if( m_aLists.get(i).size() <= 1 ){
				return m_aLists.get(i).get( iEntry );
			}
			else{
				while( iEntry!=m_aLists.get(i).size() )
				{
					if ( m_aLists.get(i).get( iEntry ).hash() == hash )
						return ( m_aLists.get(i).get( iEntry ) );
					++iEntry;
				}
			}
			
			
			CqNamedParameterList retval = null;
			return ( retval );
			// return ( CqNamedParameterList() );
		}
		
		
		public void Add( CqNamedParameterList pOption )
		{
			int hash = pOption.strName().hashCode();
			int i = _hash( hash );
//			m_aLists.get( i ).add( new CqNamedParameterList(pOption) );
			m_aLists.get( i ).add( pOption );
		}
		
		public void Remove( CqNamedParameterList pOption )
		{
			int hash = pOption.strName().hashCode();
			int i = _hash( hash );
			
			Iterator ite = m_aLists.get( i ).iterator();
			while ( ite.hasNext() )
			{
				CqNamedParameterList iEntry = (CqNamedParameterList)ite.next();
				if ( iEntry == pOption )
				{
					m_aLists.get( i ).remove( iEntry );
					return ;
				}
//				iEntry++;
			}
		}
		
		public void assignment( final CqHashTable From )
		{
//			std::vector<std::list<CqNamedParameterList > >::const_iterator i;
//			for ( i = From.m_aLists.begin(); i != From.m_aLists.end(); i++ )
//			{
//			std::list<CqNamedParameterList >::const_iterator i2;
//			for ( i2 = ( *i ).begin(); i2 != ( *i ).end(); i2++ )
//			Add( *i2 );
//			}
//			return ( *this );
			//for( ArrayList<CqNamedParameterList> i : From.m_aLists ){
			for( int i = 0; i < From.m_aLists.size() ; i++ ){
				for( CqNamedParameterList i2 : From.m_aLists.get(i) ){
					this.Add( i2 );
				}
			}
			
		}
		
		private int _hash( int h )
		{
			if( h<0 ) h *= -1;
			return (h % tableSize);
		}
		
		
	};
	
	
	//************************************************************************//
	//*** コンストラクタの定義
	//************************************************************************//
	//buti　高速化
//	public CqAttributes(){
//		
//		Attribute_Stack.addFirst( this );
////		m_StackIterator = Attribute_Stack.iterator();
//		
//		CqNamedParameterList pdefattrs = new CqNamedParameterList( "System" );
//		
//		{
//			CqParameterTypedUniform<CqColor, CqColor> pColor = new CqParameterTypedUniform<CqColor, CqColor>("Color",new EqVariableType(type_color),CqColor.class,CqColor.class);
//			((CqColor)pColor.pValue()[0]).assignment( ( new CqVector3D( 1.0f, 1.0f, 1.0f ) ) );
//			pdefattrs.AddParameter(pColor);;
//		}
//		{
//			CqParameterTypedUniform<CqColor, CqColor> pOpacity = new CqParameterTypedUniform<CqColor, CqColor>("Opacity",new EqVariableType(type_color),CqColor.class,CqColor.class);
//			((CqColor)pOpacity.pValue()[0]).assignment( new CqVector3D( 1.0f, 1.0f, 1.0f ) );
//			pdefattrs.AddParameter(pOpacity);;
//		}
//		{
//			CqParameterTypedUniformArray<p_float, p_float> pTextureCoordinates = new CqParameterTypedUniformArray<p_float, p_float>("TextureCoordinates",8,new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pTextureCoordinates.pValue()[0]).value = ( 0.0f );
//			((p_float)pTextureCoordinates.pValue()[1]).value = ( 0.0f );
//			((p_float)pTextureCoordinates.pValue()[2]).value = ( 1.0f );
//			((p_float)pTextureCoordinates.pValue()[3]).value = ( 0.0f );
//			((p_float)pTextureCoordinates.pValue()[4]).value = ( 0.0f );
//			((p_float)pTextureCoordinates.pValue()[5]).value = ( 1.0f );
//			((p_float)pTextureCoordinates.pValue()[6]).value = ( 1.0f );
//			((p_float)pTextureCoordinates.pValue()[7]).value = ( 1.0f );
//			pdefattrs.AddParameter(pTextureCoordinates);;
//		}
//		{
//			CqParameterTypedUniform<p_float, p_float> pShadingRate = new CqParameterTypedUniform<p_float, p_float>("ShadingRate",new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pShadingRate.pValue()[0]).value = ( 1.0f );
//			pdefattrs.AddParameter(pShadingRate);;
//		}
//		{
//			CqParameterTypedUniform<p_float, p_float> pShadingRateSqrt = new CqParameterTypedUniform<p_float, p_float>("ShadingRateSqrt",new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pShadingRateSqrt.pValue()[0]).value = ( 1.0f );
//			pdefattrs.AddParameter(pShadingRateSqrt);;
//		}
//		{
//			CqParameterTypedUniform<p_int, p_float> pShadingInterpolation = new CqParameterTypedUniform<p_int, p_float>("ShadingInterpolation",new EqVariableType(type_integer), p_int.class,p_float.class);
//			((p_int)pShadingInterpolation.pValue()[0]).value = ( ShadingConstant );
//			pdefattrs.AddParameter(pShadingInterpolation);;
//		}
//		{
//			CqParameterTypedUniform<p_int, p_float> pMatte = new CqParameterTypedUniform<p_int, p_float>("Matte",new EqVariableType(type_integer), p_int.class,p_float.class);
//			((p_int)pMatte.pValue()[0]).value = ( 0 );
//			pdefattrs.AddParameter(pMatte);;
//		}
//		{
//			CqParameterTypedUniformArray<p_float, p_float> pDetailRange = new CqParameterTypedUniformArray<p_float, p_float>("DetailRange",4,new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pDetailRange.pValue()[0]).value = ( 0.0f );
//			((p_float)pDetailRange.pValue()[1]).value = ( 0.0f );
//			((p_float)pDetailRange.pValue()[2]).value = ( Float.MAX_VALUE );
//			((p_float)pDetailRange.pValue()[3]).value = ( Float.MAX_VALUE );
//			pdefattrs.AddParameter(pDetailRange);;
//		}
//		{
//			CqParameterTypedUniformArray<CqMatrix, CqMatrix> pBasis = new CqParameterTypedUniformArray<CqMatrix, CqMatrix>("Basis",2,new EqVariableType(type_matrix), CqMatrix.class,CqMatrix.class);
//			((CqMatrix)pBasis.pValue()[0]).assignment( RiBezierBasis );
//			((CqMatrix)pBasis.pValue()[1]).assignment( RiBezierBasis );
//			pdefattrs.AddParameter(pBasis);;
//		}
//		{
//			CqParameterTypedUniformArray<p_int, p_float> pBasisStep = new CqParameterTypedUniformArray<p_int, p_float>("BasisStep",2,new EqVariableType(type_integer), p_int.class,p_float.class);
//			((p_int)pBasisStep.pValue()[0]).value = ( 3 );
//			((p_int)pBasisStep.pValue()[1]).value = ( 3 );
//			pdefattrs.AddParameter(pBasisStep);;
//		}
//		{
//			CqParameterTypedUniform<p_int, p_float> pOrientation = new CqParameterTypedUniform<p_int, p_float>("Orientation",new EqVariableType(type_integer), p_int.class,p_float.class);
//			((p_int)pOrientation.pValue()[0]).value = ( 0 );
//			pdefattrs.AddParameter(pOrientation);;
//		}
//		{
//			CqParameterTypedUniform<p_int, p_float> pSides = new CqParameterTypedUniform<p_int, p_float>("Sides",new EqVariableType(type_integer), p_int.class,p_float.class);
//			((p_int)pSides.pValue()[0]).value = ( 2 );
//			pdefattrs.AddParameter(pSides);;
//		}
//		{
//			CqParameterTypedUniform<p_float, p_float> pLevelOfDetailRulerSize = new CqParameterTypedUniform<p_float, p_float>("LevelOfDetailRulerSize",new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pLevelOfDetailRulerSize.pValue()[0]).value = ( Float.MAX_VALUE );
//			pdefattrs.AddParameter(pLevelOfDetailRulerSize);;
//		}
//		{
//			CqParameterTypedUniformArray<p_float, p_float> pLevelOfDetailBounds = new CqParameterTypedUniformArray<p_float, p_float>("LevelOfDetailBounds",2,new EqVariableType(type_float), p_float.class,p_float.class);
//			((p_float)pLevelOfDetailBounds.pValue()[0]).value = ( 0.0f );
//			((p_float)pLevelOfDetailBounds.pValue()[1]).value = ( 1.0f );
//			pdefattrs.AddParameter(pLevelOfDetailBounds);;
//		}
//		
//		AddAttribute( pdefattrs );
//	}
		public CqAttributes(){
		
		Attribute_Stack.addFirst( this );
//		m_StackIterator = Attribute_Stack.iterator();
		
		CqNamedParameterList pdefattrs = new CqNamedParameterList( "System" );
		
		{
			CqParameterTypedUniform<CqColor, CqColor> pColor = new CqParameterTypedUniform<CqColor, CqColor>("Color",new EqVariableType(type_color),CqColor.class,CqColor.class);
//			((CqColor)pColor.pValue_get(0,0)).assignment( ( new CqVector3D( 1.0f, 1.0f, 1.0f ) ) );
			((CqColor)pColor.pValue_get(0,0)).assignment( 1.0f, 1.0f, 1.0f );
			pdefattrs.AddParameter(pColor);;
		}
		{
			CqParameterTypedUniform<CqColor, CqColor> pOpacity = new CqParameterTypedUniform<CqColor, CqColor>("Opacity",new EqVariableType(type_color),CqColor.class,CqColor.class);
//			((CqColor)pOpacity.pValue_get(0,0)).assignment( new CqVector3D( 1.0f, 1.0f, 1.0f ) );
			((CqColor)pOpacity.pValue_get(0,0)).assignment( 1.0f, 1.0f, 1.0f );
			pdefattrs.AddParameter(pOpacity);;
		}
		{
			CqParameterTypedUniformArray<p_float, p_float> pTextureCoordinates = new CqParameterTypedUniformArray<p_float, p_float>("TextureCoordinates",8,new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pTextureCoordinates.pValue_get(0,0)).value = ( 0.0f );
			((p_float)pTextureCoordinates.pValue_get(0,1)).value = ( 0.0f );
			((p_float)pTextureCoordinates.pValue_get(0,2)).value = ( 1.0f );
			((p_float)pTextureCoordinates.pValue_get(0,3)).value = ( 0.0f );
			((p_float)pTextureCoordinates.pValue_get(0,4)).value = ( 0.0f );
			((p_float)pTextureCoordinates.pValue_get(0,5)).value = ( 1.0f );
			((p_float)pTextureCoordinates.pValue_get(0,6)).value = ( 1.0f );
			((p_float)pTextureCoordinates.pValue_get(0,7)).value = ( 1.0f );
			pdefattrs.AddParameter(pTextureCoordinates);;
		}
		{
			CqParameterTypedUniform<p_float, p_float> pShadingRate = new CqParameterTypedUniform<p_float, p_float>("ShadingRate",new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pShadingRate.pValue_get(0,0)).value = ( 1.0f );
			pdefattrs.AddParameter(pShadingRate);;
		}
		{
			CqParameterTypedUniform<p_float, p_float> pShadingRateSqrt = new CqParameterTypedUniform<p_float, p_float>("ShadingRateSqrt",new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pShadingRateSqrt.pValue_get(0,0)).value = ( 1.0f );
			pdefattrs.AddParameter(pShadingRateSqrt);;
		}
		{
			CqParameterTypedUniform<p_int, p_float> pShadingInterpolation = new CqParameterTypedUniform<p_int, p_float>("ShadingInterpolation",new EqVariableType(type_integer), p_int.class,p_float.class);
			((p_int)pShadingInterpolation.pValue_get(0,0)).value = ( ShadingConstant );
			pdefattrs.AddParameter(pShadingInterpolation);;
		}
		{
			CqParameterTypedUniform<p_int, p_float> pMatte = new CqParameterTypedUniform<p_int, p_float>("Matte",new EqVariableType(type_integer), p_int.class,p_float.class);
			((p_int)pMatte.pValue_get(0,0)).value = ( 0 );
			pdefattrs.AddParameter(pMatte);;
		}
		{
			CqParameterTypedUniformArray<p_float, p_float> pDetailRange = new CqParameterTypedUniformArray<p_float, p_float>("DetailRange",4,new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pDetailRange.pValue_get(0,0)).value = ( 0.0f );
			((p_float)pDetailRange.pValue_get(0,1)).value = ( 0.0f );
			((p_float)pDetailRange.pValue_get(0,2)).value = ( Float.MAX_VALUE );
			((p_float)pDetailRange.pValue_get(0,3)).value = ( Float.MAX_VALUE );
			pdefattrs.AddParameter(pDetailRange);;
		}
		{
			CqParameterTypedUniformArray<CqMatrix, CqMatrix> pBasis = new CqParameterTypedUniformArray<CqMatrix, CqMatrix>("Basis",2,new EqVariableType(type_matrix), CqMatrix.class,CqMatrix.class);
			((CqMatrix)pBasis.pValue_get(0,0)).assignment( RiBezierBasis );
			((CqMatrix)pBasis.pValue_get(0,1)).assignment( RiBezierBasis );
			pdefattrs.AddParameter(pBasis);;
		}
		{
			CqParameterTypedUniformArray<p_int, p_float> pBasisStep = new CqParameterTypedUniformArray<p_int, p_float>("BasisStep",2,new EqVariableType(type_integer), p_int.class,p_float.class);
			((p_int)pBasisStep.pValue_get(0,0)).value = ( 3 );
			((p_int)pBasisStep.pValue_get(0,1)).value = ( 3 );
			pdefattrs.AddParameter(pBasisStep);;
		}
		{
			CqParameterTypedUniform<p_int, p_float> pOrientation = new CqParameterTypedUniform<p_int, p_float>("Orientation",new EqVariableType(type_integer), p_int.class,p_float.class);
			((p_int)pOrientation.pValue_get(0,0)).value = ( 0 );
			pdefattrs.AddParameter(pOrientation);;
		}
		{
			CqParameterTypedUniform<p_int, p_float> pSides = new CqParameterTypedUniform<p_int, p_float>("Sides",new EqVariableType(type_integer), p_int.class,p_float.class);
			((p_int)pSides.pValue_get(0,0)).value = ( 2 );
			pdefattrs.AddParameter(pSides);;
		}
		{
			CqParameterTypedUniform<p_float, p_float> pLevelOfDetailRulerSize = new CqParameterTypedUniform<p_float, p_float>("LevelOfDetailRulerSize",new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pLevelOfDetailRulerSize.pValue_get(0,0)).value = ( Float.MAX_VALUE );
			pdefattrs.AddParameter(pLevelOfDetailRulerSize);;
		}
		{
			CqParameterTypedUniformArray<p_float, p_float> pLevelOfDetailBounds = new CqParameterTypedUniformArray<p_float, p_float>("LevelOfDetailBounds",2,new EqVariableType(type_float), p_float.class,p_float.class);
			((p_float)pLevelOfDetailBounds.pValue_get(0,0)).value = ( 0.0f );
			((p_float)pLevelOfDetailBounds.pValue_get(0,1)).value = ( 1.0f );
			pdefattrs.AddParameter(pLevelOfDetailBounds);;
		}
		
		AddAttribute( pdefattrs );
	}

	public CqAttributes( CqAttributes From ){
		this.assignment( From );
		
		// Register ourself with the global attribute stack.
		Attribute_Stack.addFirst( this );
//		m_StackIterator = Attribute_Stack.iterator();
	}
	
	public void destruct(){
//		// Remove ourself from the stack
//		Attribute_Stack.erase( m_StackIterator );
		
//		m_StackIterator.remove();
		Attribute_Stack.remove( this );
	}
	
	
	//************************************************************************//
	//*** メソッドの定義
	//************************************************************************//
	
	public void AddRef(){
		super.AddRef();
	}
	public void Release(){
		super.Release();
	}
	
	/** Get a pointer to this attribute state suitable for writing.
	 * I the external references count is greater than 1, then create a copy on the stack and return that.
	 * @return a pointer to these attribute safe to write into.
	 */
	public CqAttributes Write()
	{
		// We are about to write to this attribute,so clone if references exist.
		if ( RefCount() > 1 )
		{
			CqAttributes pWrite = Clone();
			pWrite.AddRef();
			this.Release();
			return ( pWrite );
		}
		else
			return ( this );
	}
	
	/** Add a new user defined attribute.
	 * @param pAttribute a pointer to the new user defined attribute.
	 */
	public void AddAttribute( final CqNamedParameterList pAttribute )
	{
		m_aAttributes.Add( pAttribute );
	}
	/** Get a pointer to a named user defined attribute.
	 * @param strName the name of the attribute to retrieve.
	 * @return a pointer to the attribute or 0 if not found.
	 */
	public CqNamedParameterList pAttribute( final String strName )
	{
		return ( m_aAttributes.Find( strName ) );
	}
	/** Get a pointer to a named user defined attribute suitable for writing.
	 * If the attribute has more than 1 external reference, create a duplicate an return that.
	 * @attention If the attribute does not exist in the list, one will automatically be created and added.
	 * @param strName the name of the attribute to retrieve.
	 * @return a pointer to the attribute.
	 */
	public CqNamedParameterList pAttributeWrite( final String strName )
	{
		CqNamedParameterList pAttr = m_aAttributes.Find( strName );
		if ( pAttr!=null )
		{
			//XXX: unique()に代わって、単純なreturnを実装した。 2005.08.29.isawa
//			if ( pAttr.unique() )
//				return ( pAttr );
//			else
//			{
				CqNamedParameterList pNew = new CqNamedParameterList( pAttr );
				m_aAttributes.Remove( pAttr );
				m_aAttributes.Add( pNew );
				return ( pNew );
//			}
		}
		CqNamedParameterList pNew = new CqNamedParameterList( strName );
		m_aAttributes.Add( pNew );
		return ( pNew );
	}
	
	/** Add a lightsource to the current available list.
	 * @param pL a pointer to the new lightsource.
	 */
	public void AddLightsource( final CqLightsource pL )
	{
		// Check if the ligthsource is already active
		for ( CqLightsource i : m_apLightsources )
		{
			if ( i == pL )
				return ;
		}
		m_apLightsources.add( pL );
	}
	/** Remove a lightsource from the current available list.
	 * @param pL a pointer to the lightsource to remove.
	 */
	public void	RemoveLightsource( final CqLightsource pL )
	{
		// Check if the ligthsource is in the active list.
		for ( CqLightsource i : m_apLightsources )
		{
			if ( i == pL )
			{
				m_apLightsources.remove( i );
				return ;
			}
		}
	}
	/** Get a reference to the lightsource list.
	 * @return a reference to the vector of lightsource pointers.
	 */
	public STLVector< CqLightsource > apLights()
	{
		return ( m_apLightsources );
	}
	
	/** Flip the orientation in which primitives are described between left and right handed.
	 * @param time the frame time to get the values in the case of a motion blurred attribute. (not used).
	 */
	public void	FlipeOrientation( float time )
	{
		boolean co = GetIntegerAttribute( "System", "Orientation" ) [ 0 ] == 0;
		GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = ( co ) ? 1 : 0;
	}
	
	public IqShader pshadDisplacement( float time )
	{
		return ( m_pshadDisplacement );
	}
	public void SetpshadDisplacement( final IqShader pshadDisplacement, float time )
	{
		m_pshadDisplacement = pshadDisplacement;
	}
	public IqShader pshadAreaLightSource( float time )
	{
		return ( m_pshadAreaLightSource );
	}
	public void SetpshadAreaLightSource( final IqShader pshadAreaLightSource, float time )
	{
		m_pshadAreaLightSource = pshadAreaLightSource;
	}
	public IqShader pshadSurface( float time )
	{
		return ( m_pshadSurface );
	}
	public void SetpshadSurface( final IqShader pshadSurface, float time )
	{
		m_pshadSurface = pshadSurface;
	}
	public IqShader pshadAtmosphere( float time )
	{
		return ( m_pshadAtmosphere );
	}
	public void SetpshadAtmosphere( final IqShader pshadAtmosphere, float time )
	{
		m_pshadAtmosphere = pshadAtmosphere;
	}
	public IqShader pshadExteriorVolume( float time )
	{
		return ( m_pshadExteriorVolume );
	}
	public void SetpshadExteriorVolume( final IqShader pshadExteriorVolume, float time )
	{
		m_pshadExteriorVolume = pshadExteriorVolume;
	}
	public IqShader pshadAreaInteriorVolume( float time )
	{
		return ( m_pshadInteriorVolume );
	}
	public void SetpshadInteriorVolume( final IqShader pshadInteriorVolume, float time )
	{
		m_pshadInteriorVolume = pshadInteriorVolume;
	}
	
	/** Get the array of trim curve loops.
	 *	\return A pointer to the trim loops array object.
	 */
	public CqTrimLoopArray TrimLoops()
	{
		return ( m_TrimLoops );
	}
	
	/** Clone the entire attribute state.
	 * @return a pointer to the new attribute state.
	 */
	public CqAttributes Clone()
	{
		return ( new CqAttributes( this ) );
	}
	
	/** Get a system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqParameter pointer or 0 if not found.
	 */
	public CqParameter pParameter( final String strName, final String strParam )
	{
	    CqNamedParameterList pList = pAttribute( strName );
	    if ( pList!=null )
	    {
	        return ( pList.pParameter( strParam ) );
	    }
	    return ( null );
	}
	

	/** Get a system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqParameter pointer or 0 if not found.
	 */
	public CqParameter pParameterWrite( final String strName, final String strParam )
	{
	    CqNamedParameterList pList = pAttributeWrite( strName );
	    if ( pList!=null )
	    {
	        return ( pList.pParameter( strParam ) );
	    }
	    return ( null );
	}

	/* *********************** */
	/* インターフェースの実装  */
	/* *********************** */
	
	/** Get a float system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return Float pointer 0 if not found.
	 */
	public	p_float[] GetFloatAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
//	        return ( (p_float[])((CqParameterTyped<p_float, Float>)( pParam )).pValue() );
	    	
	    	Object[] pvalue = ((CqParameterTyped<p_float, p_float>)( pParam )).pValue();
	    	p_float[] ret = new p_float[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (p_float)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get an integer system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return Integer pointer 0 if not found.
	 */
	public	p_int[] GetIntegerAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
	    	Object[] pvalue = ((CqParameterTyped<p_int, p_float>)( pParam )).pValue();
	    	p_int[] ret = new p_int[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (p_int)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a string system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqString pointer 0 if not found.
	 */
	public p_String[] GetStringAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
//	        return ( (String[])( (CqParameterTyped<String, String>)( pParam ) ).pValue() );
	    	
	    	Object[] pvalue = ((CqParameterTyped<p_String, p_String>)( pParam )).pValue();
	    	p_String[] ret = new p_String[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (p_String)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a point system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVetor3D pointer 0 if not found.
	 */
	public CqVector3D[] GetPointAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqVector3D[])( (CqParameterTyped<CqVector3D, CqVector3D>)( pParam ) ).pValue() );
	        
	    	Object[] pvalue = ((CqParameterTyped<CqVector3D, CqVector3D>)( pParam )).pValue();
	    	CqVector3D[] ret = new CqVector3D[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqVector3D)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a vector system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVetor3D pointer 0 if not found.
	 */
	public CqVector3D[] GetVectorAttributeWrite( final String strName, final String strParam )
	{
	    return ( GetPointAttributeWrite( strName, strParam ) );
	}


	/** Get a normal system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVetor3D pointer 0 if not found.
	 */
	public CqVector3D[] GetNormalAttributeWrite( final String strName, final String strParam )
	{
	    return ( GetPointAttributeWrite( strName, strParam ) );
	}


	/** Get a color system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqColor pointer 0 if not found.
	 */
	public CqColor[] GetColorAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqColor[])( (CqParameterTyped<CqColor, CqColor>)( pParam ) ).pValue() );
	     
	    	Object[] pvalue = ((CqParameterTyped<CqColor, CqColor>)( pParam )).pValue();
	    	CqColor[] ret = new CqColor[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqColor)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a matrix system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqMatrix pointer 0 if not found.
	 */
	public CqMatrix[] GetMatrixAttributeWrite( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameterWrite( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqMatrix[])( (CqParameterTyped<CqMatrix, CqMatrix>)( pParam ) ).pValue() );
	        
	    	Object[] pvalue = ((CqParameterTyped<CqMatrix, CqMatrix>)( pParam )).pValue();
	    	CqMatrix[] ret = new CqMatrix[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqMatrix)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a float system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return Float pointer 0 if not found.
	 */
	public float[] GetFloatAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
	    	// float[]に型変換してみました。2005.08.30.isawa
//	        return ( (float[])( (CqParameterTyped<Float, Float>)( pParam ) ).pValue() );
	    	Object[] pTemp = ( (CqParameterTyped<p_float, p_float>)( pParam ) ).pValue();
	    	float[] ret = new float[ pTemp.length ];
	    	for( int i=0; i<pTemp.length; i++ ){
	    		ret[i] = ((p_float)pTemp[i]).value;
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get an integer system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return Integer pointer 0 if not found.
	 */
	public int[] GetIntegerAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
	    	// int[]に型変換してみました。2005.08.30.isawa
//	    	return ( (int[])( (CqParameterTyped<Integer, Float>)( pParam ) ).pValue() );
	    	Object[] pTemp = ( (CqParameterTyped<p_int, p_float>)( pParam ) ).pValue();
	    	int[] ret = new int[ pTemp.length ];
	    	for( int i=0; i<pTemp.length; i++ ){
	    		ret[i] = ((p_int)pTemp[i]).value;
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a string system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqString pointer 0 if not found.
	 */
	public String[] GetStringAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
//	        return ( (String[])( (CqParameterTyped<String, String>)( pParam ) ).pValue() );
	        
	        Object[] pvalue = ((CqParameterTyped<p_String, p_String>)( pParam )).pValue();
	        String[] ret = new String[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = ((p_String)pvalue[i]).value;
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a point system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVector3D pointer 0 if not found.
	 */
	public CqVector3D[] GetPointAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqVector3D[])( (CqParameterTyped<CqVector3D, CqVector3D>)( pParam ) ).pValue() );
	        
	        Object[] pvalue = ((CqParameterTyped<CqVector3D, CqVector3D>)( pParam )).pValue();
	        CqVector3D[] ret = new CqVector3D[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqVector3D)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a vector system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVector3D pointer 0 if not found.
	 */
	public CqVector3D[] GetVectorAttribute( final String strName, final String strParam )
	{
	    return ( GetPointAttribute( strName, strParam ) );
	}


	/** Get a normal system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqVector3D pointer 0 if not found.
	 */
	public CqVector3D[] GetNormalAttribute( final String strName, final String strParam )
	{
	    return ( GetPointAttribute( strName, strParam ) );
	}


	/** Get a color system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqColor pointer 0 if not found.
	 */
	public CqColor[] GetColorAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqColor[])( (CqParameterTyped<CqColor, CqColor>)( pParam ) ).pValue() );
	        
	        Object[] pvalue = ((CqParameterTyped<CqColor, CqColor>)( pParam )).pValue();
	        CqColor[] ret = new CqColor[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqColor)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}


	/** Get a matrix system attribute parameter.
	 * @param strName The name of the attribute.
	 * @param strParam The name of the paramter on the attribute.
	 * @return CqMatrix pointer 0 if not found.
	 */
	public CqMatrix[] GetMatrixAttribute( final String strName, final String strParam )
	{
	    CqParameter pParam = pParameter( strName, strParam );
	    if ( pParam != null ){
//	        return ( (CqMatrix[])( (CqParameterTyped<CqMatrix, CqMatrix>)( pParam ) ).pValue() );
	        
	        Object[] pvalue = ((CqParameterTyped<CqMatrix, CqMatrix>)( pParam )).pValue();
	        CqMatrix[] ret = new CqMatrix[pvalue.length];
	    	for( int i=0; i<pvalue.length; i++ ){
	    		ret[i] = (CqMatrix)pvalue[i];
	    	}
	    	return ret;
	    }
	    else
	        return ( null );
	}
	
	
	
    public int cLights()
    {
        return ( apLights().size() );
    }
    public IqLightsource pLight( int index )
    {
        return ( m_apLightsources.get( index ) );
    }
	
	
	
	
	//************************************************************************//
	//*** 演算子のオーバーロード
	//************************************************************************//
	
	public void assignment( final CqAttributes From )
	{
		m_aAttributes.assignment( From.m_aAttributes );
		
		m_apLightsources.addAll( From.m_apLightsources );
		
		m_pshadDisplacement = From.m_pshadDisplacement;
		m_pshadAreaLightSource = From.m_pshadAreaLightSource;
		m_pshadSurface = From.m_pshadSurface;
		m_pshadAtmosphere = From.m_pshadAtmosphere;
		m_pshadInteriorVolume = From.m_pshadInteriorVolume;
		m_pshadExteriorVolume = From.m_pshadExteriorVolume;	
	}
	
	
	
	
	
}
