/** 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/domains/graphics/surface/imagedata.hpp

*/

#ifndef SGX_UTILS_IMAGEDATA_HPP
#define SGX_UTILS_IMAGEDATA_HPP		1

#include "domains/graphics/color/color.hpp"

class CImageParser;

// An ImageData block is a cross-platform, easy-to-handle, texture surface.
// It is always in memory and available for use, and it is always in the
// same formats: RGB:888, and RGBA:8888

// It supports a number of basic 2D operations
class CImageData {
public:
	typedef enum {
		eRGB,
		eRGBA,
		// The following are the same memory formats as
		// above, although hold a distinction for gfx
		// engines
		eLuminence,
		eAlpha,
	} tFormat;

	class Mask {
	public:
		Mask();
		Mask(const tREAL32 r, const tREAL32 g, const tREAL32 b);
		Mask(const tBYTE r, const tBYTE g, const tBYTE b, const tBYTE delta);
		Mask(const tBYTE r, const tBYTE g, const tBYTE b, const tBYTE delta_r, const tBYTE delta_g, const tBYTE delta_b);
		Mask(const sgxColorRGB &col);
		
		SGX_INLINE tBOOL isValid() const { return m_Valid; }
		SGX_INLINE tBYTE getAlpha(const tBYTE &r, const tBYTE &g, const tBYTE &b) const;

	private:
		tBOOL			m_Valid;
		tBOOL			m_RangeValid;

		tBYTE			m_MaskRed, m_MaskGreen, m_MaskBlue;
		tBYTE			m_MaskMinRed, m_MaskMinBlue, m_MaskMinGreen;
		tBYTE			m_MaskMaxRed, m_MaskMaxBlue, m_MaskMaxGreen;

	};

	CImageData(const tFormat fmt = eRGBA);
	CImageData(const CImageData &other);		// copy ctor performs a clone operation
	CImageData(const CImageData &opaque, const CImageData &alpha);
	CImageData(const tMEM_SIZE w, const tMEM_SIZE h, const tFormat fmt);
	CImageData(const tMEM_SIZE w, const tMEM_SIZE h, const tFormat fmt, const tMEM_SIZE span, tBYTE *pBitmap);
	~CImageData();



	void		create(const tMEM_SIZE w, const tMEM_SIZE h, const tFormat fmt);
	void		release();

	tMEM_SIZE	getWidth()  const { return pBitmap ? iWidth : 0; }
	tMEM_SIZE	getHeight() const { return pBitmap ? iHeight : 0; }
	tFormat		getFormat() const { return iFormat; }
	tBYTE *		getBitmap() const { return pBitmap; }

	tBOOL		IsValid() const { return pBitmap ? TRUE : FALSE; }

	tBOOL		isTransparent()const;
	tBOOL		isTranslucent()const;

	tMEM_SIZE	getSpan() const { return iSpan; }	// one row of pixels, in bytes

	tMEM_SIZE	bpp() const { return bpp(iFormat); }
	tMEM_SIZE	bpl() const { return bpp() * iWidth; }	// data bytes only. You will usually want 'Span'
	
	static tMEM_SIZE bpp(tFormat fmt) { return (tMEM_SIZE)(fmt==eRGBA ? 4 : 3); }

	void	blit(const CImageData &src_image);
	tBOOL	getPixelAt(tUINT32 &col, const tINT32 x, const tINT32 y)const;
	tBOOL	getPixelAt(sgxColorRGBA &col, const tINT32 x, const tINT32 y)const;
	tBOOL	setPixelAt(const sgxColorRGBA &col, const tINT32 x, const tINT32 y);

	void	convertFormat(tFormat new_fmt);

	// These functions generate new data in situ
	void	washAlpha(tBYTE alpha);
	void	washColor(const sgxColorRGBA &col) { washColor(col.r, col.g, col.b); }
	void	washColor(const tREAL32 red, const tREAL32 green, const tREAL32 blue) { washColor(tBYTE(red*255.0f), tBYTE(green*255.0f), tBYTE(blue*255.0f)); }
	void	washColor(const tBYTE red, const tBYTE green, const tBYTE blue);
	
	void	buildMask(const CImageData::Mask &mask);
	void	applyMask(const CImageData::Mask &mask);
	void	applyAlpha(const CImageData &alpha);

	// These functions affect the data already present.
	void	flipVertical();

	// Debug
	tBOOL	validate() const { return TRUE; }

private:
	tMEM_SIZE				iWidth;
	tMEM_SIZE				iHeight;
	tFormat					iFormat;
	tBYTE					*pBitmap;
	// iSpan is always width*bpp - UNLESS you create the bitmap manually
	tMEM_SIZE				iSpan;
	tBOOL					bOurBitmap;	// this is so we don't destroy the users bmp,
										// and it saves us from copying data on assignment

};


#endif /* SGX_UTILS_IMAGEDATA_HPP */
