/*
  MidiSynth, A MIDI synthesiser, a repacement for the Acorn MIDI module

  main.h - Common declarations and definitions

  created  19/01/10
  1.0      14/06/14
*/

#ifndef main_h
#define main_h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "kernel.h"
#include "swis.h"
#include "wimp.h"
#include "midi_spec.h"
#include "midi.h"
#include "instrument.h"

#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
#endif

#ifndef NULL
#define NULL 0
#endif

#define LIMIT(lo,x,hi) \
  if((x) < (lo)) (x) = (lo); \
  else if((x) > (hi)) (x) = (hi)

// General numeric constants
#define PI     3.1415926535897932384626433832795
#define LN2    0.69314718055994530941723212145818
#define LN10   2.3025850929940456840179914546844

// Saturates 'x' to 'lo' or 'hi'
#define LIMIT(lo,x,hi) \
  if((x) < (lo)) (x) = (lo); \
  else if((x) > (hi)) (x) = (hi)

//#define TEST // define to enable the test window

typedef unsigned long long int Uint64;
typedef signed long long int Int64;

// error return values, negative where used, eg. return -PARAMETER_ERROR
enum err_msg_e
{
  NO_ERROR_, // must be first
  CANNOT_OPEN_TEMPLATES_FILE,
  MAIN_TEMPLATE_NOT_FOUND,
  INFO_TEMPLATE_NOT_FOUND,
  TEST_TEMPLATE_NOT_FOUND,
  PARAMETER_ERROR,
  OUT_OF_RANGE,
  NO_HEADER,
  INVALID_HEADER_LENGTH,
  UNSUPPORTED_FORMAT,
  INVALID_NUMBER_OF_TRACKS,
  FILE_TOO_LARGE,
  PROBLEM_READING_FILE,
  INCOMPLETE,
  PROBLEM_OPENING_FILE,
  NO_FILE_LOADED,
  CANNOT_ALLOCATE_MEMORY,
  INVALID_DATA,
  INVALID_SIZE,
  INVALID_CRC,
  INPUT_OPEN_PROBLEM,
  OUTPUT_OPEN_PROBLEM,
  NO_ROOM_ON_DISC,
  CANNOT_OVERWRITE_DIR,
  FILE_EXISTS,
  CANNOT_OVERWRITE_IMAGE,
  NOT_A_CHOICES_FILE,
  FILE_OVER_2GB,
  INVALID_SAMPLE_RATE,
  INVALID_BITRATE
};

// windows
enum { WIN_MAIN,
       WIN_INFO,
#ifdef TEST
       WIN_TEST,
#endif
       WIN_MAX };

// menus
enum { MENU_ICONBAR,
       MENU_OPTIONS,
       MENU_MAX };

// main window icons
#define ICON_TEXT1       2
#define ICON_TEXT2       3
#define ICON_TEXT3       4
#define ICON_TEXT4       5
#define ICON_TEXT5       6
#define ICON_FILENAME    8
#define ICON_INFO1       9
#define ICON_INFO2      10
#define ICON_INFO3      11
#define ICON_INFO4      12
#define ICON_INFO5      13
#define ICON_OPTION1    14
#define ICON_OPTION2    15
#define ICON_OPTION3    16
#define ICON_OPTION4    17
#define ICON_SAVE_WAV   18
#define ICON_SAVE_MP3   19
#define ICON_SAVE_TEXT  20
#define ICON_BAR_BACK   21
#define ICON_BAR_VALUE  22
#define ICON_BAR_STR    23
#define ICON_STOP       24

#ifdef TEST
// test window icons
#define ICON_TST_BACK    1
#define ICON_TST_VALUE   2
#endif

typedef struct ro_s
{
  unsigned int flags;
  int task_handle;
  win_data_t win_data[WIN_MAX];
  int cur_menu;
  int drag;       // icons: 0, ICON_SAVE_WAV, ICON_SAVE_MP3, ICON_SAVE_TEXT
  int converting; // filetypes: 0, AMPEG, WAVE

  struct vdu_s
  {
    int width;
    int height;
  } vdu;

} ro_t;
// ro.flags bits
#define QUIT           0
#define MESSAGES_OPEN  1

typedef struct
{
  int sample_rate;
  int bitrate;
  int mono;
  int tempo;
} opt_t;


// main.c
extern ro_t ro;
extern opt_t option;
void file_icon_state(int wave, int mp3, int text, int stop);
int check_disc_space(char *filename, unsigned int size);

// player.c
#define CLK_RES 10 // position and duration resolution in counts per second (1 or 10)
extern unsigned int song_duration; // song duration in 1/CLK_RES seconds
void midiPlayer_init(opt_t *option);
void midiPlayer_term(void);
void midiPlayer_recording(void);
void midi_file_player(void);
enum // player_start actions
{
  FILE_PLAY,   // (entry option) TRUE when player is playing or paused
  FILE_INFO,   // (entry option) TRUE when player is scanning the file for information
  QUIET,       // (entry option) TRUE to suppress all messages
  PAUSED,      // (control)      TRUE when player is paused
  SEEKING      // (internal use) TRUE when seeking to a position
};
int player_start(int action);
void player_stop(void);
void player_close(void);
int player_rescan(void);
int player_tempo(int data);
int player_pitch(int data);
int player_load(char *name, int options); // returns error or duration
int player_save_wav(char *file_out);
int player_save_txt(char *filename);
int rec_active(void);
void set_rec_active(void);

// mp3.c
int mp3_init(opt_t *option);
int player_save_mp3(char *filename);
void mp3_recording(void);

#endif
