/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg cObject.cVisibleObject.cInteractiveObject.cWater*/
/**
 * plane derived from class cInteractiveObject
 *
 * #include "cWater.hh"
 * -lglut
 *
 * @see cInteractiveObject
 * @pkgdoc cObject.cVisibleObject.cInteractiveObject.cWater
 */

#ifndef cWater_hh
#define cWater_hh

#include "cInteractiveObject.hh"

/**
 * Water surface object.
 	*
	* This object displays a water surface.
	* The surface extends from (-size_x/2,-size_y/2,-max_amp) to
	* (size_x/2, size_y/2, max_amp)
	* Texture coordinates are generated also. (default: (0.0,0.0)-(1.0,1.0))
	*
	* The maximum amplitude defaults to 1.0, the default resolution is
	* 8 subdivisions per side, which means 128 triangles.
	*/
class cWater 
:	public cInteractiveObject
{
// LIFECYCLE
public:
	/** a structure describing a center of an oscillation */
	typedef struct sOscillationCenter {
		GLfloat pos_x, pos_y;
		GLfloat amplitude;
		GLfloat frequency;
	} tsOscillationCenter;

	/**
	 * default constructor w/ optional object name
	 	* @param name name of object (optional)
	 	*/
	cWater (
		cEventDispatcher *disp,
		const char *name = NULL);

	/**
	 * constructor w/ optional size and object name
	    *
	    * default max_amp of 1.0 is used
		*
	 	* @param size_x (GLdouble) x side length of water (default: 1.0)
	 	* @param size_y (GLdouble) y side length of water (default: 1.0)
	 	* @param name name of object (optional)
	 	*/
	cWater (
		cEventDispatcher *disp,
		GLfloat size_x, 
		GLfloat size_y, 
		const char *name = NULL);

	/**
	 * default constructor
	 	* @param size_x (GLdouble) x side length of water (default: 1.0)
	 	* @param size_y (GLdouble) y side length of water (default: 1.0)
	 	* @param max_amp maximum amplitude
		* @param name name of object (optional)
	 	*/
	cWater (
		cEventDispatcher *disp,
		GLfloat size_x, 
		GLfloat size_y, 
		GLfloat max_amp,
		const char *name = NULL);

	/**
	 * default constructor
	 	* @param size_x (GLdouble) x side length of water (default: 1.0)
	 	* @param size_y (GLdouble) y side length of water (default: 1.0)
	 	* @param max_amp maximum amplitude
		* @param resolution subdivisions per side (default: 8)
		* @param name name of object (optional)
	 	*/
	cWater (
		cEventDispatcher *disp,
		GLfloat size_x, 
		GLfloat size_y, 
		GLfloat max_amp,
		int resolution,
		const char *name = NULL);

	/**
	 * destructor
	 	*/
	virtual ~cWater ();

	/**
	 * initialization function
	 	*/
	virtual int Init ();

	/**
	 * set texture coordinates to use
	 	* @param x_min from-x
	 	* @param x_max to-x
		* @param y_min from-y
	 	* @param y_max to-y
	 	*/
	virtual void SetTextureDomain (
		GLfloat x_min, GLfloat x_max,
		GLfloat y_min, GLfloat y_max);

	/**
	 * add a new oscillating source
	 	* @param src tsOscillationCenter w/ position, amplitude and freq.
		*/
	virtual void AddOscillation (
		const tsOscillationCenter &osc);

	/**
	 * event receiver - we listen for animation events
	 	*
		* @return 0 - event accepted, -1 - event not accepted
	 	*/
	virtual int ReceiveEvent (const cEvent &event);

protected:	
	/**
	 * drawing function
	 	*/
	virtual void DrawThisObject ();

	/**
	 * return class name
	 	*/
	virtual const char *GetDefaultName () const
	{
		return "cWater";
	}

	/**
	 * calculate the water surface
	 	*/
	virtual void CalculateWater ();

	/** ID of display list which contains the surface */
	GLuint mDisplayList;

	/** side length of plane */
	GLfloat mSizeX;
	GLfloat mSizeY;

	/** maximum amplitude */
	GLfloat mMaxAmp;

	/** current amplitude scaling factor for satisfying MaxAmp
	    criterion */
	GLfloat mAmpScale;

	/** resolution of surface, if given */
	int mResolution;

	/** texture domain to use */
	GLfloat mTexFromX, mTexToX, mTexFromY, mTexToY;

	/** have we animated the surface? -> need recalculation? */
	bool mRecalculationNeeded;

	/** counter for animation events */
	GLfloat mTimeStamp;

	/** number of active oscillations */
	int mOscillationNo;

	/** parameters of all oscillations */
	tsOscillationCenter *mOscillations;
};

#endif	// ifndef cWater_hh
