/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/include/sgx/graphics/drawsurface.hpp

*/

#ifndef SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP
#define SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP	1

class CSGXFont;

class CSGXDrawSurface  {

public:
	CSGXDrawSurface(tUINT32 w=0, tUINT32 h=0);
	virtual tUINT32 getWidth();
	virtual tUINT32 getHeight();
	
	virtual void resize(tUINT32 w, tUINT32 h);
	virtual sgxColorRGB setDrawColor(const sgxColorRGB &col);
	virtual sgxColorRGB setFillColor(const sgxColorRGB &col);
	virtual sgxColorRGBA setFillColor(const sgxColorRGBA &col);
	virtual sgxColorRGBA setFillColor(const tREAL32 r, const tREAL32 g, const tREAL32 b, const tREAL32 a=1.0f);

	virtual void clearFillColor();
	virtual void getDrawColor(sgxColorRGB &col) const;
	virtual void getFillColor(sgxColorRGB &col) const;
	virtual tUINT32 getFillTextureRegion()const;
	virtual const CSGXTexture * getFillTexture()const;
	virtual void setFillTextureRegion(const tUINT32 region);
	virtual void setFillTextureRegion(const sgxUV &uv);
	virtual void setFillTextureRegion(const tREAL32 u1, const tREAL32 v1, const tREAL32 u2, const tREAL32 v2);
	virtual void setFillTextureRegion(const tUINT32 u1, const tUINT32 v1, const tUINT32 u2, const tUINT32 v2);
	
	virtual void setFillTexture(const CSGXTexture *pTexture, const tUINT32 region = 0);
	virtual void setFillTexture(const CSGXTexture *pTexture, const tREAL32 u1, const tREAL32 v1, const tREAL32 u2, const tREAL32 v2);
	
	virtual void clearFillTexture();
	//
	// The only retrieval method is to get the whole xform. The individual components
	// e.g. rotate X, translate Y, etc are lost since the order matters, and we are
	// not concerned with keeping a list of them.
	//
	virtual void getRenderTransform(sgxTransform2D &xform) const ;
	//
	// Explicitly setting the position of all future renders
	//
	virtual void resetRenderTransform();
	virtual void setRenderTransform(const sgxTransform2D &xform);
	virtual void setRenderTransformPosition(const sgxVector2 &position);
	virtual void setRenderTransformScale(const tREAL32 &axisScale);
	virtual void setRenderTransformScale(const sgxVector2 &axisScales);
	//
	// Modify the position of all future renders, by an amount
	//
	virtual void translateRenderTransform(const sgxVector2 &offset) ;
	virtual void rotateXRenderTransform(const tREAL32 rotateXRadians);
	virtual void rotateYRenderTransform(const tREAL32 rotateYRadians);
	virtual void rotateZRenderTransform(const tREAL32 rotateZRadians);
	virtual void scaleRenderTransform(const tREAL32 &axisScale);
	virtual void scaleRenderTransform(const sgxVector2 &axisScales);
	virtual void areaTransform(const sgxRect2i &rc);
	virtual void areaTransform(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	
	//
	// Rendering lines, drawn in the current 'draw ink' colour.
	//
	virtual void drawPoint(const sgxPoint2i &pt);
	
	virtual void drawPoint(const tPOINT x, const tPOINT y);
	virtual void setLinePoint(const tPOINT x, const tPOINT y);
	virtual void drawLine(const sgxPoint2i &ptFrom, const sgxPoint2i &ptTo);
	virtual void drawLine(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	virtual void drawLineTo(const sgxPoint2i &pt);
	virtual void drawLineTo(const tPOINT x, const tPOINT y);
	virtual void drawRectangle(const sgxPoint2i &ptFrom, const sgxPoint2i &ptTo) ;
	virtual void drawRectangle(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	virtual void drawCircle(const sgxCircle2D &circle);
	
	//
	// Font handling
	//
	virtual void setCurrentFont(const sgxString &name);
	virtual void setCurrentFont(const CSGXFont *pFont);
	virtual sgxColorRGB setFontColor(const sgxColorRGB &col);
	virtual sgxColorRGBA setFontColor(const sgxColorRGBA &col);
	virtual void drawText(const char *pStr, tINT32 x, tINT32 y, const CSGXFontFormatting &fmt=CSGXFontFormatting());

	//
	// Render solid faces
	//
	typedef enum {
		eFromCentre,
		eFromTopLeft,
		eFromTopRight,
		eFromBottomLeft,
		eFromBottomRight,
	} tFocusPoint;

	virtual void fillPoint(const tPOINT x, const tPOINT y, const tFocusPoint &fp=eFromCentre);
	virtual void fillPoint(const sgxPoint2i &center, const tFocusPoint &fp=eFromCentre);
	virtual void fillPoint(const sgxPoint2i &center, tPOINT size);
	virtual void fillCircle(const sgxCircle2D &circle);
	virtual void fillBox();
	virtual void fillBox(const sgxRect2i &rc);
	virtual void fillBox(const sgxPoint2i &ptFrom, const sgxPoint2i &ptTo);
	virtual void fillBox(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	virtual void fillPolygon(const sgxVector<sgxPoint2i> &ptList) ;

	virtual void fillQuad(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2, const tPOINT x3, const tPOINT y3, const tPOINT x4, const tPOINT y4);

	virtual void tileBox();
	virtual void tileBox(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	virtual void tileBox(const sgxPoint2i &ptFrom, const sgxPoint2i &ptTo);

	virtual void surroundBox(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2, tBOOL fillCentre=TRUE);

	//
	// Basic clipping
	//
	virtual void clearClipRect();
	virtual void setClipRect(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2);
	virtual void setClipRect(const sgxRect2i &rc);
	virtual void getClipRect(sgxRect2i &rc);

protected:
	const CSGXTexture *	m_pTexture;
	const CSGXFont *	m_pCurrentFont;
	// The current region is stored in three ways,
	// so the platform can use the most efficient form.
	// (It also saves floating point errors that occur when
	// converting between pixel regions->uv->pixel regions)
	sgxUV			m_CurrentUV;
	tUINT32			m_CurrentUVRegion;
	sgxRect2i		m_CurrentUVPixels;
	//
	sgxRect2i		m_CurrentClipArea;
	//
	sgxColorRGBA 	m_CurrentDrawColor;
	sgxColorRGBA 	m_CurrentFillColor;
	sgxColorRGBA 	m_CurrentFontColor;
	tBOOL 			m_UseColorFill;
	tPOINT	 		m_fLastX, m_fLastY;
public:
	sgxTransform2D 	m_Xform;

	tUINT32			m_Width;
	tUINT32			m_Height;
	
};

class CSGXMetaSurface : public CSGXDrawSurface {
public:
	CSGXMetaSurface(CSGXDrawSurface *pSurface);
	CSGXMetaSurface(CSGXDrawSurface *pSurface, const tUINT32 width, const tUINT32 height);

	// use the parent setRenderTransform method(s)
	virtual void fillQuad(const tPOINT x1, const tPOINT y1, const tPOINT x2, const tPOINT y2, const tPOINT x3, const tPOINT y3, const tPOINT x4, const tPOINT y4);
	virtual void drawText(const char *pStr, tINT32 x, tINT32 y, const CSGXFontFormatting &fmt=CSGXFontFormatting());

protected:
	CSGXDrawSurface *m_pSurface;
};


#endif // SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP

