/*****************************************************************************

        GRAOUMF TRACKER 2
        Author: Laurent de Soras, 1996-2016

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

*****************************************************************************/



/*\\\ FICHIERS INCLUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include <stdio.h>
#include	<stdlib.h>

#include	"archi.h"
#include "base.h"
#include "base_ct.h"
#include "edstring.h"
#include "gtracker.h"
#include "intrface.h"
#include "mpannel.h"
#include "rsc01.h"
#include "song.h"
#include "String.h"
#include "tracks.h"



/*\\\ CONSTANTES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ TYPES & STRUCTURES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

typedef struct
{
	UBYTE		day;			/* 1-31 */
	UBYTE		month;		/* 1-12 */
	UWORD		year;			/* 1994-... */
} SONG_DATE;



/*\\\ PROTOTYPES DES FONCTIONS PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ VARIABLES EXTERNES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ VARIABLES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

WORD	SONG_sequence [SONG_MAX_SONG_LENGTH] = { 0 };
int	SONG_song_length = 1;
int	SONG_song_repeat = 0;
char	SONG_name [SONG_NAME_LEN];
char	SONG_small_comment [SONG_SMALLCOM_LEN];
char	SONG_tracker_name [SONG_TRACKER_NAME_LEN];
String	SONG_extra_comment;
SONG_DATE	SONG_date;



/*\\\ FONCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/


signed int	SONG_init (void)
{
	char	temp_0 [99+1];

	SONG_set_song_repeat (0);
	SONG_set_song_length (1);
	SONG_set_pattern_number (0, 0);
	SONG_set_song_name ("");
	SONG_set_small_comment ("");
	SONG_set_extra_comment ("");
	sprintf (temp_0, "Graoumf Tracker r%d", GTK_VERSION_NUMBER);
	BASE_copy_string (temp_0, SONG_tracker_name, strlen (temp_0), SONG_TRACKER_NAME_LEN);

	return (0);
}



void	SONG_restore (void)
{
}



/****************************************************************************/
/*                                                                          */
/*      ROUTINES DE BASE                                                    */
/*                                                                          */
/****************************************************************************/



int	SONG_get_pattern_number (int songpos)
{
	return (SONG_sequence [songpos]);
}



void	SONG_set_pattern_number (int songpos, int pattern)
{
	SONG_sequence [songpos] = pattern;
}



int	SONG_get_song_length (void)
{
	return (SONG_song_length);
}



void	SONG_set_song_length (int length)
{
	SONG_song_length = length;
}



int	SONG_get_song_repeat (void)
{
	return (SONG_song_repeat);
}



void	SONG_set_song_repeat (int repeat)
{
	SONG_song_repeat = repeat;
}



void	SONG_get_song_name (char *name_0)
{
	BASE_copy_string (SONG_name, name_0,
							SONG_NAME_LEN, SONG_NAME_LEN);
	name_0 [SONG_NAME_LEN] = 0;
}



void	SONG_set_song_name (const char *name_0)
{
	BASE_copy_string (name_0, SONG_name, strlen (name_0), SONG_NAME_LEN);
}



void	SONG_get_small_comment (char *text_0)
{
	BASE_copy_string (SONG_small_comment, text_0,
							SONG_SMALLCOM_LEN, SONG_SMALLCOM_LEN);
	text_0 [SONG_SMALLCOM_LEN] = 0;
}



void	SONG_set_small_comment (const char *text_0)
{
	BASE_copy_string (text_0, SONG_small_comment, strlen (text_0), SONG_SMALLCOM_LEN);
}



String	SONG_get_extra_comment (void)
{
	return (SONG_extra_comment);
}



void	SONG_set_extra_comment (const String &xcom)
{
	SONG_extra_comment = xcom;
}



void	SONG_get_tracker_name (char *name_0)
{
	BASE_copy_string (SONG_tracker_name, name_0,
							SONG_TRACKER_NAME_LEN, SONG_TRACKER_NAME_LEN);
	name_0 [SONG_TRACKER_NAME_LEN] = 0;
}



void	SONG_set_tracker_name (const char *name_0)
{
	BASE_copy_string (name_0, SONG_tracker_name, strlen (name_0), SONG_TRACKER_NAME_LEN);
}



void	SONG_reset_date (void)
{
	time_t		the_time;
	const struct tm	*date_ptr;

	the_time = time (NULL);
	date_ptr = localtime (&the_time);
	SONG_date.day = (UBYTE) date_ptr->tm_mday;
	SONG_date.month = (UBYTE) (date_ptr->tm_mon + 1);
	SONG_date.year = (UWORD) (date_ptr->tm_year + 1900);
}



signed int	SONG_insert_pos (int position)
{
	int		song_len;
	int		cur_pos;

	song_len = SONG_get_song_length ();
	if (   song_len >= SONG_MAX_SONG_LENGTH
	    || position >= song_len
	    || position < 0)
	{
		return (-1);	/* Impossible d'inserer une nouvelle position */
	}

	SONG_set_song_length (song_len + 1);

	for (cur_pos = song_len; cur_pos >= position; cur_pos --)
	{
		SONG_set_pattern_number (cur_pos + 1, SONG_get_pattern_number (cur_pos));
	}

	return (0);
}



signed int	SONG_delete_pos (int position)
{
	int		song_len;
	int		cur_pos;

	song_len = SONG_get_song_length ();
	if (   song_len <= 1
	    || position >= song_len - 1
	    || position < 0)
	{
		return (-1);	/* Impossible d'effacer la position */
	}

	for (cur_pos = position + 1; cur_pos < song_len; cur_pos ++)
	{
		SONG_set_pattern_number (cur_pos - 1, SONG_get_pattern_number (cur_pos));
	}

	SONG_set_song_length (song_len - 1);

	return (0);
}



/*==========================================================================*/
/*      Nom: SONG_clear_song                                                */
/*      Description: Efface la sequence.                                    */
/*      Retour: 0 si tout s'est bien passe.                                 */
/*==========================================================================*/

signed int	SONG_clear_song (void)
{
	char	temp_0 [99+1];

	GTK_stop_all ();
	GTK_set_line_position (0);
	GTK_set_song_position (0);

	SONG_set_song_repeat (0);
	SONG_set_song_length (1);
	SONG_set_pattern_number (0, 0);
	SONG_set_song_name ("");
	SONG_set_small_comment ("");
	SONG_set_extra_comment ("");
	sprintf (temp_0, "Graoumf Tracker r%d", GTK_VERSION_NUMBER);
	BASE_copy_string (temp_0, SONG_tracker_name, strlen (temp_0), SONG_TRACKER_NAME_LEN);

	INTR_pattern_editor_track_ptr->check_cursor ();

	return (0);
}



/****************************************************************************/
/*                                                                          */
/*      MODIFICATIONS AVEC L'INTERFACE                                      */
/*                                                                          */
/****************************************************************************/



/*==========================================================================*/
/*      Nom: SONG_set_pattern_number_intr                                   */
/*      Description: Change le pattern de la position courante de           */
/*                   differentes manieres. L'interface est ici mise en jeu. */
/*      Parametres en entree:                                               */
/*        - type: 0 = Le parametre est absolu,                              */
/*                1 = Le parametre est relatif,                             */
/*                2 = Entree au clavier.                                    */
/*        - value: le parametre en question.                                */
/*==========================================================================*/

void	SONG_set_pattern_number_intr (int type, signed int value)
{
	int			songpos;
	int			linepos;
	signed int	pattern;
	char			nbr3_0 [3+1];

	songpos = GTK_get_song_position ();
	pattern = SONG_get_pattern_number (songpos);

	switch (type)
	{
	/* Mode relatif */
	case	INTR_CHGTYPE_REL:
		pattern += value;
		break;

	/* Entree au clavier */
	case	INTR_CHGTYPE_KBD:
		sprintf (nbr3_0, INTR_base_song_3, pattern);
		EDIT_edit_string_base (nbr3_0, RSC_OBJ_MP_VAR_PAT_VAL, 3, INTR_base_song);
		pattern = (int) strtol (nbr3_0, NULL, INTR_base_song);
		break;

	/* Mode absolu */
	case	INTR_CHGTYPE_ABS:
		pattern = value;
		break;
	}

	pattern = MIN (pattern, PAT_NBRPATTERNS_MAXI - 1);
	pattern = MAX (pattern, 0);
	SONG_set_pattern_number (songpos, pattern);
	GTK_modified_flag = true;
	linepos = MIN (GTK_get_line_position (), PAT_get_current_pattern_height () - 1);
	GTK_set_line_position (linepos);
	MPAN_display_var_icons (true, true);
	INTR_pattern_editor_track_ptr->refresh_dynamic (true);
}



/*==========================================================================*/
/*      Nom: SONG_set_song_length_intr                                      */
/*      Description: Change la longueur de la song de                       */
/*                   differentes manieres. L'interface est ici mise en jeu. */
/*      Parametres en entree:                                               */
/*        - type: 0 = Le parametre est absolu,                              */
/*                1 = Le parametre est relatif,                             */
/*                2 = Entree au clavier.                                    */
/*        - value: le parametre en question.                                */
/*==========================================================================*/

void	SONG_set_song_length_intr (int type, signed int value)
{
	int			songpos;
	signed int	songlen;
	char			nbr3_0 [3+1];

	GTK_stop_all ();

	songpos = GTK_get_song_position ();
	songlen = SONG_get_song_length ();

	switch (type)
	{
	/* Position relative */
	case	INTR_CHGTYPE_REL:
		songlen += value;
		break;

	/* Entree au clavier */
	case	INTR_CHGTYPE_KBD:
		sprintf (nbr3_0, INTR_base_song_3, songlen);
		EDIT_edit_string_base (nbr3_0, RSC_OBJ_MP_VAR_LEN_VAL, 3, INTR_base_song);
		songlen = (int) strtol (nbr3_0, NULL, INTR_base_song);
		break;

	/* Position absolue  */
	case	INTR_CHGTYPE_ABS:
		songlen = value;
		break;
	}

	songlen = MAX (songlen, songpos + 1);
	songlen = MAX (songlen, SONG_get_song_repeat ());
	songlen = MIN (songlen, SONG_MAX_SONG_LENGTH);
	songlen = MAX (songlen, 0);
	SONG_set_song_length (songlen);
	GTK_modified_flag = true;
	MPAN_display_var_icons (true, true);
	INTR_pattern_editor_track_ptr->refresh_dynamic (true);
}



/*==========================================================================*/
/*      Nom: SONG_set_song_repeat_intr                                      */
/*      Description: Change le point de repetition de la song de            */
/*                   differentes manieres. L'interface est ici mise en jeu. */
/*      Parametres en entree:                                               */
/*        - type: 0 = Le parametre est absolu,                              */
/*                1 = Le parametre est relatif,                             */
/*                2 = Entree au clavier.                                    */
/*        - value: le parametre en question.                                */
/*==========================================================================*/

void	SONG_set_song_repeat_intr (int type, signed int value)
{
	signed int	songrep;
	int			songlen;
	char			nbr3_0 [3+1];

	songrep = SONG_get_song_repeat ();
	songlen = SONG_get_song_length ();

	switch (type)
	{
	/* Position relative */
	case	INTR_CHGTYPE_REL:
		songrep += value;
		break;

	/* Entree au clavier */
	case	INTR_CHGTYPE_KBD:
		sprintf (nbr3_0, INTR_base_song_3, songrep);
		EDIT_edit_string_base (nbr3_0, RSC_OBJ_MP_VAR_REP_VAL, 3, INTR_base_song);
		songrep = (int) strtol (nbr3_0, NULL, INTR_base_song);
		break;

	/* Position absolue  */
	case	INTR_CHGTYPE_ABS:
		songrep = value;
		break;
	}

	songrep = MIN (songrep, songlen - 1);
	songrep = MAX (songrep, 0);
	SONG_set_song_repeat (songrep);
	GTK_modified_flag = true;
	MPAN_display_var_icons (true, true);
	INTR_pattern_editor_track_ptr->refresh_dynamic (true);
}



/****************************************************************************/
/*                                                                          */
/*                                                                          */
/*                                                                          */
/****************************************************************************/



/*==========================================================================*/
/*      Nom:                                                                */
/*      Description:                                                        */
/*      Parametres en entree:                                               */
/*      Parametres en sortie:                                               */
/*      Parametres en entree/sortie:                                        */
/*      Retour:                                                             */
/*==========================================================================*/
