/*****************************************************************************
 * $Id: mod_pony_cloud_cirrus.cc,v 1.1 2006/11/24 21:56:58 devel Exp $
 * @file
 * @author	Jim E. Brooks  http://www.jimbrooks.org
 * @brief	CirrusCloud class.
 *//*
 * LEGAL:	COPYRIGHT (C) 2006 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE (GPL).
 *****************************************************************************/

#define MOD_PONY_CLOUD_CIRRUS_CC 1
#include "mod_pony_common.hh"
#include "gfx_random.hh"
#include "mod_pony_cloud.hh"
#include "mod_pony_cloud_cirrus.hh"

////////////////////////////////////////////////////////////////////////////////
///////////////////////////////  CirrusCloud  //////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

SafePtr<const CirrusCloud::Shape>      CirrusCloud::msShape;
CloudBillboardMap<CirrusCloud::Shape>  CirrusCloud::msCloudBillboardMap;

/*****************************************************************************
 * Ctor/dtor.
 * @param	q
 * @param	pos
 * @param	radius
 * @param	shape
 *			Defines cloud's shape.
 * @param	asBillboard
 *          If false, cirrus cloud will be a single large textured quad.
 *****************************************************************************/
CirrusCloud::CirrusCloud( QuadrantPtrConst q, const Position& pos, const fp radius, const Shape& shape, const bool asBillboard )
:   Parent(q, pos)
{
	SetRadius( radius );

	if ( ! asBillboard )
	{
		// Construct as simple large quad.
		static Texcoord8 sTexcoords;
		IF_ONCE
		{
			sTexcoords[0] = 0.0; sTexcoords[1] = 0.0;  // corner 0
			sTexcoords[2] = 1.0; sTexcoords[3] = 0.0;  // corner 1
			sTexcoords[4] = 1.0; sTexcoords[5] = 1.0;  // corner 2
			sTexcoords[6] = 0.0; sTexcoords[7] = 1.0;  // corner 3
		}
		ASSERT( shape.mTextureNames.size() == 1 );  // mTextureNames[] has 1 elem
		Texture2Ptr texture = gEng.GetTexture( shape.mTextureNames[0] );
		texture->SetFunc( Texture2::eFunc_REPLACE );
		mTexQuad.Set( texture, sTexcoords, RGBA() );
		mTexQuad.mWorldVertexs[0].Set( pos[XX]+radius, pos[YY], pos[ZZ]+radius );
		mTexQuad.mWorldVertexs[1].Set( pos[XX]+radius, pos[YY], pos[ZZ]-radius );
		mTexQuad.mWorldVertexs[2].Set( pos[XX]-radius, pos[YY], pos[ZZ]-radius );
		mTexQuad.mWorldVertexs[3].Set( pos[XX]-radius, pos[YY], pos[ZZ]+radius );
	}
	else
	{
		// Construct as a Billboard.
	    // Get Billboard object associated with this cloud.
		msShape = &shape;  // implied arg for Paint(), MakeInstance() will invoke it
		SafePtr<Billboard> billboard = \
        msCloudBillboardMap.GetBillboard( shape,
		                                  *this,
		                                  Billboard::Parm( shape.mTextureNames ) );
	    // Make an instance of billboard.  Billboard is an object factory.
	    // It creates a set of BillboardSlice objects for a particular BillboardOwner (this object).
	    billboard->MakeInstance( *this, *this );  // *this aren't redundant, they're passed as different types
	}

	FinalConstruction();
	DEBUG_CODE( CheckObjectCtor(); )
}
CirrusCloud::~CirrusCloud()
{
	DEBUG_CODE( CheckObjectDtor(); )
}

/*****************************************************************************
 * Stub.  Paint() applies to procedural textures.
 *****************************************************************************/
void
CirrusCloud::Paint( Billboard& billboard, const uint sliceIdx,
                    Billboard::Texel* const texels, const uint texelCnt )
{
	ASSERT(0);  // N/A never called
} 

/*****************************************************************************
 * Visibility test.
 *****************************************************************************/
int
CirrusCloud::Visible( void )
{
	return Parent::Visible();
}
/*****************************************************************************
 * Draw (N/A if billboard).
 *****************************************************************************/
void
CirrusCloud::Draw( void )
{
	// Draw single quad (N/A if billboard).
	mTexQuad.Draw( GP_SRC_ALPHA, GP_ONE_MINUS_SRC_ALPHA, eDepthTest_DISABLE );
}
