#ifndef __SWFSHAPE_H__
#define __SWFSHAPE_H__

#include "PajaTypes.h"
#include "Vector2C.h"
#include "Matrix2C.h"
#include "ColorC.h"
#include <vector>
#include "SWFChar.h"
#include "SWFDictionaryC.h"

//
// Fillstyle
//


enum GradientTypeE {
	GRADIENT_LINEAR = 0,
	GRADIENT_RADIAL
};

class SWFGradientC
{
public:
	SWFGradientC( PajaTypes::uint32 ui32Type = 0 );
	virtual ~SWFGradientC();

	PajaTypes::uint32			get_type() const;

	void						add_color( const PajaTypes::ColorC& rCol, PajaTypes::uint32 ui32Pos );
	PajaTypes::uint32			get_color_count() const;
	const PajaTypes::ColorC&	get_color( PajaTypes::uint32 ui32Index ) const;
	PajaTypes::uint32			get_position( PajaTypes::uint32 ui32Index ) const;

	void						build();
	PajaTypes::uint32			get_texture_id() const;

private:
	PajaTypes::uint32				m_ui32Type;
	std::vector<PajaTypes::ColorC>	m_rColors;
	std::vector<PajaTypes::uint32>	m_rPositions;
	PajaTypes::uint32				m_ui32TexId;
};


enum FillTypeE {
	FILLTYPE_SOLID = 0,
	FILLTYPE_GRADIENT,
	FILLTYPE_BITMAP,
};

class SWFFillStyleC
{
public:
	SWFFillStyleC( PajaTypes::uint32 ui32Type );
	virtual ~SWFFillStyleC();

	PajaTypes::uint32			get_type() const;

	void						set_color( const PajaTypes::ColorC& rCol );
	PajaTypes::ColorC			get_color() const;

	void						set_matrix( const PajaTypes::Matrix2C& rMat );
	const PajaTypes::Matrix2C&	get_matrix() const;

	void						set_gradient( SWFGradientC* rGrad );
	SWFGradientC*				get_gradient();

	void						set_bitmap_id( PajaTypes::uint32 ui32Id );
	PajaTypes::uint32			get_bitmap_id() const;

private:
	PajaTypes::uint32	m_ui32Type;
	PajaTypes::uint32	m_ui32BitmapId;
	PajaTypes::ColorC	m_rColor;
	PajaTypes::Matrix2C	m_rMatrix;
	SWFGradientC		m_rGradient;
};


//
// Line style
//

class SWFLineStyleC
{
public:
	SWFLineStyleC( PajaTypes::float32 f32Width, const PajaTypes::ColorC& rColor );
	virtual ~SWFLineStyleC();

	PajaTypes::ColorC	get_color() const;
	PajaTypes::float32	get_width() const;

private:
	PajaTypes::ColorC	m_rColor;
	PajaTypes::float32	m_f32Width;
};


//
// Edge
//

class SWFEdgeC
{
public:
	SWFEdgeC();
	virtual ~SWFEdgeC();

	void	set_is_curve( bool bCurve = true );
	void	set_start_point( const PajaTypes::Vector2C& rPt );
	void	set_end_point( const PajaTypes::Vector2C& rPt );
	void	set_control_point( const PajaTypes::Vector2C& rPt );
	void	set_fill_style0( PajaTypes::uint16 ui16Fill );
	void	set_fill_style1( PajaTypes::uint16 ui16Fill );
	void	set_line_style( PajaTypes::uint16 ui16Line );

	bool						is_curve() const;
	const PajaTypes::Vector2C&	get_start_point() const;
	const PajaTypes::Vector2C&	get_end_point() const;
	const PajaTypes::Vector2C&	get_control_point() const;
	PajaTypes::uint16			get_fill_style0() const;
	PajaTypes::uint16			get_fill_style1() const;
	PajaTypes::uint16			get_line_style() const;

private:
	bool				m_bCurve;
	PajaTypes::uint16	m_ui16FillStyle0;
	PajaTypes::uint16	m_ui16FillStyle1;
	PajaTypes::uint16	m_ui16LineStyle;
	PajaTypes::Vector2C	m_rStartPt;
	PajaTypes::Vector2C	m_rEndPt;
	PajaTypes::Vector2C	m_rControlPt;
};


//
// Shape record
//

struct SWFRenderEdgeS {
	PajaTypes::Vector2C	rVec[2];
	PajaTypes::uint32	ui32LineStyle;
};

class SWFRenderDispListC
{
public:
	SWFRenderDispListC();
	virtual ~SWFRenderDispListC();

	void						set_color( const PajaTypes::ColorC& rColor );
	const PajaTypes::ColorC&	get_color() const;

	void						set_displist( PajaTypes::uint32 ui32List );
	PajaTypes::uint32			get_displist() const;

	void						set_texture( PajaTypes::uint32 ui32Tex );
	PajaTypes::uint32			get_texture() const;

	void						set_fillstyle( PajaTypes::uint32 ui32Style );
	PajaTypes::uint32			get_fillstyle() const;

	void						add_edge( const SWFRenderEdgeS* pEdge );
	PajaTypes::uint32			get_edge_count() const;
	SWFRenderEdgeS*				get_edge( PajaTypes::uint32 ui32Index );

private:
	PajaTypes::ColorC			m_rColor;
	PajaTypes::uint32			m_ui32DispList;
	PajaTypes::uint32			m_ui32Texture;
	PajaTypes::uint32			m_ui32FillStyle;
	std::vector<SWFRenderEdgeS>	m_rEdges;
};

class SWFRenderShapeC
{
public:
	SWFRenderShapeC();
	virtual ~SWFRenderShapeC();

	void						add_displist( SWFRenderDispListC* rList );
	PajaTypes::uint32			get_displist_count() const;
	SWFRenderDispListC*			get_displist( PajaTypes::uint32 ui32Index );

private:
	std::vector<SWFRenderDispListC*>	m_rDispLists;
};

class SWFShapeRecordC
{
public:
	SWFShapeRecordC();
	virtual ~SWFShapeRecordC();

	// fills
	void					add_fill( const SWFFillStyleC* rFill );
	SWFFillStyleC*			get_fill( PajaTypes::uint32 ui32Idx );
	PajaTypes::uint32		get_fill_count() const;

	// outlines
	void					add_line_style( const SWFLineStyleC* pOutline );
	SWFLineStyleC*			get_line_style( PajaTypes::uint32 ui32Idx );
	PajaTypes::uint32		get_line_style_count() const;

	// edges
	void					add_edge( const SWFEdgeC* pEdge );
	const SWFEdgeC*			get_edge( PajaTypes::uint32 ui32Idx ) const;
	PajaTypes::uint32		get_edge_count() const;

	PajaTypes::float32		get_scale() const;
	void					set_scale( PajaTypes::float32 f32Scale );

	PajaTypes::float32		get_min_scale() const;
	PajaTypes::float32		get_max_scale() const;
	void					set_min_scale( PajaTypes::float32 f32Scale );
	void					set_max_scale( PajaTypes::float32 f32Scale );

	void					prepare( bool bIsGlyph, SWFDictionaryC* pDict );
	void					unprepare();

	SWFRenderShapeC*		get_render_shape();

private:
	std::vector<SWFFillStyleC>	m_rFills;
	std::vector<SWFLineStyleC>	m_rLineStyles;
	std::vector<SWFEdgeC>		m_rEdges;
	PajaTypes::float32			m_f32Scale, m_f32MinScale, m_f32MaxScale;
	SWFRenderShapeC*			m_pRenderShape;
};


//
// Shape character
//

class SWFShapeC : public SWFCharC
{
public:
	SWFShapeC();
	virtual ~SWFShapeC();

	virtual PajaTypes::uint32	get_type() const;
	virtual SWFShapeRecordC*	get_shape();

private:
	SWFShapeRecordC		m_rShape;
};


#endif