/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     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: include/sgx/graphics/drawsurface.hpp

*/

#ifndef SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP
#define SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP	1

class CSGXDrawSurface  {

public:
	CSGXDrawSurface(tUINT32 w, tUINT32 h);
	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 sgxColorRGB setFillColor(const sgxColorRGBA &col);

	virtual void clearFillColor();
	virtual void getDrawColor(sgxColorRGB &col) const;
	virtual void getFillColor(sgxColorRGB &col) 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);
	
	//
	// 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);
	
	//
	// 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 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;
	// 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;
	//
	sgxColorRGB 	m_CurrentDrawColor;
	sgxColorRGB 	m_CurrentFillColor;
	tBOOL 			m_UseColorFill;
	tPOINT	 		m_fLastX, m_fLastY;
	sgxTransform2D 	m_Xform;

	tUINT32			m_Width;
	tUINT32			m_Height;
	
	CSGXDrawSurface() :m_pTexture(NULL) {}
	
};

#endif // SGX_GRAPHICS_GRAPHICS_DRAWSURFACE_HPP

