///////////////////////////////////////////////////////////////////////////////
/// @file deBitmap_priv.hpp
///
/// @brief bitmap loading & conversion
///
/// @author Assassin, Hootie, paradoxnj
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jan 2002
/// @author Assassin
/// @remarks Initial Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEBITMAP_PRIV_H
#define DEBITMAP_PRIV_H

#include "deList.hpp"
#include "deBitmap.hpp"
#include "deWorld_Helper.hpp"
#include "deArray.hpp"
#include "deResource_Helper.hpp"

class deBitmap : public deResourceBase, public IdeBitmap
{
	struct DriverBitmapEntry
	{
		long ID;				//id of the driver
		void *Data;				//a pointer to data the driver wants to store
		IdeDriver * Driver;		// a pointer to the driver so that the buffer can be properly freed
	};

public:
	deBitmap();
	deBitmap(const char *filename);
	void * GetRscInterface(long interface_id);
		
protected:
	// call IdeResourceBase::Release instead
	virtual ~deBitmap();
	
protected:
	deTArray<u8*>				m_Data;
	IdeDriver::BPP				m_Format;

	long						m_Width;
	long						m_Height;
	long						m_ByteDepth;
	long						m_ImageSize;
	long						m_MipLevels;
	deBoolean					m_RenderTarget;
	deTList <DriverBitmapEntry>	m_DriverData;	//info that drivers can store

	void		SetBitDepth(long depth);
	long		WrappedIndex(long X, long Y);
	long		WrappedIndex(long X, long Y, long Width, long Height);
	deBoolean	DownSampleDXTC(void* &source, void* target, long SP, long SW, long SH, long TP, long TH, 
							   IdeDriver::BPP SFormat, IdeDriver::BPP TFormat);

public:
	
	deBoolean LoadBMPFile(IdeFile *file);
	deBoolean LoadTGAFile(IdeFile *file);
	deBoolean LoadPCXFile(IdeFile *file);
	deBoolean LoadPNGFile(IdeFile *file);
	deBoolean LoadDDSFile(IdeFile *file);
	deBoolean LoadCMAPFile(IdeFile *file, const char* filename);
	friend IdeBitmap* IdeBitmap_CreateBitmapWithInfo(long Width, long Height, IdeDriver::BPP Format);
	friend long BPPByteDepth(IdeDriver::BPP BPPType);
	
public:
	deBoolean		Reset();
	void			Cleanup();
	
	void*			GetData(u32 FaceNum);
	long			GetWidth();
	long			GetHeight();
	IdeDriver::BPP	GetFormat();
	long			GetBitDepth();
	long			GetByteDepth();
	DWORD			GetImageSize();
	long			GetNumFaces();
	deBoolean		IsRenderTarget();
	long			GetScalingFactor();
	deARGB			GetColorAt(long X, long Y);
	void			GetFloatColorAt(long X, long Y, deColor & color);
	long			GetMipLevels();
	
	deBoolean		SetData(void *data, long ByteLength, u32 FaceNum);
	void			SetWidth(long width);
	void			SetHeight(long height);
	void			SetFormat(IdeDriver::BPP Format);
	void			SetImageSize(long size);
	void			SetRenderTarget(deBoolean RenderTarget);
	void			SetColorAt(long X, long Y, deARGB Color);
	void			SetColorAt(long X, long Y, const deColor & color);
	deBoolean		SetNumFaces(long NumFaces);
	void			SetMipLevels(long MipLevels);
	
	deBoolean		CopyRect(const IdeBitmap* &Source, deRect *SourceRect, long TargetX, long TargetY);

	deBoolean		SaveToFileSystem(IdeFileSystem *FS, const char *filename);
	deBoolean		SaveToFile(IdeFile *file);
	
	void*			GetDriverData(long ID);
	deBoolean		SetDriverData(long ID, void *Data, IdeDriver * Driver);
	
	deBoolean		ConvertGrayScaleToDot3(long numsamples, deFloat amplify);
	deBoolean		BindGrayScaleAsAlphaMap(IdeBitmap *AlphaMap);
	deBoolean		DownSampleMIP(void* &source, void* target, long SW, long SH, long SP, 
									long TW, long TH, long TP, IdeDriver::BPP SFormat, IdeDriver::BPP TFormat);
	
	IdeResourceBase	*MakeCopy();

	static long		s_BitmapRscInterfaceID;
};

class deBitmapProxy : public deWorldObject, virtual public IdeBitmapProxy
{
protected:
	virtual ~deBitmapProxy();
	
public:
	deBitmapProxy(IdeBitmap* bmp = NULL);

	WorldObjectClassDef;
	void*		GetWOInterface(long interface_id);

	void		SetBitmap(IdeBitmap* bmp);
	IdeBitmap*	GetBitmap();
	void		SetFilename(const char* filename);

	void		SettingSavePixels(deBoolean Save);

	const char*		GetFilename();
	void			GetFilenameBuffer(char *buffer, long buffersize);
	long			GetWidth();
	long			GetHeight();
	IdeDriver::BPP	GetFormat();

	static long		s_BitmapProxyWOInterfaceID;

private:
	IdeBitmap* m_BMP;
	char m_BitmapName[256];
	deBoolean m_SavePixels;
};

// helper functions
void		GetColorIn(u8* data, IdeDriver::BPP Format, deColor &Color);
void		SetColorIn(u8* data, IdeDriver::BPP Format, deColor Color);
deBoolean	DecompressDXTC(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP SFormat, IdeDriver::BPP TFormat);
deBoolean	DecompressDXT1(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP TFormat);
deBoolean	DecompressDXT2(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP TFormat);
deBoolean	DecompressDXT3(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP TFormat);
deBoolean	DecompressDXT4(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP TFormat);
deBoolean	DecompressDXT5(const void* source, void* target,
						   long Width, long Height, long TP,
						   IdeDriver::BPP TFormat);

#endif
