// 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.QGetRenderContext;
import static net.cellcomputing.himawari.shaderexecenv.GlobalShaderExecEnv.*;
import static net.cellcomputing.himawari.library.RiGlobal.*;
import static net.cellcomputing.himawari.library.EqEnvVars.*;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqVector3D;
import net.cellcomputing.himawari.shaderexecenv.CqShaderExecEnv;

/**
 * 
 * 
 * 
 * @author NTT DATA Corporation
 */
public strictfp class CqLightsource implements IqLightsource {
	
	private IqShader			m_pShader;			///< Pointer to the associated shader.
	private CqAttributes		m_pAttributes;		///< Pointer to the associated attributes.
	private IqShaderExecEnv	m_pShaderExecEnv;	///< Pointer to the shader execution environment.
	
	
	//************************************************************************//
	//*** コンストラクタの定義
	//************************************************************************//
	
	public CqLightsource( final IqShader pShader, boolean fActive )
	{
		m_pShader = pShader;
		m_pAttributes = null;
		m_pShaderExecEnv = new CqShaderExecEnv();
		// Set a reference with the current attributes.
		m_pAttributes = (CqAttributes)( QGetRenderContext().pattrCurrent() );
		m_pAttributes.AddRef();
	}
	
	public CqLightsource( final IqShader pShader ){
		this( pShader, true );
	}
	
	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.library.IqLightsource#destruct()
	 */
	public void destruct() {
		m_pAttributes = null;
	}
	
	
	//************************************************************************//
	//*** メソッドの定義
	//************************************************************************//
	
	/** Get a pointer to the associated lightsource shader.
	 * \return a pointer to a IqShader derived class.
	 */
	public  IqShader pShader()
	{
		return ( m_pShader );
	}
	
	/** Initialise the environment for the specified grid size.
	 * \param iGridRes Integer grid resolution.
	 * \param iGridRes Integer grid resolution.
	 */
	public void Initialise( int uGridRes, int vGridRes )
	{
		int Uses = gDefLightUses;
		if ( m_pShader!=null )
		{
			Uses |= m_pShader.Uses();
			m_pShaderExecEnv.Initialise( uGridRes, vGridRes, m_pAttributes, (IqTransform)null, m_pShader, Uses );
		}
		
		if ( m_pShader!=null )
			m_pShader.Initialise( uGridRes, vGridRes, m_pShaderExecEnv );
		
		if ( USES( Uses, EnvVars_L ) )	L() .Initialise( uGridRes, vGridRes );
		if ( USES( Uses, EnvVars_Cl ) )	Cl() .Initialise( uGridRes, vGridRes );
		
		// Initialise the geometric parameters in the shader exec env.
		if ( USES( Uses, EnvVars_P ) )	P() .SetPoint( QGetRenderContext() .matSpaceToSpace( "shader", "current", m_pShader.matCurrent(), new CqMatrix(), QGetRenderContextI().Time() ).multiply( new CqVector3D( 0.0f, 0.0f, 0.0f ) ) );
		if ( USES( Uses, EnvVars_u ) )	u() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_v ) )	v() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_du ) )	du() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_dv ) )	dv() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_s ) )	s() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_t ) )	t() .SetFloat( 0.0f );
		if ( USES( Uses, EnvVars_N ) )	N() .SetNormal( new CqVector3D( 0.0f, 0.0f, 0.0f ) );
	}
	
	
	/** Evaluate the shader.
	 * \param pPs the point being lit.
	 */
	public void Evaluate( IqShaderData pPs, IqShaderData pNs, IqSurface pSurface )
	{
		Ps().SetValueFromVariable( pPs );
		Ns().SetValueFromVariable( pNs );
		m_pShaderExecEnv.SetCurrentSurface(pSurface);
		m_pShader.Evaluate( m_pShaderExecEnv );
	}
	
	/** Get a pointer to the attributes associated with this lightsource.
	 * \return a CqAttributes pointer.
	 */
	public IqAttributes pAttributes()
	{
		return ( m_pAttributes );
	}
	
	
	// Redirect acces via IqShaderExecEnv
	public	int	uGridRes()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.uGridRes() );
	}
	public	int	vGridRes()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.vGridRes() );
	}
	public	int	GridSize()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.GridSize() );
	}
	public	CqMatrix	matObjectToWorld()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.matObjectToWorld() );
	}
	public	IqShaderData Cs()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Cs() );
	}
	public	IqShaderData Os()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Os() );
	}
	public	IqShaderData Ng()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Ng() );
	}
	public	IqShaderData du()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.du() );
	}
	public	IqShaderData dv()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.dv() );
	}
	public	IqShaderData L()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.L() );
	}
	public	IqShaderData Cl()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Cl() );
	}
	public IqShaderData Ol()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Ol() );
	}
	public IqShaderData P()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.P() );
	}
	public IqShaderData dPdu()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.dPdu() );
	}
	public IqShaderData dPdv()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.dPdv() );
	}
	public IqShaderData N()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.N() );
	}
	public IqShaderData u()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.u() );
	}
	public IqShaderData v()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.v() );
	}
	public IqShaderData s()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.s() );
	}
	public IqShaderData t()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.t() );
	}
	public IqShaderData I()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.I() );
	}
	public IqShaderData Ci()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Ci() );
	}
	public IqShaderData Oi()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Oi() );
	}
	public IqShaderData Ps()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Ps() );
	}
	public IqShaderData E()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.E() );
	}
	public IqShaderData ncomps()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.ncomps() );
	}
	public IqShaderData time()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.time() );
	}
	public IqShaderData alpha()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.alpha() );
	}
	public IqShaderData Ns()
	{
		assert( m_pShaderExecEnv!=null ); return ( m_pShaderExecEnv.Ns() );
	}
	

}
