/*		
 *		GRAMophone II, a grammar based algorithmic musical composition tool
 *		-------------------------------------------------------------------
 *
 *		global.h
 *
 *		Copyright (c) 2007, Giovanni Ferranti <giovanni@giovanniferranti.it>
 *
 * 		GRAMophone II is free software; you can redistribute it and/or modify
 * 		it under the terms of the GNU General Public License as published by
 * 		the Free Software Foundation; either version 2 of the License, or
 * 		(at your option) any later version.
 *
 * 		This program is distributed in the hope that it will be useful,
 * 		but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * 		GNU Library General Public License for more details.
 *
 *		You should have received a copy of the GNU General Public License along
 *		with this program; if not, write to the Free Software Foundation, Inc.,
 *		51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *		-------------------------------------------------------------------
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "midifile.h"

#define	VERSION				"0.8.13a"
#define DEFAULT_FILENAME	"composition.mid"
#define MAX_FILENAME_LENGTH	256
#define MAX_ITERATIONS		50000	//numero massimo di iterazioni
#define	MAX_STR				4096
#define NUM_GLOBAL_PARAMS	7
#define NUM_LOCAL_PARAMS	6
#define NUM_VARS			1024	//numero massimo di variabili, sia globali
									//sia locali
#define NUM_PLAYERS			128		//numero massimo di players
#define NUM_CTRL			22
#define VAR_LENGTH			31
#define NUM_MACRO			65536
#define NUM_PRODS			1024
#define DIM_EXP				512
#define	DIM_MIDI_CODE		1024
#define MAX_RECURSION		50
#define DIM_BUFFER			10240
#define MAX_CHORD			50
#define DIM_RTGD_BUFFER		256

/* 
 * TEMP VARS
 */

char string_buf[MAX_STR], idTemp[MAX_STR];
unsigned int note[5], rest;
unsigned int chord[MAX_CHORD][5];

/*
 * WORK VARS
 */

unsigned char isGlobal, globalWritten;
unsigned int varCount, macroCount, playerCount, prev_duration, stringCount, level;

/*
 * COMMAND LINE OPT
 */

FILE *midi;
char namefile[MAX_FILENAME_LENGTH];
unsigned char checkOption, debugOption;

/*
 * MIDI DATA
 */

char data[4];

/*
 * DATA STRUCTURES
 */

unsigned int global_resolution, global_iterations;
unsigned char grammarOption; //1 - Chomsky; 2 - Lindenmayer
char *strings[MAX_STR];
enum var_type {OCT=1, VEL, DUR, REL, BYTEDATA};

enum default_prm {DEFOCT, DEFVEL, DEFDUR, DEFREL, DEFINSTR, CHN, DEFMSB};

unsigned int global_params[NUM_GLOBAL_PARAMS];
			//0 - Octave; 1 - Velocity
			//2 - Duration; 3 - Release
			//4 - Instrument; 5 - Channel;
			//6 - Msb

unsigned char loc_par_flag[10]; 
			//0 - grammar
			//1 - iterations
			//2 - time signature
			//3 - octave
			//4 - velocity
			//5 - duration
			//6 - release
			//7 - msb
			//8 - instrument
			//9 - channel

//GrammyVM ASM

enum GrammyAsm {_ADD=1, _SUB, _MUL, _DIV, _MOD, _INC, _DEC, _OR, _AND, _NOT, _EQ, 
				_NE, _LT, _LE, _GT, _GE, _SP, _PRD, _PRD_ALT, _CHK, _ELSE, _GOTO, _EXP, _UPDATE,
				_ENDEXP, _MOV, _NOTEON, _REST, _EMPTY, _TRN, _INV, _RTRGD, _RTGINV, 
		 		_RND, _ENDMELOP, _REP, _ENDREP, _CHORD, _ENDCHORD, _UMIN, _PRNT, _STR};

//Errors

enum error_msg {UNTERMINATED_STR, EOF_ERR, TOO_DEEPLY, DISCOGRAPHY_NOT_FOUND,
				EXPECTED, MEMORY_ERR, ALREADY, GRAMMAR_EXPECTED, RES_OUT,
				IT_OUT, OUT, NUMERATOR_OUT, FRACTION_DEN_ERR, OCTAVE_OUT,
				TEMPO_OUT, PLAYER_EXPECTED, VAR_NOT_DECLARED, TOO_LONG,
				CHN_OUT, TOO_MANY_PLAYERS, TOO_MANY_VARS, TYPE_ERR,
				TOO_MANY_MACROS, TOO_MANY_NOTE_PAR, REPEAT_ERR, SILENT_ERR,
				TOO_MANY_STRINGS, ELSE_WITHOUT_CONDITION};

unsigned char glob_num, glob_den;
char *title, *copyright; 
unsigned int tempo;

typedef struct note_vars_value *pnote_var;

typedef struct note_vars_value {
  char *name;
  unsigned char type;
  unsigned int value;
} note_var;

note_var global_vars[NUM_VARS];

typedef struct Expression *pExp;

typedef struct Expression {	
  unsigned int expcode[DIM_EXP][5];
} expression;

typedef struct grammarProduction *pProd;

typedef struct grammarProduction {
  char name[VAR_LENGTH];	
  unsigned int ec; //Expression Counter
  unsigned int cc; //Code Counter
  unsigned int numOr;
  unsigned int numOrAlt;  
  unsigned char terminal;
  unsigned int idTerminal;
  pExp exp;
  unsigned int midicode[DIM_MIDI_CODE][10];
  unsigned char created_by_body;
  unsigned int iterationCounter;
  unsigned char visited;
} production;

typedef struct virtual_player *pPlayer;

typedef struct virtual_player {
  char *identifier;
  int local_params[NUM_LOCAL_PARAMS];
  unsigned char num, den;
  unsigned char grammar;
  unsigned int iterations;
  note_var local_vars[NUM_VARS];
  pProd productions[NUM_PRODS];
} player;

pPlayer players[NUM_PLAYERS];

typedef struct macro_data *pmacro;

typedef struct macro_data {
  char *name, *data;
} macro;

macro macros[NUM_MACRO];
