///////////////////////////////////////////////////////////////////////////////
/// @file deBitmap.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_H
#define DEBITMAP_H

#include "deGlobalTypes.hpp"
#include "deResource.hpp"
#include "deDriver.hpp"
#include "deWorld.hpp"

#if defined(DEBITMAP_DLL_EXPORTS) || defined(DESTINY3D_EXPORT_ALL)
#	define BITMAP_API	extern "C" DEDLL_EXPORT
#elif defined(DESTINY3D_STATIC_LINK)
#	define BITMAP_API	extern "C"
#else
#	define BITMAP_API	extern "C" DEDLL_IMPORT
#endif

#ifdef USING_DESTINY3D
#ifdef _DEBUG
#	ifdef DESTINY3D_STATIC_LINK
#		pragma comment(lib, "deBitmap_sd")
#		pragma comment(lib, "zlib-d")
#		pragma comment(lib, "libpng-d")
#	else
#		pragma comment(lib, "deBitmapd")
#	endif //DESTINY3D_STATIC_LINK
#else
#	ifdef DESTINY3D_STATIC_LINK
#		pragma comment(lib, "deBitmap_s")
#		pragma comment(lib, "zlib")
#		pragma comment(lib, "libpng")
#	else
#		pragma comment(lib, "deBitmap")
#	endif //DESTINY3D_STATIC_LINK
#endif //_DEBUG
#endif //USING_DESTINY3D


class IdeDriver;
class IdeFileSystem;
class IdeBitmap;
class IdeBitmapProxy;

// factory functions
/// initialize the bitmap module
BITMAP_API deBoolean IdeBitmap_Initialize();
/// create a zero'd bitmap
BITMAP_API IdeBitmap* IdeBitmap_CreateBitmap();
/// create a bitmap proxy
/// @param FromBitmap an IdeBitmap to create a proxy from
/// @return valid IdeBitmapProxy object if FromBitmap was a NULL or a valid bitmap
BITMAP_API IdeBitmapProxy* IdeBitmap_CreateProxy(IdeResourceBase* FromBitmap = NULL);
/// create a bitmap with specific attributes (not cleared)
BITMAP_API IdeBitmap* IdeBitmap_CreateBitmapWithInfo(long Width, long Height, IdeDriver::BPP Format, deBoolean CubeMap = deFALSE);
/// get the IdeBitmap resource interface ID for use in IdeResourceBase::GetRscInterface
BITMAP_API long IdeBitmap_GetRscInterfaceID();
/// get the IdeBitmapProxy dworld object interface ID for use in IdeWorldObject::GetWOInterface
BITMAP_API long IdeBitmapProxy_GetWOInterfaceID();

/// A bitmap class for holding 2D image data.
/// Bitmaps can be used for various applications, such as texture-mapping,
/// terrain heightmapping, screenshot storage, etc. The IdeBitmap class
/// provides a means for loading, saving, and manipulating bitmap data. Used
/// with the IdeBitmapProxy class, bitmap data can be stored and loaded with
/// Destiny3D World files, allowing textures and heightmaps to be compiled into
/// them. The pixel formats for an IdeBitmap are the same as those used for
/// textures in IdeDriver::BPP. IdeBitmap stores some texture-specific
/// information, such as render target status, number of faces (6 for a cubemap),
/// and number of MIP levels to generate. IdeBitmap also supports blits from one
/// instance to another, and other compositing and converstion operations such
/// as copying a grayscale bitmap into the alpha channel of another bitmap, and
/// converting a grayscale bump-map into an equivalent dot3 normal map.
/// Related functions: IdeBitmap_CreateBitmap, IdeBitmap_CreateBitmapWithInfo, IdeBitmap_GetRscInterfaceID
//class IdeBitmap : virtual public IdeResourceBase
DE3D_INTERFACE(IdeBitmap, IdeResourceBase)
{
protected:
	// call IdeResourceBase::Release instead
	virtual ~IdeBitmap() {}

public:
	virtual deBoolean		Reset() = 0;
	virtual void			Cleanup() = 0;

	/// get the raw data contained in the bitmap
	virtual void*			GetData(u32 FaceNum = 0) = 0;
	/// get the width of this bitmap
	virtual long			GetWidth() = 0;
	/// get the height of this bitmap
	virtual long			GetHeight() = 0;
	/// get the pixelformat of this bitmap
	virtual IdeDriver::BPP	GetFormat() = 0;
	/// get the bitdepth of this bitmap (multiple of 8 almost always)
	virtual long			GetBitDepth() = 0;
	/// get the byte depth of this bitmap
	virtual long			GetByteDepth() = 0;
	/// get the total amount of memory consumed by this bitmap
	virtual DWORD			GetImageSize() = 0;
	virtual long			GetScalingFactor() = 0;
	virtual long			GetNumFaces() = 0;
	/// get the color of a certain pixel, given pixel coordinates (returns ARGB format)
	virtual deARGB			GetColorAt(long X, long Y) = 0;
	/// get the color of a certain pixel, given pixel coordinates (using deColor format)
	virtual void			GetFloatColorAt(long X, long Y, deColor & color) = 0;
	/// get whether or not this bitmap is used as a render target
	virtual deBoolean		IsRenderTarget() = 0;
	/// retrieve the number of mip levels for this bitmap
	virtual long			GetMipLevels() = 0;

	virtual deBoolean		SetData(void *data, long ByteLength, u32 FaceNum = 0) = 0;
	virtual void			SetWidth(long width) = 0;
	virtual void			SetHeight(long height) = 0;
	virtual void			SetFormat(IdeDriver::BPP Format) = 0;
	virtual void			SetBitDepth(long depth) = 0;
	virtual void			SetImageSize(long size) = 0;
	virtual void			SetRenderTarget(deBoolean RenderTarget) = 0;
	virtual void			SetColorAt(long X, long Y, deARGB Color) = 0;
	virtual deBoolean		SetNumFaces(long NumFaces = 1) = 0;
	virtual void			SetMipLevels(long MipLevels = -1) = 0;

	/// Blitting function. Blits a source bitmap into this bitmap, clamping the edges.
	/// Source bitmap must share the same pixel format as this target.
	virtual deBoolean		CopyRect(const IdeBitmap* &Source, deRect *SourceRect, long TargetX, long TargetY) = 0;

	virtual deBoolean		SaveToFileSystem(IdeFileSystem *FS, const char *filename) = 0;
	virtual deBoolean		SaveToFile(IdeFile *file) = 0;

	// internal engine use only
	virtual void*			GetDriverData(long ID) = 0;
	virtual deBoolean		SetDriverData(long ID, void *Data, IdeDriver * Driver) = 0;

	/// convert this grayscale bitmap into a 32-bit DOT3 bitmap
	virtual deBoolean		ConvertGrayScaleToDot3(long numsamples = 7, deFloat amplify = 0.0f) = 0;
	/// use another bitmap (same height & width) to fill in the alpha channel in this one
	virtual deBoolean		BindGrayScaleAsAlphaMap(IdeBitmap *AlphaMap) = 0;
	virtual deBoolean		DownSampleMIP(void* &source, void* target, long SW, long SH, long SP, long TW, long TH, long TP, IdeDriver::BPP SFormat, IdeDriver::BPP TFormat) = 0;
};

/// Proxy class for storing bitmaps as DWorld objects.
/// Related functions: IdeBitmap_CreateProxy, IdeBitmapProxy_GetWOInterfaceID
class IdeBitmapProxy : virtual public IdeWorldObject
{
protected:
	virtual ~IdeBitmapProxy() {}

public:
	/// give the proxy object a bitmap to work with
	virtual void		SetBitmap(IdeBitmap* bmp) = 0;
	/// retrieve the bitmap that the proxy holds
	virtual IdeBitmap*	GetBitmap() = 0;
	/// give the proxy object a bitmap filename to reference
	virtual void		SetFilename(const char* filename) = 0;

	/// save the bitmap pixels to a file
	virtual void		SettingSavePixels(deBoolean Save) = 0;

	// some utility functions for pass-through operations

	/// get the filename of the bitmap held by the proxy, if it has one
	virtual const char*		GetFilename() = 0;
	virtual void			GetFilenameBuffer(char *buffer, long buffersize) = 0;
	virtual long			GetWidth() = 0;
	virtual long			GetHeight() = 0;
	virtual IdeDriver::BPP	GetFormat() = 0;
};

#endif
