#ifndef CLMOD_H
#define CLMOD_H

#ifndef GRIM
#include "cltypes.h"
#endif

#define CL_API_VERSION		3

// Texture Filter.
// Used with GFX_SetTextureFilter (int filter)
#define TF_POINT			1
#define TF_LINEAR			2


// Blend Mode.
// Used with: GFX_SetBlendMode (int src, int dst)
#define BM_DISABLE			0
#define BM_ZERO				1
#define BM_ONE				2
#define BM_SRCCOLOR			3
#define BM_INVSRCCOLOR		4
#define BM_SRCALPHA			5
#define BM_INVSRCALPHA		6
#define BM_DESTALPHA		7
#define BM_INVDESTALPHA		8
#define BM_DESTCOLOR		9
#define BM_INVDESTCOLOR		10
#define BM_SRCALPHASAT		11
#define BM_BOTHSRCALPHA		12
#define BM_BOTHINVSRCALPHA	13



// Core variable
struct var_t
{
	char	*id;

	char	*stringValue;
	float	*floatValue;

	var_t () { id = 0; stringValue = 0; floatValue = 0; }
};



// Mod info structure
struct modInfo_t
{
	char	name[32];
	char	author[32];
	float	version;

	int		usesApiVersion;

	modInfo_t () { version = 1.0f; usesApiVersion = CL_API_VERSION; memset (name, 0, 32); memset (author, 0, 32); }
};


// 2d vertex for "arbitrary" polygon drawing
struct vertex2_t
{
	vec2_t			pos;
	vec2_t			zrhw;	// has to be always 1 0.5 (lousy optimization)
	unsigned int	col;
	vec2_t			tex;
};


// key config for 2 players (defined in Options->Controls of Crimsonland)
struct keyConfig_t
{
	int				up[2];
	int				down[2];
	int				left[2];
	int				right[2];
	int				fire[2];

	int				torsoLeft[2];
	int				torsoRight[2];
	int				joyAimAxisX[2];
	int				joyAimAxisY[2];
	int				joyMoveAxisX[2];
	int				joyMoveAxisY[2];

	int				levelUp;
	int				reload;
};


// Main MOD API exported by Crimsonland
struct clAPI_t
{
	// API version number
	int					version;

	// key configuration set Crimsonland controls. Modifying this doesn't affect cl controls itself
	keyConfig_t			keyConfig;


	// Prints formatted string on cl console
	virtual void		CORE_Printf (char *fmt, ...) = 0;
	// Get core variable -- if it doesn't exist, a new var is created so this always returns a valid pointer
	virtual var_t*		CORE_GetVar (char *id) = 0;
	// delete variable with given name. returns false if it didn't exist
	virtual bool		CORE_DelVar (char *id) = 0;
	// execute a string in cl console
	virtual void		CORE_Execute (char *string) = 0;
	// add a core command that runs given function
	virtual void		CORE_AddCommand (char *id, void (*cmd)()) = 0;
	// delete core command. returns false if it didn't exist
	virtual bool		CORE_DelCommand (char *id) = 0;
	// get core extension. Reserved for possible future use.
	virtual void		*CORE_GetExtension (char *ext) = 0;

	// clear screen with given rgba color
	virtual void		GFX_Clear (float r, float g, float b, float a) = 0;

	// gets the width of given null terminated string in pixels
	virtual int			GFX_GetStringWidth (char *string) = 0;
	// prints formatted string on screen at (x, y) in screen space
	virtual void		GFX_Printf (float x, float y, char *fmt, ...) = 0;

	// load texture from file. returns texture handle id or -1 on failure (eg. file unknown or not found)
	// Supported formats are Targa (.tga) and JPEG (.jpg)
	virtual int			GFX_LoadTexture (char *filename) = 0;
	// free texture with given handle, returns false if id was invalid
	virtual bool		GFX_FreeTexture (int texId) = 0;
	// set texture active. All quads are drawn using set texture.
	virtual void		GFX_SetTexture (int texId) = 0;

	// set texture filter. Default: TF_LINEAR
	virtual void		GFX_SetTextureFilter (int filter) = 0;
	// set source and destination blend mode. Default: src = BM_SRCALPHA, dst = BM_INVSRCALPHA
	virtual void		GFX_SetBlendMode (int src, int dst) = 0;

	// set quad rgba color
	virtual void		GFX_SetColor (float r, float g, float b, float a) = 0;
	// set quad texture coordinates, a rectangle inside the set texture. All coordinates are in range 0..1
	virtual void		GFX_SetSubset (float x1, float y1, float x2, float y2) = 0;

	// begin drawing quads
	virtual void		GFX_Begin () = 0;
	// end drawing quads
	virtual void		GFX_End () = 0;
	// draw a quad that's w pixels width and h pixels high on screen the upper left corner at (x,y)
	virtual void		GFX_Quad (float x, float y, float w, float h) = 0;
	// draw a rotated quad on screen, a is the angle of rotation in radians (2 * M_PI == 360 degrees)
	virtual void		GFX_QuadRot (float x, float y, float w, float h, float a) = 0;
	// draw multiple "arbitrary" quads with pointer to an array
	virtual void		GFX_DrawQuads (vertex2_t *v, int numQuads) = 0;

	// loads a sound sample. !! Only Ogg (.ogg) Vorbis format is supported !! returns sample handle id or -1 on failure
	virtual int			SFX_LoadSample (char *filename) = 0;
	// free sample with given id, returns false if id was invalid
	virtual bool		SFX_FreeSample (int sfxId) = 0;
	// plays sample with given panning and volume
	virtual void		SFX_PlaySample (int sfxId, float pan = 0.0f, float volume = 1.0f) = 0;

	// load a tune. !! Only Ogg Vorbis (.ogg) format is supported !! returns handle or -1 on failure
	virtual int			SFX_LoadTune (char *filename) = 0;
	// frees loaded tune with given id. returns false if id is invalid
	virtual bool		SFX_FreeTune (int tuneId) = 0;
	// plays a tune only one instance of a tune can be played at the time, (but two tunes can be played simultaneously).
	virtual void		SFX_PlayTune (int tuneId) = 0;
	// stop playing a tune with id
	virtual void		SFX_StopTune (int tuneId) = 0;

	// returns true if key is pressed down, otherwise false
	virtual bool		INP_KeyDown (int key) = 0;
	// return analog input value (eg. mouse or joystick axis)
	virtual float		INP_GetAnalog (int key) = 0;
	// gets character that's being pressed down (poor non-callback solution to get character input)
	virtual char		INP_GetPressedChar () = 0;
	// get key name string
	virtual char*		INP_GetKeyName (int key) = 0;

	// invoke Crimsonland menu. Only valid parameter is (for now):
	//		"options" to enter options
	virtual void		CL_EnterMenu (char *menu) = 0;
};


// MOD implementation
struct modExport_t
{
	// MOD's Crimsonland API pointer
	clAPI_t*			cl;

	// MOD in/out parameters 
	struct parms_t
	{
		union
		{
			int					reserved[256];			// reserve plenty of space for future use
			struct
			{
				bool			drawMouseCursor;		// when enabled, Crimsonland engine draws mouse cursor for you
				bool			onPause;				// Crimsonland enables this when you should be on pause
			};
		};
	} parms;

	// this is called when the MOD is loaded and only once
	virtual bool		Init () = 0;
	// this is called when the MOD is unloaded and only once. Make sure all resourced allocated are freed here.
	virtual void		Shutdown () = 0;
	// this is called once each frame. int msecs is the time elapsed since the last frame.
	virtual bool		Frame (int msecs) = 0;
};




// extended key codes for mouse and joystick buttons
// note that these don't have anything to do with DirectInput
#define DIKE_MOUSE1		(0xff+1)
#define DIKE_MOUSE2		(0xff+2)
#define DIKE_MOUSE3		(0xff+3)
#define DIKE_MOUSE4		(0xff+4)
#define DIKE_MOUSE5		(0xff+5)

#define DIKE_MWHEELUP	(0xff+10)
#define DIKE_MWHEELDOWN	(0xff+11)

#define DIKE_JOY1		(0xff+32)
#define DIKE_JOY2		(0xff+33)
#define DIKE_JOY3		(0xff+34)
#define DIKE_JOY4		(0xff+35)
#define DIKE_JOY5		(0xff+36)
#define DIKE_JOY6		(0xff+37)
#define DIKE_JOY7		(0xff+38)
#define DIKE_JOY8		(0xff+39)
#define DIKE_JOY9		(0xff+40)

#define DIKE_JOY(x)		(0xff+31+x)

#define DIKE_JOYUP		(0xff+50)
#define DIKE_JOYDOWN	(0xff+51)
#define DIKE_JOYLEFT	(0xff+52)
#define DIKE_JOYRIGHT	(0xff+53)

#define DIKA_AXISX		(0xff+64)
#define DIKA_AXISY		(0xff+65)
#define DIKA_AXISZ		(0xff+66)

#define DIKA_AXISX2		(0xff+74)
#define DIKA_AXISY2		(0xff+75)
#define DIKA_AXISZ2		(0xff+76)

#define DIKA_ROTX		(0xff+84)
#define DIKA_ROTY		(0xff+85)
#define DIKA_ROTZ		(0xff+86)

#define DIKA_MOUSEXREL	(0xff+96)
#define DIKA_MOUSEYREL	(0xff+97)
#define DIKA_MOUSEXSTAT	(0xff+100)
#define DIKA_MOUSEYSTAT	(0xff+101)

#define DIKE_UNBOUND	(0xff+127)
#define DIKE_LAST		(0xff+128)


// Following key codes are ripped from Microsoft DirectX 8.1 SDK
/****************************************************************************
 *
 *      DirectInput keyboard scan codes
 *
 ****************************************************************************/
#define DIK_ESCAPE          0x01
#define DIK_1               0x02
#define DIK_2               0x03
#define DIK_3               0x04
#define DIK_4               0x05
#define DIK_5               0x06
#define DIK_6               0x07
#define DIK_7               0x08
#define DIK_8               0x09
#define DIK_9               0x0A
#define DIK_0               0x0B
#define DIK_MINUS           0x0C    /* - on main keyboard */
#define DIK_EQUALS          0x0D
#define DIK_BACK            0x0E    /* backspace */
#define DIK_TAB             0x0F
#define DIK_Q               0x10
#define DIK_W               0x11
#define DIK_E               0x12
#define DIK_R               0x13
#define DIK_T               0x14
#define DIK_Y               0x15
#define DIK_U               0x16
#define DIK_I               0x17
#define DIK_O               0x18
#define DIK_P               0x19
#define DIK_LBRACKET        0x1A
#define DIK_RBRACKET        0x1B
#define DIK_RETURN          0x1C    /* Enter on main keyboard */
#define DIK_LCONTROL        0x1D
#define DIK_A               0x1E
#define DIK_S               0x1F
#define DIK_D               0x20
#define DIK_F               0x21
#define DIK_G               0x22
#define DIK_H               0x23
#define DIK_J               0x24
#define DIK_K               0x25
#define DIK_L               0x26
#define DIK_SEMICOLON       0x27
#define DIK_APOSTROPHE      0x28
#define DIK_GRAVE           0x29    /* accent grave */
#define DIK_LSHIFT          0x2A
#define DIK_BACKSLASH       0x2B
#define DIK_Z               0x2C
#define DIK_X               0x2D
#define DIK_C               0x2E
#define DIK_V               0x2F
#define DIK_B               0x30
#define DIK_N               0x31
#define DIK_M               0x32
#define DIK_COMMA           0x33
#define DIK_PERIOD          0x34    /* . on main keyboard */
#define DIK_SLASH           0x35    /* / on main keyboard */
#define DIK_RSHIFT          0x36
#define DIK_MULTIPLY        0x37    /* * on numeric keypad */
#define DIK_LMENU           0x38    /* left Alt */
#define DIK_SPACE           0x39
#define DIK_CAPITAL         0x3A
#define DIK_F1              0x3B
#define DIK_F2              0x3C
#define DIK_F3              0x3D
#define DIK_F4              0x3E
#define DIK_F5              0x3F
#define DIK_F6              0x40
#define DIK_F7              0x41
#define DIK_F8              0x42
#define DIK_F9              0x43
#define DIK_F10             0x44
#define DIK_NUMLOCK         0x45
#define DIK_SCROLL          0x46    /* Scroll Lock */
#define DIK_NUMPAD7         0x47
#define DIK_NUMPAD8         0x48
#define DIK_NUMPAD9         0x49
#define DIK_SUBTRACT        0x4A    /* - on numeric keypad */
#define DIK_NUMPAD4         0x4B
#define DIK_NUMPAD5         0x4C
#define DIK_NUMPAD6         0x4D
#define DIK_ADD             0x4E    /* + on numeric keypad */
#define DIK_NUMPAD1         0x4F
#define DIK_NUMPAD2         0x50
#define DIK_NUMPAD3         0x51
#define DIK_NUMPAD0         0x52
#define DIK_DECIMAL         0x53    /* . on numeric keypad */
#define DIK_OEM_102         0x56    /* < > | on UK/Germany keyboards */
#define DIK_F11             0x57
#define DIK_F12             0x58
#define DIK_F13             0x64    /*                     (NEC PC98) */
#define DIK_F14             0x65    /*                     (NEC PC98) */
#define DIK_F15             0x66    /*                     (NEC PC98) */
#define DIK_KANA            0x70    /* (Japanese keyboard)            */
#define DIK_ABNT_C1         0x73    /* / ? on Portugese (Brazilian) keyboards */
#define DIK_CONVERT         0x79    /* (Japanese keyboard)            */
#define DIK_NOCONVERT       0x7B    /* (Japanese keyboard)            */
#define DIK_YEN             0x7D    /* (Japanese keyboard)            */
#define DIK_ABNT_C2         0x7E    /* Numpad . on Portugese (Brazilian) keyboards */
#define DIK_NUMPADEQUALS    0x8D    /* = on numeric keypad (NEC PC98) */
#define DIK_PREVTRACK       0x90    /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */
#define DIK_AT              0x91    /*                     (NEC PC98) */
#define DIK_COLON           0x92    /*                     (NEC PC98) */
#define DIK_UNDERLINE       0x93    /*                     (NEC PC98) */
#define DIK_KANJI           0x94    /* (Japanese keyboard)            */
#define DIK_STOP            0x95    /*                     (NEC PC98) */
#define DIK_AX              0x96    /*                     (Japan AX) */
#define DIK_UNLABELED       0x97    /*                        (J3100) */
#define DIK_NEXTTRACK       0x99    /* Next Track */
#define DIK_NUMPADENTER     0x9C    /* Enter on numeric keypad */
#define DIK_RCONTROL        0x9D
#define DIK_MUTE            0xA0    /* Mute */
#define DIK_CALCULATOR      0xA1    /* Calculator */
#define DIK_PLAYPAUSE       0xA2    /* Play / Pause */
#define DIK_MEDIASTOP       0xA4    /* Media Stop */
#define DIK_VOLUMEDOWN      0xAE    /* Volume - */
#define DIK_VOLUMEUP        0xB0    /* Volume + */
#define DIK_WEBHOME         0xB2    /* Web home */
#define DIK_NUMPADCOMMA     0xB3    /* , on numeric keypad (NEC PC98) */
#define DIK_DIVIDE          0xB5    /* / on numeric keypad */
#define DIK_SYSRQ           0xB7
#define DIK_RMENU           0xB8    /* right Alt */
#define DIK_PAUSE           0xC5    /* Pause */
#define DIK_HOME            0xC7    /* Home on arrow keypad */
#define DIK_UP              0xC8    /* UpArrow on arrow keypad */
#define DIK_PRIOR           0xC9    /* PgUp on arrow keypad */
#define DIK_LEFT            0xCB    /* LeftArrow on arrow keypad */
#define DIK_RIGHT           0xCD    /* RightArrow on arrow keypad */
#define DIK_END             0xCF    /* End on arrow keypad */
#define DIK_DOWN            0xD0    /* DownArrow on arrow keypad */
#define DIK_NEXT            0xD1    /* PgDn on arrow keypad */
#define DIK_INSERT          0xD2    /* Insert on arrow keypad */
#define DIK_DELETE          0xD3    /* Delete on arrow keypad */
#define DIK_LWIN            0xDB    /* Left Windows key */
#define DIK_RWIN            0xDC    /* Right Windows key */
#define DIK_APPS            0xDD    /* AppMenu key */
#define DIK_POWER           0xDE    /* System Power */
#define DIK_SLEEP           0xDF    /* System Sleep */
#define DIK_WAKE            0xE3    /* System Wake */
#define DIK_WEBSEARCH       0xE5    /* Web Search */
#define DIK_WEBFAVORITES    0xE6    /* Web Favorites */
#define DIK_WEBREFRESH      0xE7    /* Web Refresh */
#define DIK_WEBSTOP         0xE8    /* Web Stop */
#define DIK_WEBFORWARD      0xE9    /* Web Forward */
#define DIK_WEBBACK         0xEA    /* Web Back */
#define DIK_MYCOMPUTER      0xEB    /* My Computer */
#define DIK_MAIL            0xEC    /* Mail */
#define DIK_MEDIASELECT     0xED    /* Media Select */

/*
 *  Alternate names for keys, to facilitate transition from DOS.
 */
#define DIK_BACKSPACE       DIK_BACK            /* backspace */
#define DIK_NUMPADSTAR      DIK_MULTIPLY        /* * on numeric keypad */
#define DIK_LALT            DIK_LMENU           /* left Alt */
#define DIK_CAPSLOCK        DIK_CAPITAL         /* CapsLock */
#define DIK_NUMPADMINUS     DIK_SUBTRACT        /* - on numeric keypad */
#define DIK_NUMPADPLUS      DIK_ADD             /* + on numeric keypad */
#define DIK_NUMPADPERIOD    DIK_DECIMAL         /* . on numeric keypad */
#define DIK_NUMPADSLASH     DIK_DIVIDE          /* / on numeric keypad */
#define DIK_RALT            DIK_RMENU           /* right Alt */
#define DIK_UPARROW         DIK_UP              /* UpArrow on arrow keypad */
#define DIK_PGUP            DIK_PRIOR           /* PgUp on arrow keypad */
#define DIK_LEFTARROW       DIK_LEFT            /* LeftArrow on arrow keypad */
#define DIK_RIGHTARROW      DIK_RIGHT           /* RightArrow on arrow keypad */
#define DIK_DOWNARROW       DIK_DOWN            /* DownArrow on arrow keypad */
#define DIK_PGDN            DIK_NEXT            /* PgDn on arrow keypad */

/*
 *  Alternate names for keys originally not used on US keyboards.
 */
#define DIK_CIRCUMFLEX      DIK_PREVTRACK       /* Japanese keyboard */




#endif // CLMOD_H