/**
 * \mainpage CSC3502 : PonyTracker
 *
 * Les fonctionnalités de cette application sont les suivantes :
 * <ul>
 * <li> fonction 1</li>
 * <li> fonction 2</li>
 * <li> fonction 3</li>
 * <li> fonction 4</li>
 * </ul>
 *
 * @file main.c
 *
 * Programme principal du Ponytracker
 *
 * @version 1.1
 * @author Module CSC3502 : Projet Informatique 1ère année TELECOM SudParis
 * @date  Mai 2014
*/

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <string.h>

#include "motifs/motifs.h"
#include "melodie/melodie.h"
#include "samples/samples.h"
#include "instruments/instruments.h"
#include "lecture/lecture.h"
//#include <SDL2/SDL.h>
//#include <SDL2/SDL_mixer.h>
//#include <SDL2/SDL_main.h>

#define DEF_NBR_TMP 16
#define MAX_PATTERNS 256
#define NBR_INST 10
#define NBR_SMPL 5

// Variables globales
Motif* melodie[MAX_PATTERNS] = {NULL};
Motif* liste = NULL;
Instrument* inst[NBR_INST] = {NULL};
Sample* smpl[NBR_SMPL] = {NULL};
int nbrPortees = 1;
int taille;

GtkBuilder *monBuilder;
char *Do="Do";
char *DoD="Do#";
char *Re="Re";
char *ReD="Re#";
char *Mi="Mi";
char *Fa="Fa";
char *FaD="Fa#";
char *Sol="Sol";
char *SolD="Sol#";
char *La="La";
char *LaD="La#";
char *Si="Si";
char *N1="1";
char *N2="2";
char *N3="3";
char *N4="4";
char *N5="5";


// Fonctions de débug

void afficherMotif(Motif* m, int nbrPortees){
	printf("%s  :\n",m->nom);
	for (int tmp = 0; tmp < m->nbrTmp; tmp++){
		for (int portee = 0; portee < nbrPortees; portee++){
			printf("%d ",getNote(m,portee,tmp));
		}
		printf("\n");
	}
}

// Fin des fonctions de débug

void debut(Motif* melodie[], Instrument* inst[], Sample* smpl[], Motif* liste, int nbrPortees){
	ajouterMotif(&liste, DEF_NBR_TMP, nbrPortees);
	Motif* m = liste;

	int i;

	// En guise d'exemple, voici la mélodie du générique de My Little Pony : Friendship is Magic.

	// My Little Pony.
	
	for (i = 0; i < DEF_NBR_TMP; i++) {
		definirNote(m,0,i,-1);
		definirOctave(m,0,i,3);
	}

	definirNote(m,0,0,1);
	definirInstrument(m,0,0,0);
	definirInstrument(m,0,2,-1);
	definirNote(m,0,4,0);
	definirInstrument(m,0,4,0);
	definirNote(m,0,5,1);
	definirInstrument(m,0,5,0);
	definirInstrument(m,0,6,-1);
	definirNote(m,0,7,3);
	definirInstrument(m,0,7,0);
	definirInstrument(m,0,8,-1);
	definirNote(m,0,9,1);
	definirInstrument(m,0,9,0);
	definirInstrument(m,0,12,-1);
	
	ajouterMotif(&liste, DEF_NBR_TMP, nbrPortees);
	Motif* n = liste;

	// I used to wonder what friendship could be.
	
	for (i = 0; i < DEF_NBR_TMP; i++) {
		definirNote(n,0,i,-1);
		definirOctave(n,0,i,3);
	}

	definirNote(n,0,1,5);
	definirInstrument(n,0,1,0);
	definirNote(n,0,2,5);
	definirInstrument(n,0,2,0);
	definirNote(n,0,3,5);
	definirInstrument(n,0,3,0);
	definirNote(n,0,4,5);
	definirInstrument(n,0,4,0);
	definirInstrument(n,0,5,-1);
	definirNote(n,0,6,1);
	definirInstrument(n,0,6,0);
	definirNote(n,0,7,3);
	definirInstrument(n,0,7,0);
	definirInstrument(n,0,8,-1);
	definirNote(n,0,9,1);
	definirInstrument(n,0,9,0);
	definirInstrument(n,0,10,-1);
	definirNote(n,0,11,5);
	definirInstrument(n,0,11,0);
	definirInstrument(n,0,12,-1);
	definirNote(n,0,13,3);
	definirInstrument(n,0,13,0);
	definirInstrument(n,0,14,-1);
	definirNote(n,0,15,1);
	definirInstrument(n,0,15,0);

	ajouterMotif(&liste, DEF_NBR_TMP, nbrPortees);
	Motif* p = liste;

	// Until you all shared its magic with me.
	
	for (i = 0; i < DEF_NBR_TMP; i++) {
		definirNote(p,0,i,-1);
		definirOctave(p,0,i,3);
	}

	definirNote(p,0,0,5);
	definirInstrument(p,0,0,0);
	definirNote(p,0,1,8);
	definirInstrument(p,0,1,0);
	definirInstrument(p,0,2,-1);
	definirNote(p,0,3,8);
	definirInstrument(p,0,3,0);
	definirInstrument(p,0,4,-1);
	definirNote(p,0,5,5);
	definirInstrument(p,0,5,0);
	definirInstrument(p,0,6,-1);
	definirNote(p,0,7,3);
	definirInstrument(p,0,7,0);
	definirInstrument(p,0,8,-1);
	definirNote(p,0,9,1);
	definirInstrument(p,0,9,0);
	definirNote(p,0,10,5);
	definirInstrument(p,0,10,0);
	definirInstrument(p,0,11,-1);
	definirNote(p,0,12,3);
	definirInstrument(p,0,12,0);
	definirInstrument(p,0,14,-1);

	ajouterMotifVirtuel(melodie,0,m);
	ajouterMotifVirtuel(melodie,1,n);
	ajouterMotifVirtuel(melodie,2,m);
	ajouterMotifVirtuel(melodie,3,p);

	// Définir les instruments les samples

	ajouterSample(smpl,0,"lecture/0.wav");
	setHauteur(smpl[0],440.0);

	ajouterInstrument(inst,0);
	setSample(inst[0],smpl[0]);
}

int main( int argc, char *argv[] ){
  debut(melodie, inst, smpl, liste, nbrPortees);
  Motif* m = melodie[0];
  GtkWidget *maFenetre;
  char str[20];
  gtk_init( &argc, &argv );
  
  monBuilder = gtk_builder_new();
  
  gtk_builder_add_from_file( monBuilder, "GUI/ponytrackertest.glade", NULL);
  gtk_builder_connect_signals( monBuilder, NULL);
  
  maFenetre = GTK_WIDGET( gtk_builder_get_object( monBuilder, "fenetreprincipale"));
  
  GtkButton *button = (GtkButton*) gtk_builder_get_object(monBuilder, "button16");
	switch (getNote(m,0,0)) {
	case 0 :
	  strcpy(str,"Do ");
	  break;
	case 1 :
	  strcpy(str,"Do# ");
	  break;
	case 2 :
	  strcpy(str,"Re ");
	  break;
	case 3 :
	  strcpy(str,"Re# ");
	  break;
	case 4 :
	  strcpy(str,"Mi ");
	  break;
	case 5 :
	  strcpy(str,"Fa ");
	  break;
	case 6 :
	  strcpy(str,"Fa# ");
	  break;
	case 7 :
	  strcpy(str,"Sol ");
	  break;
	case 8 :
	  strcpy(str,"Sol# ");
	  break;
	case 9 : 
	  strcpy(str,"La ");
	  break;
	case 10 :
	  strcpy(str,"La# ");
	  break;
	case 11 :
	  strcpy(str,"Si ");
	  break;
	default :
	  break;
	}

	printf("%d\n",getOctave(m,0,0));
	
	switch (getOctave(m,0,0)) {
	case 0 :
	  strcat(str, "0 ");
	  break;
	case 1 : 
	  strcat(str, "1 ");
	  break;
	case 2 :
	  strcat(str, "2 ");
	  break;
	case 3 :
	  strcat(str, "3 ");
	  break;
	case 4 :
	  strcat(str, "4 ");
	  break;
	default :
	  break;
	}

	switch (getInstrument(m,0,0)) {
	case 0 :
	  strcat(str, "0 ");
	  break;
	case 1 : 
	  strcat(str, "1 ");
	  break;
	case 2 :
	  strcat(str, "2 ");
	  break;
	case 3 :
	  strcat(str, "3 ");
	  break;
	case 4 :
	  strcat(str, "4 ");
	  break;
	default :
	  break;
	}

	switch (getVolume(m,0,0)) {
	case 0 :
	  strcat(str, "0 ");
	  break;
	case 1 : 
	  strcat(str, "1 ");
	  break;
	case 2 :
	  strcat(str, "2 ");
	  break;
	case 3 :
	  strcat(str, "3 ");
	  break;
	case 4 :
	  strcat(str, "4 ");
	  break;
	default :
	  break;
	}

	switch (getEffet(m,0,0)) {
	case 0 :
	  strcat(str, "0 ");
	  break;
	case 1 : 
	  strcat(str, "1 ");
	  break;
	case 2 :
	  strcat(str, "2 ");
	  break;
	case 3 :
	  strcat(str, "3 ");
	  break;
	case 4 :
	  strcat(str, "4 ");
	  break;
	default :
	  break;
	}

	gtk_button_set_label(button, str);

	gtk_widget_show_all (maFenetre);
	gtk_main();
	return EXIT_SUCCESS;
}

void fenetreSample ( int argc, char *argv[] )
{

  GtkWidget *maFenetreSample = GTK_WIDGET( gtk_builder_get_object( monBuilder, "ajoutsample"));

  gtk_widget_show_all (maFenetreSample);
}

void fenetreInstrument ( int argc, char *argv[] )
{
  GtkWidget *maFenetreInstrument = GTK_WIDGET( gtk_builder_get_object( monBuilder, "ajoutinstrument"));

  gtk_widget_show_all (maFenetreInstrument);
}

void fenetreMotif ( int argc, char *argv[] )
{
  GtkWidget *maFenetreMotif = GTK_WIDGET( gtk_builder_get_object( monBuilder, "ajoutmotif"));

  gtk_widget_show_all (maFenetreMotif);
}

void fenetreNote ( int argc, char *argv[] )
{
  GtkWidget *maFenetreNote = GTK_WIDGET( gtk_builder_get_object( monBuilder, "ajoutnote"));
  
  gtk_widget_show_all (maFenetreNote);
}

void remplissageNote (GtkWidget *widget, gpointer *data){

	Motif* m = melodie[0];

  GtkEntry *entryNote = (GtkEntry*) gtk_builder_get_object(monBuilder,"combonote");
  GtkEntry *entryOctave = (GtkEntry*) gtk_builder_get_object(monBuilder,"combooctave");
  GtkEntry *entryInstrument = (GtkEntry*) gtk_builder_get_object(monBuilder,"comboinstrument");
  GtkEntry *entryVolume = (GtkEntry*) gtk_builder_get_object(monBuilder,"combovolume");
  GtkEntry *entryEffet = (GtkEntry*) gtk_builder_get_object(monBuilder,"comboeffet");

  const char *strnote = gtk_entry_get_text(GTK_ENTRY(entryNote));
  const char *stroctave = gtk_entry_get_text(GTK_ENTRY(entryOctave));
  const char *strinstrument = gtk_entry_get_text(GTK_ENTRY(entryInstrument));
  const char *strvolume = gtk_entry_get_text(GTK_ENTRY(entryVolume));
  const char *streffet = gtk_entry_get_text(GTK_ENTRY(entryEffet));

  if (strcmp(Do,strnote)==0) definirNote(m,0,0,1);
  else 
    if (strcmp(DoD,strnote)==0) definirNote(m,0,0,2);
    else
      if (strcmp(Re,strnote)==0) definirNote(m,0,0,3);
      else
	if (strcmp(ReD,strnote)==0) definirNote(m,0,0,4);
	else
	  if (strcmp(Mi,strnote)==0) definirNote(m,0,0,5);
	  else
	    if (strcmp(Fa,strnote)==0) definirNote(m,0,0,6);
	    else
	      if (strcmp(FaD,strnote)==0) definirNote(m,0,0,7);
	      else
		if (strcmp(Sol,strnote)==0) definirNote(m,0,0,8);
		else
		  if (strcmp(SolD,strnote)==0) definirNote(m,0,0,9);
		  else
		    if (strcmp(La,strnote)==0) definirNote(m,0,0,10);
		    else
		      if (strcmp(LaD,strnote)==0) definirNote(m,0,0,11);
		      else
			if (strcmp(Si,strnote)==0) definirNote(m,0,0,12);

  if (strcmp(N1,stroctave)==0) definirOctave(m,0,0,1);
  else
    if (strcmp(N2,stroctave)==0) definirOctave(m,0,0,2);
    else
      if (strcmp(N3,stroctave)==0) definirOctave(m,0,0,3);
      else
	if (strcmp(N4,stroctave)==0) definirOctave(m,0,0,4);
	else
	  if (strcmp(N5,stroctave)==0) definirOctave(m,0,0,5);

  if (strcmp(N1,strinstrument)==0) definirInstrument(m,0,0,1);
  else
    if (strcmp(N2,strinstrument)==0) definirInstrument(m,0,0,2);
    else
      if (strcmp(N3,strinstrument)==0) definirInstrument(m,0,0,3);
      else
	if (strcmp(N4,strinstrument)==0) definirInstrument(m,0,0,4);
	else
	  if (strcmp(N5,strinstrument)==0) definirInstrument(m,0,0,5);

  if (strcmp(N1,strvolume)==0) definirVolume(m,0,0,1);
  else
    if (strcmp(N2,strvolume)==0) definirVolume(m,0,0,2);
    else
      if (strcmp(N3,strvolume)==0) definirVolume(m,0,0,3);
      else
	if (strcmp(N4,strvolume)==0) definirVolume(m,0,0,4);
	else
	  if (strcmp(N5,strvolume)==0) definirVolume(m,0,0,5);

  if (strcmp(N1,streffet)==0) definirEffet(m,0,0,1);
  else
    if (strcmp(N2,streffet)==0) definirEffet(m,0,0,2);
    else
      if (strcmp(N3,streffet)==0) definirEffet(m,0,0,3);
      else
	if (strcmp(N4,streffet)==0) definirEffet(m,0,0,4);
	else
	  if (strcmp(N5,streffet)==0) definirEffet(m,0,0,5);
}

void lancerLecture ()
{
	
	//courant = 0;
	//taille = 0;
	printf("%d\n",nbrPortees);
	//debut(melodie, inst, smpl, liste, nbrPortees);
	lecture(nbrPortees,1,480,inst,melodie);
}

void quitter ()
{
	gtk_main_quit();
}

void refresh(){}
