#pragma once
#include "Script.hpp"
//===========================================================================//
// File:	 Surface.hpp													 //
// Project:  GameOS					                                         //
// Contents: DirectDraw Surface object										 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 11/15/97  JTR    Created													 //
// 12/23/97  JTR    Documentation, Additions and Debugging 					 //
// 01/05/98  JTR    Fixed blit clip bug					 					 //
// 01/07/98  JTR    Added TGA loader, added setpixel	 					 //
//																			 //
//---------------------------------------------------------------------------//
// Copyright (C) 2000, Microsoft, Inc.										//
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

//
// uncommented by jcem
#define USEPNG



//////////////////////////////////////////////////////////////////////////////////
// bitmap format in memory
typedef struct _nativeformat
{
	int 
		m_height,
		m_width,
		m_pitch,
		m_bitDepth;
	unsigned char * 
		m_lpDynData;
	unsigned char * 
		m_lpRawData;


} NATIVEFORMAT;






typedef class Surface* HGOSSURFACE;
typedef class Font* HGOSFONT;
typedef class gos_GAF* HGOSGAF;

//
// Position structure, to decode GOSVAR_POSITION variables through a callback (location is a POSITION)
//
typedef struct
{
	signed long	x;
	signed long	y;
	signed long	z;
} POSITION;

//
// Cube structure, to decode GOSVAR_CUBE variables through a callback (region is a CUBE)
//
typedef struct
{
	POSITION p1;
	POSITION p2;
} CUBE;








class Surface
{
	public:
		NATIVEFORMAT			m_nativeFormat;
		bool					m_chromaKey;
		bool					m_isGAF;
		bool					m_isMemorySurface;

		char*					m_lpPath;
		bool					isVolatile;

		Surface(DWORD width, DWORD height);
		Surface(unsigned char * lpDyn, DWORD width, DWORD height, DWORD pitch);
		Surface(const char * name, bool volat);
		virtual ~Surface();
		void Blit(CUBE * rect, int x, int y, HGOSSURFACE dst);
		void StretchBlit(CUBE * src_rect, float sx, float sy, int x, int y, HGOSSURFACE dst );
		void* GetDataPointer();
		void Clear(DWORD color);
		void SetPixel(DWORD,DWORD,DWORD);
		void SetPixel(DWORD,DWORD, unsigned char, unsigned char, unsigned char, unsigned char);
		DWORD GetPixel(DWORD,DWORD);
		void BresenhamLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, DWORD color);
		void BHApproxNextY(unsigned int xp, unsigned int yp, unsigned int dx, unsigned int dy, int dirVector, DWORD color);
		void BHApproxNextX(unsigned int xp, unsigned int yp, unsigned int dx, unsigned int dy, int dirVector, DWORD color);
		void SetPixelNoTranslate(DWORD x, DWORD y, DWORD color);
		void CopyBitmap();
		void Restore();

	protected:
		void LoadPNGFile(const char *);
		void LoadJPGFile(const char *);
		void LoadTGAFile(const char *);
		void LoadBMPFile(const char *);
		void Load();
};

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// ***************************	  SURFACE API	 ****************************** //
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////
// The different ways text can be wrapped across a surface.
typedef enum gosEnum_TextWrap
{
	GOSWRAP_NONE,
	GOSWRAP_CHAR,
	GOSWRAP_WORD,
	GOSWRAP_CHARSCROLL,
	GOSWRAP_WORDSCROLL
};

//////////////////////////////////////////////////////////////////////////////////
// Return the path of the disk image or NULL, if none
char * gos_GetSurfacePath(HGOSSURFACE surf);

//////////////////////////////////////////////////////////////////////////////////
// Create a surface with the dimensions <width>, <height> and the surface format 
// <s_fmt> and return its handle to <hsurf>.
void gos_CreateSurface( HGOSSURFACE* hsurf, DWORD width, DWORD height);

//////////////////////////////////////////////////////////////////////////////////
// Create a surface with the dimensions <width>, <height> and the surface format 
// <s_fmt> and return its handle to <hsurf>.
void gos_CreateMemorySurface( HGOSSURFACE* hsurf, unsigned char * lpDynData, DWORD width, DWORD height, DWORD pitch);

//////////////////////////////////////////////////////////////////////////////////
// Load the BMP or TGA found at the location specified in <path> as a Surface of
// format <s_fmt>.
void gos_LoadSurface( const char* path, HGOSSURFACE* surf, bool is_volatile );

//////////////////////////////////////////////////////////////////////////////////
// Destroy and deallocate memory associated with the given surface handle <hsurf>.
void gos_DestroySurface( HGOSSURFACE* hsurf );

//////////////////////////////////////////////////////////////////////////////////
// Blit the portion of surface <src> specified in rectangle <rect> to <x>, <y> on
// surface <dst>. Conversion between surface formats is handled automatically,
// but is considered non-optimal.
void gos_BlitSurface( CUBE* rect, HGOSSURFACE src, int x, int y, HGOSSURFACE dst );

//////////////////////////////////////////////////////////////////////////////////
// Blit the portion of surface <src> specified in rectangle <rct> to <dst_rct> on
// surface <dst>. StretchBlitting doesn't current support conversion of surfaces.
//
void gos_StretchBlitSurface(CUBE * rct, HGOSSURFACE src, float sx, float sy, int x, int y,HGOSSURFACE dst);

//////////////////////////////////////////////////////////////////////////////////
// Restore the surface specified by handle <hsurf> to its original bitmap
// and convert it to the current background surface format.
void gos_RestoreSurface(HGOSSURFACE hsurf);

//////////////////////////////////////////////////////////////////////////////////
// Clear the surface pointed to by handle <hsurf> to the RbyteGbyteBbyte found
// in <color>.
void gos_ClearSurface( HGOSSURFACE surf, DWORD color );

//////////////////////////////////////////////////////////////////////////////////
// Since the internal surface pitch does not always match the width of a surface,
// use this call for proper surface data manipulations. Returns the pitch of 
// the surface pointed to by <hsurf> in bytes.
DWORD gos_GetSurfacePitch( HGOSSURFACE hsurf );

//////////////////////////////////////////////////////////////////////////////////
// Return the "visible" surface width of the surface specified by handle <hsurf>.
DWORD gos_GetSurfaceWidth( HGOSSURFACE hsurf );

//////////////////////////////////////////////////////////////////////////////////
// Return the height of the surface specified by handle <hsurf>.
DWORD gos_GetSurfaceHeight( HGOSSURFACE hsurf );

//////////////////////////////////////////////////////////////////////////////////
// Given <r>, <g>, <b> values from 0-255, return an index to the best match in
// the universal palette. The code behind this needs some attention, Andy.
unsigned char gos_PaletteColorMatch( unsigned char r, unsigned char g, unsigned char b );

//////////////////////////////////////////////////////////////////////////////////
// If you have the <x>, <y> coordinates of a point on the surface <hsurf>, and 
// you can provide the color in 0x00rrggbb format, this call will do it for you.
void gos_SetPixel( HGOSSURFACE hsurf, DWORD x, DWORD y, DWORD color );

//////////////////////////////////////////////////////////////////////////////////
// If you have the <x>, <y> coordinates of a point on the surface <hsurf>, and 
// you want the color in 0x00rrggbb format, this call will do it for you.
DWORD gos_GetPixel( HGOSSURFACE hsurf, DWORD x, DWORD y);

//////////////////////////////////////////////////////////////////////////////////
// Given surface <hsurf>, start a line at <x>, <y> at continue it to <x2>, <y2>;
// draw the line in color c (format = RbyteGbyteBbyte).
void gos_Line( HGOSSURFACE hsurf, DWORD x1, DWORD y1, DWORD x2, DWORD y2, DWORD c );

//////////////////////////////////////////////////////////////////////////////////
// Given surface <hsurf>, set the chromakey flag to <onoff>. When set to TRUE,
// GameOS will NOT draw any colors that equate to Red=0, Green=0, Blue=0.
void gos_MakeChromaKeySurface( HGOSSURFACE hsurf, bool onoff );




//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// ******************************	  GAF API	 ****************************** //
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////
// Load a GAF from disk. Use %d in filename to load images
//
void gos_CreateGAFResource(HGOSGAF * gaf, char * filename);

//////////////////////////////////////////////////////////////////////////////////
// Retrieve the width, height, and number of frames
//
void gos_GetGAFSize(HGOSGAF gaf, int * x, int * y, int * length);

//////////////////////////////////////////////////////////////////////////////////
// Imprint the surf <dst> with the <frame>th image in GAF <gaf> at <x>, <y>
//
void gos_GetGAFFrame(HGOSGAF gaf, int frame, HGOSSURFACE *dst);

//////////////////////////////////////////////////////////////////////////////////
// Deallocate all memory associated with the GAF <gaf>.
//
void gos_DestroyGAFResource(HGOSGAF * gaf);

//
// Get a handle to the surface used for GAFs
//
HGOSSURFACE gos_GetSurface(HGOSGAF gaf);




typedef LinkedList< HGOSSURFACE > AllSurfacesList;
extern AllSurfacesList AllSurfaces;

