/*****************************************************************************
 * $Id: mod_pony_cloud_cumulus.hh,v 1.2 2006/11/25 17:38:28 devel Exp $
 * @file
 * @author	Jim E. Brooks  http://www.jimbrooks.org
 * @brief	CumulusCloud class.
 *//*
 * LEGAL:	COPYRIGHT (C) 2006 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE (GPL).
 *****************************************************************************/

#if COMPILING_MODULE_PONY
#ifndef MOD_PONY_CLOUD_CUMULUS_HH
#define MOD_PONY_CLOUD_CUMULUS_HH 1

#include "eng_billboard.hh"
#include "mod_pony_cloud.hh"

////////////////////////////////////////////////////////////////////////////////
/// @brief CumulusCloud class.
///
class CumulusCloud : public FixedData, public BillboardOwner
{
private:
	PREVENT_COPYING(CumulusCloud)
	typedef FixedData Parent;

private:
    static const uint TEXTURE_WIDTH          = 1024/4;
    static const uint TEXTURE_WIDTH_TUNED    = 1024;         // width which texture's visual appearance was tuned
    static const uint SLICES                 = 36;
    static const uint SLICE_TEXTURE_RATIO    = 6;            // must be integral and < sliceCnt

public:
	////////////////////////////////////////////////////////////////////////////
    /// Parameters defining the shape of a cloud.
    ///
	/// Radius is omitted.  Rather, radius is a member of the Object class,
	/// and can be used to differently scale clouds with the same Shape.
    ///
    class Shape
    {
	public:
        Shape( fp     color,
               fp     alpha,
               fp     noiseFreq,
               uint16 noiseFreqScaleLimit, 
               fp     distNormFactor )
        :   mColor(color),
            mAlpha(alpha),
            mNoiseFreq(noiseFreq),
            mNoiseFreqScaleLimit(noiseFreqScaleLimit),
            mDistNormFactor(distNormFactor)
        {
        }

		friend bool operator<( const Shape& a, const Shape& b )
		{
        	RETURN_LT_TRUE_GT_FALSE( a.mColor,               b.mColor )
        	RETURN_LT_TRUE_GT_FALSE( a.mAlpha,               b.mAlpha )
        	RETURN_LT_TRUE_GT_FALSE( a.mNoiseFreq,           b.mNoiseFreq )
        	RETURN_LT_TRUE_GT_FALSE( a.mNoiseFreqScaleLimit, b.mNoiseFreqScaleLimit )
        	RETURN_LT_TRUE_GT_FALSE( a.mDistNormFactor,      b.mDistNormFactor )
            return false;  // equal
		}

	private:
        fp			mColor;
        fp			mAlpha;
        fp			mNoiseFreq;
        uint16		mNoiseFreqScaleLimit;
        fp			mDistNormFactor;
		friend class CumulusCloud;
    };

public:
					CumulusCloud( QuadrantPtrConst q, const Position& pos, const fp radius, const Shape& shape );
					~CumulusCloud();
	void			FinalConstruction( void ) { }
	const string	GetName( void ) { return string("CumulusCloud"); }
    bool            Reproducible( void ) { return true; }

    // The BillboardSlice objects are rendered instead of this.
    int             Visible( void ) { return false; }
	void			Draw( void ) { ASSERT(0); }

private:
	// Methods required by BillboardOwner:
	// GetDistance() exists in BillboardOwner and Object.
    void            Paint( Billboard& billboard, const uint sliceIdx,
                           Billboard::Texel* const texels, const uint texelCnt );
	fp				GetDistance( void ) { return Object::GetDistance(); }

	static SafePtr<const Shape>  		msShape;        		// implied arg for Paint()
	static CloudBillboardMap<Shape>     msCloudBillboardMap;	// associates a particular cloud shape with a Billboard object
};


#if MOD_PONY_CLOUD_CUMULUS_CC
void
Listener_CumulusCloud_Weather( void );
#endif

#endif // MOD_PONY_CLOUD_CUMULUS_HH
#endif // COMPILING_MODULE_PONY
