//
// ImagePlugin
//
// This example plugin demostrates loading an image from a PCX file and
// how to use the ImportableImageI interface.
//
// Also simple image plugin effect is demonstrated.
//

#ifndef __IMAGEPLUGIN_H__
#define __IMAGEPLUGIN_H__


#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "EffectI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "ParamI.h"
#include "ImportableImageI.h"
#include "BBox2C.h"
#include "Matrix2C.h"
#include "DeviceContextC.h"
#include "DeviceInterfaceI.h"
#include "ImportInterfaceC.h"
#include "TimeContextC.h"
#include "AutoGizmoC.h"



//////////////////////////////////////////////////////////////////////////
//
//  Class IDs
//  Remember to make new ones if you this file as template!
//

const PluginClass::ClassIdC	CLASS_SIMPLEIMAGE_EFFECT( 0x08DF0B9D, 0xFF4B4769 );
const PluginClass::ClassIdC	CLASS_PCX_IMPORT( 0x74C4BF04, 0xCA444A3D );


//////////////////////////////////////////////////////////////////////////
//
//  PCX importer class descriptor.
//

class PCXImportDescC : public PluginClass::ClassDescC
{
public:
	PCXImportDescC();
	virtual ~PCXImportDescC();
	virtual void*						create();
	virtual PajaTypes::int32			get_classtype() const;
	virtual PluginClass::SuperClassIdC	get_super_class_id() const;
	virtual PluginClass::ClassIdC		get_class_id() const;
	virtual const char*					get_name() const;
	virtual const char*					get_desc() const;
	virtual const char*					get_author_name() const;
	virtual const char*					get_copyright_message() const;
	virtual const char*					get_url() const;
	virtual const char*					get_help_filename() const;
	virtual PajaTypes::uint32			get_required_device_driver_count() const;
	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx );
	virtual PajaTypes::uint32			get_ext_count() const;
	virtual const char*					get_ext( PajaTypes::uint32 ui32Index ) const;
};


//////////////////////////////////////////////////////////////////////////
//
//  Simple image effect class descriptor.
//

class ImageDescC : public PluginClass::ClassDescC
{
public:
	ImageDescC();
	virtual ~ImageDescC();
	virtual void*						create();
	virtual PajaTypes::int32			get_classtype() const;
	virtual PluginClass::SuperClassIdC	get_super_class_id() const;
	virtual PluginClass::ClassIdC		get_class_id() const;
	virtual const char*					get_name() const;
	virtual const char*					get_desc() const;
	virtual const char*					get_author_name() const;
	virtual const char*					get_copyright_message() const;
	virtual const char*					get_url() const;
	virtual const char*					get_help_filename() const;
	virtual PajaTypes::uint32			get_required_device_driver_count() const;
	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx );
	virtual PajaTypes::uint32			get_ext_count() const;
	virtual const char*					get_ext( PajaTypes::uint32 ui32Index ) const;
};


namespace ImagePlugin {

//////////////////////////////////////////////////////////////////////////
//
// PCX Importer class.
//

//
// The PCX header struct.
//
#pragma pack(1)
struct PCXHeaderS {
	PajaTypes::uint8		m_ui8Manufacturer;
	PajaTypes::uint8		m_ui8Version;
	PajaTypes::uint8		m_ui8Coding;
	PajaTypes::uint8		m_ui8BPP;
	PajaTypes::uint16		m_ui16XMin;
	PajaTypes::uint16		m_ui16YMin;
	PajaTypes::uint16		m_ui16XMax;
	PajaTypes::uint16		m_ui16YMax;
	PajaTypes::uint16		m_ui16HDpi;
	PajaTypes::uint16		m_ui16VDpi;
	PajaTypes::uint8		m_ui8ColorMap[48];
	PajaTypes::uint8		m_ui8Reserved;
	PajaTypes::uint8		m_ui8NPlanes;
	PajaTypes::uint16		m_ui16BytesPerLine;
	PajaTypes::uint16		m_ui16PalInfo;
	PajaTypes::uint16		m_ui16HScreenSize;
	PajaTypes::uint16		m_ui16VScreenSize;
	PajaTypes::uint8		m_ui8Filler[54];
};
#pragma pack()


class PCXImportC : public Import::ImportableImageI
{
public:
	static PCXImportC*				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 const char*				get_filename();
	virtual bool					load_file( const char* szName, Import::ImportInterfaceC* pInterface );
	virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext );

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

	// The importable image interface.
	virtual PajaTypes::int32		get_width();
	virtual PajaTypes::int32		get_height();
	virtual PajaTypes::int32		get_pitch();
	virtual PajaTypes::int32		get_bpp();
	virtual PajaTypes::uint8*		get_data();
	virtual void					bind_texture( PajaSystem::DeviceInterfaceI* pInterface, PajaTypes::uint32 ui32Properties );
	virtual const char*				get_info();
	virtual PluginClass::ClassIdC	get_default_effect();

	virtual PajaTypes::int32		get_duration( PajaSystem::TimeContextC* pTimeContext );
	virtual PajaTypes::float32		get_start_label( PajaSystem::TimeContextC* pTimeContext );
	virtual PajaTypes::float32		get_end_label( PajaSystem::TimeContextC* pTimeContext );

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

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

private:

	bool	read_encoded_block( PajaTypes::uint32 ui32Size, PajaTypes::uint8* pBuffer, FILE* pStream );

	PajaTypes::uint32		m_ui32TextureId;
	PajaTypes::uint8*		m_pData;
	PajaTypes::int32		m_i32Width, m_i32Height;
	PajaTypes::int32		m_i32Bpp;
	std::string				m_sFileName;
};


//////////////////////////////////////////////////////////////////////////
//
// The Image effect class.
//

enum TransformGizmoParamsE {
	ID_TRANSFORM_POS = 0,
	ID_TRANSFORM_PIVOT,
	ID_TRANSFORM_ROT,
	ID_TRANSFORM_SCALE,
	TRANSFORM_COUNT,
};

enum AttributeGizmoParamsE {
	ID_ATTRIBUTE_COLOR = 0,
	ID_ATTRIBUTE_FILE,
	ATTRIBUTE_COUNT,
};

enum ImageEffectGizmosE {
	ID_GIZMO_TRANS = 0,
	ID_GIZMO_ATTRIB,
	GIZMO_COUNT,
};

class ImageEffectC : public Composition::EffectI
{
public:
	static ImageEffectC*			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( Import::FileHandleC* pHandle );
	virtual Composition::ParamI*	get_default_param( PajaTypes::int32 i32Param );

	virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext );

	virtual void					do_frame( PajaSystem::DeviceContextC* pContext );
	virtual void					eval_state( PajaTypes::int32 i32Time, PajaSystem::TimeContextC* pTimeContext );
	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:
	ImageEffectC();
	ImageEffectC( Edit::EditableI* pOriginal );
	virtual ~ImageEffectC();

private:

	Composition::AutoGizmoC*	m_pTraGizmo;
	Composition::AutoGizmoC*	m_pAttGizmo;

	PajaTypes::Matrix2C	m_rTM;
	PajaTypes::BBox2C	m_rBBox;
	PajaTypes::Vector2C	m_rVertices[4];
	PajaTypes::ColorC	m_rFillColor;
};

};	// namespace


extern ImageDescC		g_rImageDesc;
extern PCXImportDescC	g_rPCXImportDesc;


#endif	// __IMAGEPLUGIN_H__