/*
   CMSC 427 - Term Project Candidate
   ---------------------------------

   Beth Weinstein - bweinste@wam.umd.edu
   Ben Stewart - stewartb@wam.umd.edu
   Nawfel Tricha - Topaz@endorproductions.com

   Minimal OpenGL project using Microsoft Visual C++.
   This project is a premilinary candidate for the term 
   project required by CMSC 427.

   ABSTRACT:
      In this project, we will develop several fast 
      rendering and collision routines which would 
      require C/C++ speed and accuracy and then 
      implement a VisualJ++ interface.

   MODULE:
      Global declaration header.
*/

#ifndef GLOBAL_H
#define GLOBAL_H

#include "stdafx.h"
#include <stdlib.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdio.h>
#include "vis.h"
#include "Utils.h"
#include "IO_Md2.h"


// NT:
// Spectrum:
   typedef struct dsp_s
      {
      float bass, kick, mid, high, volume;
      int tick;
      } dsp_t;


// NT: 
// Definition of a skin.
// Global index of the skin in the global array.
// Height/width, Dimensions of the original skin, from TGA, not in OpenGL.
// tga: Used temporarly to load TGA file in this pointer.
// glTexture: Actual OpenGL texture pointer.
   typedef struct skin_s
      {
      unsigned int  index;          // Skin number
      int           height, width;  // Width, Height
      unsigned char *tga;           // Buffer to skin (when loaded)
      GLubyte       *glTexture;     // Texture buffer
      } skin_t;

// NT: 
// Skin list.
// skin_name: Name of the skin (file name associated with the skin).
// used: True if the current skin is being used.
// skin: skin data.
   typedef struct skin_list_s
      {  
      char *skin_name;
      char used;
      skin_t *skin;
      } skin_list_t;

// NT: 
// Triangle definition.
// a, b, c: 3 CCW non-coolinear vertices in triangle
// a_s, a_t: skin coordinate (x.s, y.t) for first vertex
// b_s, b_t: skin coordinate (x.s, y.t) for second vertex
// c_s, c_t: skin coordinate (x.s, y.t) for third vertex
// normal: normal of triangle
typedef struct triangle_s
   {
   vec3_t   a, b, c;
	float a_s, a_t, b_s, b_t, c_s, c_t;
   vec3_t normal;
   } triangle_t;

// NT: 
// Definition of a model.
// num_triangles: number of triangles in the model
// tri: triangle list
// skin_index: index of skin in model
typedef struct mdl_s
   {
   int            num_triangles;
   triangle_t     *tri;
   int            skin_index;
   } mdl_t;

// NT: 
// Model list:
// model_name: Name of the model (file name associated with the model).
// used: True if the current model is being used.
// model: model data.
typedef struct model_list_s
   {
   char *model_name;
   char used;
   mdl_t *model;
   } model_list_t;


// NT: 
// CMD2 Alias model list:
// model_name: Name of the model (file name associated with the model).
// used: True if the current model is being used.
// model: model data.
typedef struct CMD2_list_s
   {
   char *model_name;
   char used;
   CMD2 *model;
   } CMD2_list_t;

// NT:
// Current frame structure in model parts. [Not needed for this project]
// frame: frame number
// final_angle: final interpolated angle of the frame
// delta_angle: angle change speed
// rotation: rotation of the frame
// translation: translation of the frame
// next: next frame in the part action
   typedef struct pose_s
      {
      int frame;
      vec3_t final_angle;
      vec3_t delta_angle;
      vec3_t rotation;
      vec3_t translation;
      struct pose_s *next;
      } pose_t;

// NT:
// This is the part of the model that represent a node in the model 
// hierarchy.
// taken: true = part is in use
// tag_name: part name (leg, torso, etc)
// model_index: index (from model list) of the model it represents
// skin_index: index of the skin the model is using
// mat[16]: soft skeletal rendering matrix (not used in this project)
// son: son of the part (finger to an arm, arm to torso, etc)
// father: father of the part
// brother: brother of the part (mutual transforms)
// action: reserved
// current_pose: reserved
// origin: origin of the part relative to father
// angle: angles of the part relative to father
// tilt: tilt of the part, relative to world
// max_angle: maximum angles the joint of the part can acquire
// min_angle: minimum angles the joint of the part can acquire
// delta_angle: flexibility of the joint, rotation speed 
// We will set delta angles for sound response in our Winamp plugin.
// Parts with higher delta_angles will respond more to sound.
   typedef struct part_s
      {
      bool taken;
      char *tag_name;
      int model_index;
      int skin_index;
      float mat[16];
      struct part_s *son[G_MAX_SONS];
      struct part_s *father;
      struct part_s *brother;
      pose_t *action[G_MAX_ACTIONS];
      pose_t *current_pose;
      vec3_t origin;
      vec3_t angle;
      vec3_t tilt;
      vec3_t max_angle;
      vec3_t min_angle;
      vec3_t delta_angle;
      } part_t;

// NT:
// Main object structure.
// Every single entity uses an edict_s in our program.
// taken: true if the edict is being used
// state: different states of edict. (see ENT_ST_ definitions)
// skin_num: skin number
// skin_index: skin index
// body: pointer to model structure
// model: pointer to Alias animated MD2 model structure
// rgba: RGB + ALPHA of rendered entity
// origin: origin of the entity
// angle: orientation of the entity
// velocity: used by physics engine, velocity of entity
// avelocity: rotational/angular velocity of the entity
// mass: used by physics engine (mass of entity)
// scale: scale of entity when rendered
// acceleration: velocity acceleration/deceleration
// speed: entity speed
// next_think: time before entity think function is called (in msec)
// die: time before the entity vanished and is returned to the system (in msec)
// *think: think function of the entity, called directly by the engine.
// *render: render function of the entity, called directly by the engine.
// *camera: camera function of the world, called directly by the engine.
// destination: target destination vector of the entity
// idata: array of free interger variables
// fdata: array of free float variables
   typedef struct edict_s
      {
      bool           taken;
      int            state;
      unsigned int   skin_num;
      unsigned int   skin_index;
      part_t         *body;
      CMD2           *model;
      float          rgba[4];
      vec3_t         origin, angle,
                     velocity, avelocity,
                     destination;
      float          mass, scale;
      float          acceleration, speed;
      DWORD          next_think, die;
      int            frame, end_frame, loop_frame, next_frame;
      int            idata[4];
      float          fdata[4];
      void		      (*think)(struct edict_s *self);
      void		      (*render)(struct edict_s *self);
      void		      (*camera)(struct edict_s *self);
      void		      (*reached)(struct edict_s *self);
      void		      (*listen)(struct edict_s *self, struct winampVisModule *this_mod);
      } edict_t;

// NT: Engine structure:
// num_edicts: Current number of entities used by the engine.
// num_skins: Current number of skins used by the engine.
// num_models: Current number of models used by the engine.
// num_parts: Current number of parts used by the engine.
// time: Current time of the engine since the program started, in milliseconds. 
// next_stanza: time lapse before we go into next stanza. 
// stanza: rhyme/pattern of engine narative.
   typedef struct engine_s
      {
      int num_edicts,
          num_tedicts,
          num_skins, 
          num_models,
          num_CMD2s,
          num_parts;

      int skin_index;
      DWORD time, next_stanza;
      int stanza;
      float interpolation;
      } engine_t;

// NT: Camera structure:
// Has origin, angle (aim), forward, right, and up vectors.
// Mass: Used by the physics engine to determin if the camera falls to the ground, etc.
// RGB_Filter: Transparent RGB slide that goes over the lens.
// target: target of camera. targets have total control of camera.
   typedef struct camera_s
      {
      vec3_t origin,
             angle,
             forward,
             right,
             up;
      float  mass;
      vec3_t RGB_filter;
      edict_t *target;
      } camera_t;


// SYSTEM:
   // NT: Display error in module and exit to OS.
   void EngineError(char *format, ...);
   // NT: Display warning in module and ask for retry.
   void EngineWarning(char *format, ...);


// RENDERING MODULE:
   #define  RENDER_CONSOLE                1     // Render Console
   #define  RENDER_BETH_ENGINE            2     // Render Beth engine
   #define  RENDER_BEN_ENGINE             4     // Render Ben engine
   #define  RENDER_NAWFEL_ENGINE          8     // Render Nawfel engine
   #define  RENDER_FLUSH_ENGINE          16     // Render Flush engine
   #define  RENDER_CLEAR_ACC             32     // Clear color buffer
   #define  RENDER_HUD                   64     // Render Head Up display
   #define  RENDER_HELP                 128     // Render help
   #define  RENDER_DSP_LIGHT            256     // Render DSP light to hole scene

   #define  EFFECT_FLOWERS                1     // Throw flowers around 
   #define  EFFECT_SPECTRUM               2     // Render spectrum
   #define  EFFECT_FREQUENCY              4     // Render srequency
   #define  EFFECT_BASS_SCALE             8     // Render bass scale
   #define  EFFECT_CONSOLE               16     // Render background

   // Link OpenGL rendering to our application window:
      VOID EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
   // Shut down OpenGL rendering:
      VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC );
   // Render a single frame:
      void RenderFrame(struct winampVisModule *this_mod);
   // Initialize OpenGL:
      void InitGL();


// NT: Skin library:
   // Create a new skin, and return the index to it:
   int SkinSpawn(char *skin_name, skin_t *skin);
   // Return the index of a skin if it exists, otherwise, return NOT_FOUND:
   int SkinIndex(char *skin_name);

// NT: PART MODULE:
   // Spawn next available part in list, initialize, and return pointer:
   part_t *PartSpawn();
   // Return part to list for future use:
   void PartFree(part_t **p);
   // Spawn new action in part:
   pose_t *ActionSpawn();
   // Add action frame to model:
   void FrameAdd(part_t *part, int i_action, vec3_t i_final_angle,
                 vec3_t i_rotation, vec3_t i_translation);
   // Rewind action to start frame:
   void FrameInit(part_t *part, int i_action);
   // Interpolate current frame:
   void FrameInterpolate(part_t *part);
   // Return part containing the specified string:
   part_t *PartTag(char *tag_string);
   // Set son of specified part:
   void PartSetSon(part_t *p, part_t *s);
   // Set father of specified part:
   void PartSetFather (char *tag_name, char *father);
   // Set brother of specifed part:
   void PartSetBrother (char *tag_name, char *brother);
   // Return number of action for a certain part:
   int PartActions(part_t *p);
   // Return number of frames in a certain action in specified part:
   int PartActionFrames(part_t *p, int action_index);

// NT: Alias MODEL MODULE:
   // Spawn next model in list, initialize, and return index.
   int ModelSpawn(char *model_name, mdl_t *model);
   // Return index of model in list, or NOT_FOUND.
   int ModelExist(char *model_name);
   // Render a hierarchical model part:
   void RenderPart(edict_t *ent, part_t *p);
   // Render interpolated/animated alias model:
   void RenderAliasModel(edict_t *self);
   // Spawn next model in list, initialize, and return index.
   int CMD2Spawn(char *model_name, CMD2 *model);
   // Return index of model in list, or NOT_FOUND.
   int CMD2Exist(char *model_name);
   // Update texture coordinates for model:
   void UpdateTextureCoordinates(CMD2 *mdl, skin_t *skin);
   // Render black shadow:
   void RenderAliasShadow(edict_t *self);

// NT: ENTITY MODULE:
   #define ENT_ST_USED        0x01
   #define ENT_ST_VISIBLE     0x02
   #define ENT_ST_CONTACT     0x04
   #define ENT_ST_PHYS        0x08
   #define ENT_ST_ORTHO       0x10
   #define ENT_ST_MOVING      0x20
   // Spawn a new edict:
   edict_t *EdictSpawn();
   // Free exisiting edict (ent <- null):
   void EdictFree(edict_t *ent);
   // Spawn a new edict:
   edict_t *tEdictSpawn();
   // Free exisiting edict (ent <- null):
   void tEdictFree(edict_t *ent);
   // Aplly gravity to all edicts:
   void ApplyGravity();
   // Run critical frame for all edicts (Physics):
   void CriticalFrame();
   // Run think frame for all edicts (User defined think functions):
   void RunFrame();
   // Draw all entities in the world:
   void DrawEdicts();
   // Draw all transparent entities in the world:
   void DrawtEdicts();
   // RunEdict - Set edict into moving position:
   void RunEdict(edict_t *);

// NT: TARGA FILE MODULE:
   #define TGA_PROGRESSIVE_BLEND       -1
   #define TGA_ABSOLUTE_BLEND          -2
   // NT: Load Targa, return 0 if no success:
   int LoadTGA (char *pathname, unsigned char **targa_rgba, int &x_out, int &y_out);
   void TGA2GLTexture (skin_s *s, int gamma, int alpha, int &xi, int &yi);

// NT: LUXOR FILE MODULE:
   // NT: Read Luxor file format into entity.
   int LuxorRead(char *filename, edict_t *ent);

// NT: FONT MODULE:
   // Load a TGA font file:
   void LoadFont(char *filename);
   // Print string using texture mapping:
   void FontPrint (float *t_origin, char *ptr, float zoom = 1);
   // Variable font printing, same as FontPrint, but with variable parameters
   void FontPrintv(float *origin, char *format, ...);
   // Display the Console (background):
   void DisplayConsole(float scale);
   // Display the Head up display:
   void DisplayHUD (float scale);
   // Display the help screen:
   void DisplayHELP();

// NT: SOFT MODULES:
   // Spawn a fire fly:
   edict_t *FireFlySpawn(vec3_t origin, float velocity, vec3_t rgba, float alpha);
   // Spawn a Ginny:
   edict_t *GinnySpawn();
   // Spawn a Zumlin:
   edict_t *ZumlinSpawn();
   // Spawn a Ninja:
   edict_t *NinjaSpawn();
   // Spawn a Martian:
   edict_t *MartianSpawn();
   // BS: Spawn a BobaFett
   edict_t *BobaFettSpawn();
   // BS: Spawn a Chun Li
   edict_t *ChunLiSpawn();
   // BS: Spawn a Sling Shot Transformer
   edict_t *SlingShotSpawn();
   // BS: Spawn a Snork
   edict_t *SnorkSpawn();
   // Spawn a Table
   edict_t *TableSpawn();
   // Spawn a Speaker
   edict_t *SpeakerSpawn();
   // Spawn a Frame
   edict_t *FrameSpawn();
   // Spawn a Chair
   edict_t *ChairSpawn();
   // Spawn Hatch 
   edict_t *HatchSpawn();
   // Spawn Jupiter 
   edict_t *JupiterSpawn();

// BS: a data structure I use to animate my soft models
   // num_moves: the number of moves a model has
   // curr_move: current move
   // moves: IDs for each move
   // move_begin_frames: start frames for each move
   // move_mid_frames:   midpoint frames for each move
   // move_end_frames:   end frames for each move
   // camera_spin_delta: how fast the camera spins around the model
   // camera_spin_axis:  the axis to spin the camera around
   // displacement_factor: how close/far the camera is to the character
   // displacement:		   vector to displace camera along
   // camera_start:		   starting position for camera before displacement
   // m_start:			   the location to place the model when its spawned
   #define MAX_MOVES 10
	typedef struct m_data_s
	{
		unsigned int num_moves;
		unsigned int curr_move;
		unsigned char moves[MAX_MOVES];
		unsigned int  move_begin_frames[MAX_MOVES];
		unsigned int  move_mid_frames[MAX_MOVES];
		unsigned int  move_end_frames[MAX_MOVES];
		float  camera_spin_delta;
		vec3_t cam_spin_axis;
		float displacement_factor;
		float displacement_delta;
		vec3_t displacement;
		vec3_t camera_start;
		vec3_t m_start;
	} m_data_t;




// NT: ENGINE BRANCHES:
   // Beth Engine:
   void BethInit();
   void BethStanza(int stanza);
   void BethMain(struct winampVisModule *this_mod);
   void BethShutdown();
   // Ben Engine:
   void BenInit();
   void BenStanza(int stanza);
   void BenMain(struct winampVisModule *this_mod);
   void BenShutdown();
   // Nawfel Engine:
   void NawfelInit();
   void NawfelStanza(int stanza);
   void NawfelMain(struct winampVisModule *this_mod);
   void NawfelShutdown();
   // Common (Flush) Engine:
   void FlushInit();
   void FlushStanza(int stanza);
   void FlushMain(struct winampVisModule *this_mod);
   void FlushShutdown();

// NT: DSP FORMAT:
   #define DSP_SPECTRUM_BASS     1
   #define DSP_SPECTRUM_KICK     2
   #define DSP_SPECTRUM_400Hz    3
   #define DSP_SPECTRUM_2Khz     4
   #define DSP_SPECTRUM_6Khz     5
   #define DSP_SPECTRUM_10Khz    6
   #define DSP_SPECTRUM_14Khz    7
   #define DSP_SPECTRUM_20Khz    8
   #define DSP_SPECTRUM_VOLUME   9
   // NT: Return scalar of the current DSP input:      
   float DSPGetBass(struct winampVisModule *this_mod, int format);
   // NT: Render spectrum at origin:      
   void DSPRenderSpectrum(vec3_t origin, struct winampVisModule *this_mod);
   // NT: Render frequency at origin:      
   void DSPRenderFrequency(vec3_t origin, struct winampVisModule *this_mod);

// NT: Global variables:
   // Rendering mode:
      extern int r_mode;
   // Reserved
      extern int r_gravity;
   // Reserved
      extern int r_color_run;
   // Rendering effect:
      extern int r_effect;
   // Skin list [library]:
      extern skin_list_t *g_skins[G_MAX_SKINS];
   // Part List [Library]:
      extern part_t g_parts[G_MAX_PARTS];
   // Model List [Library]:
      extern model_list_t *g_models[G_MAX_MODELS];
   // CMD2 List [Library]:
      extern CMD2_list_t *g_CMD2s[G_MAX_CMD2S];
   // Edict list [library]:
      extern edict_t g_edicts[G_MAX_EDICTS];
   // Transparent Edict list [library]:
      extern edict_t g_tedicts[G_MAX_EDICTS];
   // Engine variables:
      extern engine_t eng;
   // Camera variables:
      extern camera_t cam;
   // Last part used:
      extern part_t *last_part;
   // Last texture used:
      extern unsigned int last_texture;
   // DSP spectrum:
      extern dsp_t dsp;

#endif


