#ifndef JESHADERdefs_H
#define JESHADERdefs_H

#include "jet.h"
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>



//basic defs
//none yet

//Shader Structures

// limits
#define JE_SHADER_MAX_ARGS    20 //20 max args. procTexture plasma CAN use ALL 20!!!

#define SHADER_FLAG(x) ((unsigned)1 << (x))

#define TYPE_SHADER			SHADER_FLAG(0)
#define TYPE_MP3SCRIPT		SHADER_FLAG(1)
#define TYPE_HYBRID			SHADER_FLAG(2)
#define TYPE_UNKNOWN		SHADER_FLAG(3)
#define TYPE_EXTENSION		SHADER_FLAG(4)

#define PROC_NONE			SHADER_FLAG(0)
#define PROC_PLASMA			SHADER_FLAG(1)
#define PROC_FIRE			SHADER_FLAG(2)
#define PROC_WATER_RIPPLE	SHADER_FLAG(3)
#define PROC_BUMPMAP		SHADER_FLAG(4)
#define PROC_ELECTRIC		SHADER_FLAG(5)


// global flags (note not all of these are used... yet)
#define SH_SKYGEN            SHADER_FLAG( 0)
#define SH_NEAR_BOX          SHADER_FLAG( 1)
#define SH_FAR_BOX           SHADER_FLAG( 2)
#define SH_CULL              SHADER_FLAG( 3)
#define SH_FOGPARMS          SHADER_FLAG( 4)
#define SH_NOPICMIP          SHADER_FLAG( 5)
#define SH_NOMIPMAPS         SHADER_FLAG( 6)
#define SH_POLYGON_OFFSET    SHADER_FLAG( 7)
#define SH_ENTITY_MERGABLE   SHADER_FLAG( 8)
#define SH_EXPLICIT_SKYGEN   SHADER_FLAG( 9)
#define SH_EXPLICIT_CULL     SHADER_FLAG(10)
#define SH_EXPLICIT_NOPICMIP SHADER_FLAG(11)
#define SH_EXPLICIT_PORTAL   SHADER_FLAG(12)
#define SH_EXPLICIT_SORT     SHADER_FLAG(13)



// stage flags
#define SH_STAGE_MAP_NEEDS_ALPHA     SHADER_FLAG( 0)
#define SH_STAGE_BLENDFUNC           SHADER_FLAG( 1)
#define SH_STAGE_DEPTHWRITE          SHADER_FLAG( 2)
#define SH_STAGE_DETAIL              SHADER_FLAG( 3)
#define SH_STAGE_ALPHAFUNC           SHADER_FLAG( 4)
#define SH_STAGE_EXPLICIT_BLENDFUNC  SHADER_FLAG( 5)
#define SH_STAGE_EXPLICIT_TCGEN      SHADER_FLAG( 6)
#define SH_STAGE_EXPLICIT_RGBGEN     SHADER_FLAG( 7)
#define SH_STAGE_EXPLICIT_ALPHAGEN   SHADER_FLAG( 8)
#define SH_STAGE_EXPLICIT_DEPTHFUNC  SHADER_FLAG( 9)
#define SH_STAGE_EXPLICIT_DEPTHWRITE SHADER_FLAG(10)

#define SH_STAGE_FILTER_EXT          SHADER_FLAG(11)

// map flags
#define SH_MAP_CLAMPMAP         SHADER_FLAG(0)
#define SH_MAP_ALPHA            SHADER_FLAG(1)
#define SH_MAP_PICMIP           SHADER_FLAG(2)
#define SH_MAP_MIPMAPS          SHADER_FLAG(3)

#define SH_MAP_SOLID_SKY_EXT	SHADER_FLAG(4) //work with a solid sky texture
#define SH_MAP_ALPHA_SKY_EXT	SHADER_FLAG(5) //or with 2(+) textures with alpha fx

// wave
enum {
   SH_WAVE_SIN,
   SH_WAVE_TRIANGLE,
   SH_WAVE_SQUARE,
   SH_WAVE_SAWTOOTH,
   SH_WAVE_INVSAWTOOTH,
   SH_WAVE_NOISE
};

// cull
enum {
   SH_CULL_FRONT,
   SH_CULL_BACK,
   SH_CULL_DISABLE,
   SH_CULL_BOTH_EXT,
};

// deformVertexes
enum {
   SH_VXMOD_WAVE,
   SH_VXMOD_NORMAL,
   SH_VXMOD_BULGE,
   SH_VXMOD_MOVE,
   SH_VXMOD_AUTOSPRITE,
   SH_VXMOD_AUTOSPRITE2,
   SH_VXMOD_PROJECTION_SHADOW,
   SH_VXMOD_TEXT0,
   SH_VXMOD_TEXT1,
   SH_VXMOD_STENCIL_SHADOW_EXT,
};

// sort
enum {
   SH_SORT_UNDEFINED      = 0,
   SH_SORT_PORTAL         = 1,
   SH_SORT_SKY            = 2,  // default for skyParms
   SH_SORT_OPAQUE         = 3,  // default with no blendFunc or alphaFunc
   SH_SORT_DECAL          = 4,  // default for polygonOffset (undocumented)
   SH_SORT_DECAL2         = 5,
   SH_SORT_BANNER         = 6,
   SH_SORT_SEE_THROUGH    = 7,  // default for alphaFunc (undocumented)
   SH_SORT_UNDERWATER     = 8,
   SH_SORT_ADDITIVE       = 9,  // default for blendFunc
   SH_SORT_ADDITIVE1      = 10,
   SH_SORT_ADDITIVE2      = 11,
   SH_SORT_FOG            = 12, // (undocumented)
   SH_SORT_FOG1           = 13,
   SH_SORT_FOG2           = 14,
   SH_SORT_STENCIL_SHADOW = 15, // (undocumented)
   SH_SORT_NEAREST        = 16,
   SH_SORT_NUM_SORTS
};

// tcGen
enum {
   SH_TCGEN_BASE,
   SH_TCGEN_LIGHTMAP,
   SH_TCGEN_ENVIRONMENT,
   SH_TCGEN_VECTOR,

   SH_TCGEN_SKY_EXT,
};

// tcMod
enum {
   SH_TCMOD_ROTATE,
   SH_TCMOD_SCALE,
   SH_TCMOD_SCROLL,
   SH_TCMOD_STRETCH,
   SH_TCMOD_TRANSFORM,
   SH_TCMOD_TURB,
};

// rgbGen and alphaGen
enum {
   SH_RGBAGEN_IDENTITY_LIGHTING,
   SH_RGBAGEN_IDENTITY,
   SH_RGBAGEN_WAVE,
   SH_RGBAGEN_ENTITY,
   SH_RGBAGEN_ONE_MINUS_ENTITY,
   SH_RGBAGEN_VERTEX,
   SH_RGBAGEN_ONE_MINUS_VERTEX,
   SH_RGBAGEN_PORTAL,
   SH_RGBAGEN_LIGHTING_DIFFUSE,
   SH_RGBAGEN_LIGHTING_SPECULAR,
   SH_RGBAGEN_CONST_EXT,
   SH_RGBAGEN_ONE_MINUS_PORTAL_EXT,

};

// blendFunc
enum {
   SH_BLEND_UNDEFINED,
   SH_BLEND_ONE,
   SH_BLEND_ZERO,
   SH_BLEND_DST_COLOR,
   SH_BLEND_ONE_MINUS_DST_COLOR,
   SH_BLEND_SRC_ALPHA,
   SH_BLEND_ONE_MINUS_SRC_ALPHA,
   SH_BLEND_DST_ALPHA,
   SH_BLEND_ONE_MINUS_DST_ALPHA,
   SH_BLEND_SRC_COLOR,
   SH_BLEND_ONE_MINUS_SRC_COLOR,
};

// depthFunc
enum {
   SH_DEPTHFUNC_LEQUAL,
   SH_DEPTHFUNC_EQUAL,
};

// alphaFunc
enum {
   SH_ALPHAFUNC_GT0,
   SH_ALPHAFUNC_LT128,
   SH_ALPHAFUNC_GE128,
};

// _filter
enum {
   SH_FILTER_NEAREST,
   SH_FILTER_LINEAR,
   SH_FILTER_NEAREST_MIPMAP_NEAREST,
   SH_FILTER_NEAREST_MIPMAP_LINEAR,
   SH_FILTER_LINEAR_MIPMAP_NEAREST,
   SH_FILTER_LINEAR_MIPMAP_LINEAR
};

/***************************************************************************\

parsing and compilation

\***************************************************************************/

#include "jeShaderInfo.h"


void  jeShader_AllocKeep(void);

void      jeShader_BeginScan(shader_info_t *info);
JE_SHADER_TOKEN jeShader_Scan(shader_info_t *info);
void      jeShader_EndScan(shader_info_t *info);
jeBoolean      jeShader_Skip(shader_info_t *info);


typedef jeBoolean   (*jeShader_ApproveFunc_t)(const char* name);
typedef void   (*jeShader_CompileFunc_t)(shader_t* shader);

size_t jeShader_Parse(jeShader_CompileFunc_t compile, jeShader_ApproveFunc_t approve, shader_info_t *info);
void   jeShader_Parse_stop(shader_info_t *info);


void shader_number_parse(const char* string, sh_num_t* number);


typedef int (*jeShader_Input_func_t)(void);

int             jeShader_Input();
void            jeShader_InputUnget(int cin, shader_info_t *info);
int             jeShader_Input_string_func(void);
void            jeShader_Input_set_string(const char* string, size_t size);
jeBoolean		jeShader_Input_load_string(const char* filename, char* text, size_t* size);

//int             jeShader_Input_file_func(shader_info_t *info);
int jeShader_GetInput(shader_info_t *info);

jeBoolean		jeShader_SetInput(FILE* file, shader_info_t *info);


//memory stuffs

typedef shader_t* (*sh_alloc_func_t)(void);

shader_t*       sh_alloc(void);
sh_alloc_func_t sh_alloc_set_func(sh_alloc_func_t m);
shader_t*       sh_alloc_static_func(void);
shader_t*       sh_alloc_array_func(void);
shader_t*       sh_alloc_set_array(shader_t* array, size_t elements);



//inline functions and macros
#include "inline.h"

#endif
