#ifndef __PLASMAPLUGIN_H__
#define __PLASMAPLUGIN_H__

#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "ClassDescC.h"
#include "EffectI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "LayerC.h"
#include "ParamI.h"
#include "ImportableI.h"
#include "ImportableImageI.h"
#include "BBox2C.h"
#include "Matrix2C.h"
#include "DeviceContextC.h"
#include "DeviceInterfaceI.h"
#include "OpenGLViewportC.h"
#include "OpenGLDeviceC.h"
#include "TimeContextC.h"


const	PluginClass::ClassIdC	CLASS_PLASMAEFFECT( 0, 101 );


namespace PlasmaEffect {

	enum PlasmaGizmoParamsE {
		PLASMA_PARAM_POS = 0,
		PLASMA_PARAM_PIVOT,
		PLASMA_PARAM_ROT,
		PLASMA_PARAM_SCALE,
		PLASMA_PARAM_COUNT,
	};


	class PlasmaGizmoC : public Composition::GizmoI
	{
	public:

		static PlasmaGizmoC*		create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		virtual Edit::DataBlockI*	create();
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		virtual void				copy( Edit::EditableI* pEditable );
		virtual void				restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_parameter_count();
		virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

		virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

		void						init();
		Import::ImportableImageI*	get_file();
		PajaTypes::Vector2C			get_pos( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_pivot( PajaTypes::int32 i32Time );
		PajaTypes::float32			get_rot( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_scale( PajaTypes::int32 i32Time );

	protected:
		PlasmaGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		PlasmaGizmoC( Edit::EditableI* pOriginal );
		virtual ~PlasmaGizmoC();

	private:
		Composition::ParamVector2C*	m_pParamPos;
		Composition::ParamFloatC*		m_pParamRot;
		Composition::ParamVector2C*	m_pParamScale;
		Composition::ParamVector2C*	m_pParamPivot;
	};


	enum AttributeGizmoParamsE {
		ATTRIBUTE_PARAM_SIZE = 0,
		ATTRIBUTE_PARAM_COLOR,
		ATTRIBUTE_PARAM_RENDERMODE,
		ATTRIBUTE_PARAM_TILE,
		ATTRIBUTE_PARAM_FILE,
		ATTRIBUTE_PARAM_COUNT,
	};

	class AttributeGizmoC : public Composition::GizmoI
	{
	public:

		static AttributeGizmoC*		create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		virtual Edit::DataBlockI*	create();
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		virtual void				copy( Edit::EditableI* pEditable );
		virtual void				restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_parameter_count();
		virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

		virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

		void						init();
		Import::ImportableImageI*	get_file( PajaTypes::int32 i32Time, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext );
		PajaTypes::ColorC			get_color( PajaTypes::int32 i32Time );
		PajaTypes::int32			get_render_mode( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_tile( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_size( PajaTypes::int32 i32Time );

	protected:
		AttributeGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		AttributeGizmoC( Edit::EditableI* pOriginal );
		virtual ~AttributeGizmoC();

	private:
		Composition::ParamVector2C*		m_pParamTile;
		Composition::ParamVector2C*		m_pParamSize;
		Composition::ParamColorC*		m_pParamColor;
		Composition::ParamIntC*			m_pParamRenderMode;
		Composition::ParamFileC*		m_pParamFile;
	};


	//
	// gizmo for ripple part
	//

	enum RippleGizmoParamsE {
		RIPPLE_PARAM_AMOUNT = 0,
		RIPPLE_PARAM_CENTER,
		RIPPLE_PARAM_FREQ,
		RIPPLE_PARAM_SPEED,
		RIPPLE_PARAM_COUNT,
	};


	class RippleGizmoC : public Composition::GizmoI
	{
	public:

		static RippleGizmoC*		create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		virtual Edit::DataBlockI*	create();
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		virtual void				copy( Edit::EditableI* pEditable );
		virtual void				restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_parameter_count();
		virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

		virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

		void						init();
		PajaTypes::float32			get_amount( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_center( PajaTypes::int32 i32Time );
		PajaTypes::float32			get_freq( PajaTypes::int32 i32Time );
		PajaTypes::float32			get_speed( PajaTypes::int32 i32Time );

	protected:
		RippleGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		RippleGizmoC( Edit::EditableI* pOriginal );
		virtual ~RippleGizmoC();

	private:
		Composition::ParamVector2C*		m_pParamCenter;
		Composition::ParamFloatC*		m_pParamAmount;
		Composition::ParamFloatC*		m_pParamFreq;
		Composition::ParamFloatC*		m_pParamSpeed;
	};


	//
	// gizmo for warp part
	//

	enum WarpGizmoParamsE {
		WARP_PARAM_AMOUNT = 0,
		WARP_PARAM_CENTER,
		WARP_PARAM_FREQ,
		WARP_PARAM_SPEED,
		WARP_PARAM_COUNT,
	};


	class WarpGizmoC : public Composition::GizmoI
	{
	public:

		static WarpGizmoC*			create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		virtual Edit::DataBlockI*	create();
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		virtual void				copy( Edit::EditableI* pEditable );
		virtual void				restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_parameter_count();
		virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

		virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

		void						init();
		PajaTypes::Vector2C			get_amount( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_center( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_freq( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_speed( PajaTypes::int32 i32Time );

	protected:
		WarpGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		WarpGizmoC( Edit::EditableI* pOriginal );
		virtual ~WarpGizmoC();

	private:
		Composition::ParamVector2C*		m_pParamCenter;
		Composition::ParamVector2C*		m_pParamAmount;
		Composition::ParamVector2C*		m_pParamFreq;
		Composition::ParamVector2C*		m_pParamSpeed;
	};

	//
	// gizmo for rot part
	//

	enum RotGizmoParamsE {
		ROT_PARAM_AMOUNT = 0,
		ROT_PARAM_CENTER,
		ROT_PARAM_SPEED,
		ROT_PARAM_COUNT,
	};


	class RotGizmoC : public Composition::GizmoI
	{
	public:

		static RotGizmoC*			create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		virtual Edit::DataBlockI*	create();
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		virtual void				copy( Edit::EditableI* pEditable );
		virtual void				restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_parameter_count();
		virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

		virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

		void						init();
		PajaTypes::float32			get_amount( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_center( PajaTypes::int32 i32Time );
		PajaTypes::Vector2C			get_speed( PajaTypes::int32 i32Time );

	protected:
		RotGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
		RotGizmoC( Edit::EditableI* pOriginal );
		virtual ~RotGizmoC();

	private:
		Composition::ParamVector2C*		m_pParamCenter;
		Composition::ParamFloatC*		m_pParamAmount;
		Composition::ParamVector2C*		m_pParamSpeed;
	};

	//
	// the effect
	//

	class PlasmaEffectC : public Composition::EffectI
	{
	public:
		static PlasmaEffectC*			create_new();
		virtual Edit::DataBlockI*		create();
		virtual Edit::DataBlockI*		create( Edit::EditableI* pOriginal );
		virtual void					copy( Edit::EditableI* pEditable );
		virtual void					restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32		get_gizmo_count();
		virtual Composition::GizmoI*	get_gizmo( PajaTypes::int32 i32Index );

		virtual PluginClass::ClassIdC	get_class_id();
		virtual const char*				get_class_name();

		virtual void					set_default_file( PajaTypes::int32 i32Time, Import::FileHandleC* pHandle );
		virtual Composition::ParamI*	get_default_param( PajaTypes::int32 i32Param );

		virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

		virtual void					eval_state( PajaTypes::int32 i32Time );
		virtual PajaTypes::BBox2C		get_bbox();

		virtual const PajaTypes::Matrix2C&	get_transform_matrix() const;

		virtual bool					hit_test( const PajaTypes::Vector2C& rPoint );

		virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );


	protected:
		PlasmaEffectC();
		PlasmaEffectC( Edit::EditableI* pOriginal );
		virtual ~PlasmaEffectC();

	private:
		PlasmaGizmoC*		m_pGizmo;
		AttributeGizmoC*	m_pAttribGizmo;
		RippleGizmoC*		m_pRippleGizmo;
		WarpGizmoC*			m_pWarpGizmo;
		RotGizmoC*			m_pRotGizmo;

		PajaTypes::Matrix2C	m_rTM;
		PajaTypes::BBox2C	m_rBBox;
		PajaTypes::Vector2C	m_rVertices[4];
		PajaTypes::ColorC	m_rColor;
		PajaTypes::int32	m_i32RenderMode;
//		PajaTypes::int32	m_i32Time;
		PajaTypes::Vector2C	m_rTile;

		// ripple
		PajaTypes::float32	m_f32RippleAmount;
		PajaTypes::Vector2C	m_rRippleCenter;
		PajaTypes::float32	m_f32RippleFreq;
		PajaTypes::float32	m_f32RippleSpeed;

		// warp
		PajaTypes::Vector2C	m_rWarpAmount;
		PajaTypes::Vector2C	m_rWarpCenter;
		PajaTypes::Vector2C	m_rWarpFreq;
		PajaTypes::Vector2C	m_rWarpSpeed;

		// rotation
		PajaTypes::float32	m_f32RotAmount;
		PajaTypes::Vector2C	m_rRotCenter;
		PajaTypes::Vector2C	m_rRotSpeed;
	};

};


// descprion test effect
class PlasmaDescC : public PluginClass::ClassDescC
{
public:
	PlasmaDescC() {};
	virtual ~PlasmaDescC() {};

	void*						create() { return (void*)PlasmaEffect::PlasmaEffectC::create_new(); };

	PajaTypes::int32			get_classtype() const { return PluginClass::CLASS_TYPE_EFFECT; };
	PluginClass::SuperClassIdC	get_super_class_id() const { return PluginClass::SUPERCLASS_EFFECT; };
	PluginClass::ClassIdC		get_class_id() const { return CLASS_PLASMAEFFECT; };

	const char*					get_name() const { return "Plasma"; };
	const char*					get_desc() const { return "Image warper plasma effect"; };

	const char*					get_author_name() const { return "Mikko \"memon\" Mononen"; };
	const char*					get_copyright_message() const { return "Copyright (c) 2000 Moppi Productions"; };
	const char*					get_url() const { return "http://www.moppi.inside.org/demopaja/"; };
	const char*					get_help_filename() const { return "res://help.html"; };

	virtual PajaTypes::uint32			get_required_device_driver_count() const
	{
		return 1;
	}

	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx )
	{
		return PajaSystem::CLASS_OPENGL_DEVICEDRIVER;
	}

	// file extension info. (only used in import plugins)
	PajaTypes::uint32			get_ext_count() const { return 0; };
	const char*					get_ext( PajaTypes::uint32 ui32Index ) const { return 0; };
};

extern PlasmaDescC		g_rPlasmaDesc;

#endif