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

        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	"EditString.h"
#include	"edstring.h"
#include	"file.h"
#include	"gtracker.h"
#include	"intrface.h"
#include	"log.h"
#include	"memory.h"
#include	"mpannel.h"
#include	"PatEdMenuSamplesMain.h"
#include	"Popup.h"
#include	"resource.h"
#include	"rsc01.h"
#include	"samp.h"
#include	"spl_raw.h"
#include	"splstruc.h"
#include	"WaveForm.h"



/*\\\ CONSTANTES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



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



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



/*\\\ DEFINITION DES VARIABLES DE CLASSE PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ DEFINITION DES VARIABLES DE CLASSE PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ METHODES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*==========================================================================*/
/*      Nom: check_ok                                                       */
/*      Description: Verifie l'intergrite de l'objet.                       */
/*      Retour: 0 si l'objet parait correct.                                */
/*==========================================================================*/

signed int	PatEdMenuSamplesMain::check_ok (void) const
{
	if (this == NULL)
	{
		LOG_printf ("PatEdMenuSamplesMain::check_ok: Error: \"this\" pointer is NULL.\n");
		return (-1);
	}

	/*** A faire ***/

	return (0);
}



/*==========================================================================*/
/*      Nom: self_display                                                   */
/*      Description: Affiche "textuellement" le contenu courant de l'objet. */
/*==========================================================================*/

void	PatEdMenuSamplesMain::self_display (void) const
{

	/*** A faire ***/

}



/*==========================================================================*/
/*      Nom: redraw                                                         */
/*      Description: Affiche la composante d'interface.                     */
/*==========================================================================*/

void	PatEdMenuSamplesMain::redraw (void)
{
	RSC_display_object (RSC_OBJ_MP_SUBM);

	refresh ();
}



/*==========================================================================*/
/*      Nom: refresh                                                        */
/*      Description: Rafraichit l'affichage des donnees.                    */
/*==========================================================================*/

void	PatEdMenuSamplesMain::refresh (void)
{
	int		sbar_width;
	int		slider_width;
	int		slider_pos;
	signed int	balance;
	char		string_0 [1023+1];
	char		name_0 [Sample_NAME_LEN+1];
	LWORD		freq;
	int		nbr_bytes;
	int		nbr_tracks;

	freq = SAMP_get_sample_freq (GTK_sample_nbr);
	nbr_tracks = SAMP_get_sample_stereo (GTK_sample_nbr);
	nbr_bytes = SAMP_get_sample_resolution (GTK_sample_nbr) >> 3;

	/* Numero de sample */
	sprintf (string_0, INTR_base_song_3, GTK_sample_nbr);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL);

	/* Nom du sample */
	SAMP_get_sample_name (GTK_sample_nbr, name_0);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNAME_NAME, name_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNAME_NAME);

	/* Resolution */
	sprintf (string_0, "%2d", SAMP_get_sample_resolution (GTK_sample_nbr));
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BITS_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BITS_VAL);

	/* Mono/Stereo */
	switch (SAMP_get_sample_stereo (GTK_sample_nbr))
	{
	case	1:
		strcpy (string_0, "  MONO");
		break;
	case	2:
		strcpy (string_0, "STEREO");
		break;
	default:
		sprintf (string_0, "%6d", nbr_tracks);
		break;
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_TRKS_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_TRKS_VAL);

	/* Frequence d'echantillonnage */
	sprintf (string_0, "%6ld", (long) SAMP_get_sample_freq (GTK_sample_nbr));
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_VAL);

	/* Volume */
	sprintf (string_0, "%3X", SAMP_get_sample_volume (GTK_sample_nbr));
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_VOL_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_VOL_VAL);

	/* Balance */
	balance = SAMP_get_sample_balance (GTK_sample_nbr);
	if (balance >= 0)
	{
		sprintf (string_0, "%3X", balance);
		RSC_clear_flag (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER, RSC_ATTR_NOTDISP);
		sbar_width = RSC_get_width (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR);
		slider_width = RSC_get_width (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER);
		slider_pos = (LWORD)balance * (sbar_width - slider_width) / 0xFFF;
		RSC_set_relative_object_position (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER, slider_pos, 0);
	}
	else
	{
		strcpy (string_0, "\?\?\?");
		RSC_set_flag (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER, RSC_ATTR_NOTDISP);
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_VAL);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR);

	/* Import format */
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_IMPORTF_VAL, FILE_sample_maskname.c_str ());
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_IMPORTF_VAL);

	/* Export format */
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_EXPORTF_VAL,
						 SPLS_format_routines [SPLS_export_format].name_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_EXPORTF_VAL);

	/* Signed */
	RSC_select_object_display (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SIGNED, SPLS_signed_flag);

	/* D2D */
	RSC_select_object_display (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_D2D, SAMP_get_sample_type (GTK_sample_nbr) == 1);

	/* Longueur */
	INTR_splpos_2_string (string_0, SAMP_get_sample_length (GTK_sample_nbr),
								 freq, nbr_tracks, nbr_bytes);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LEN_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LEN_VAL);

	/* Repetition */
	INTR_splpos_2_string (string_0, SAMP_get_sample_repeat (GTK_sample_nbr),
								 freq, nbr_tracks, nbr_bytes);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPEAT_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPEAT_VAL);

	/* Longueur de repetition */
	INTR_splpos_2_string (string_0, SAMP_get_sample_replen (GTK_sample_nbr),
								 freq, nbr_tracks, nbr_bytes);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPLEN_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPLEN_VAL);

	/* Longueur buffer */
	INTR_splpos_2_string (string_0, SAMP_get_sample_loopbuf (GTK_sample_nbr),
								 freq, nbr_tracks, nbr_bytes);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_RBUF_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_RBUF_VAL);

	/* MIDI note */
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_MIDIN_VAL,
						 INTR_note_names [SAMP_get_sample_midi_note (GTK_sample_nbr)]);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_MIDIN_VAL);

	/* Finetune */
	sprintf (string_0, "%3d", SAMP_get_sample_finetune (GTK_sample_nbr));
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FTUNE_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FTUNE_VAL);

	/* Loop type */
	switch (SAMP_get_sample_loop (GTK_sample_nbr))
	{
	case	WaveForm_LOOP_TYPE_NONE:
		RSC_select_radio_button_display (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NONE,
													RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NONE);
		break;
	case	WaveForm_LOOP_TYPE_FWD:
		RSC_select_radio_button_display (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NORM,
													RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NONE);
		break;
	case	WaveForm_LOOP_TYPE_PP:
		RSC_select_radio_button_display (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_PP,
													RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NONE);
		break;
	}

	// Group
	const int		group = SAMP_get_sample_group (GTK_sample_nbr);
	sprintf (string_0, INTR_base_song_3, group);
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_VAL, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_VAL);

	if (group == 0)
	{
		sprintf (string_0, "(No group)");
	}
	else
	{
		sprintf (string_0, "%s", SAMP_get_group_name (group).c_str ());
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_NAME, string_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_NAME);

	refresh_dynamic (true);
}



/*==========================================================================*/
/*      Nom: refresh_dynamic                                                */
/*      Description: Rafraichit l'affichage des donnees dynamiques.         */
/*        - force_flag: true indique qu'on doit forcer le rafraichissement. */
/*==========================================================================*/

void	PatEdMenuSamplesMain::refresh_dynamic (bool force_flag)
{
	/* Rien en fait */
}



/*==========================================================================*/
/*      Nom: manage                                                         */
/*      Description: Gere la composante d'interface                         */
/*      Parametres en entree:                                               */
/*        - sel_object: objet detecte par le gestionnaire d'interface       */
/*        - sel_elder: aine de sel_object                                   */
/*==========================================================================*/

void	PatEdMenuSamplesMain::manage (int sel_object, int sel_elder)
{
	int		sbar_width;
	int		slider_width;
	int		slider_pos;
	long		val;
	SLWORD	ret_code;
	signed int	line;
	char		string_0 [255+1];
	char		name_0 [Sample_NAME_LEN+1];
	char		nbr6_0 [6+1];
	Popup		popup_menu;
	LWORD		length;
	LWORD		repeat;
	LWORD		replen;

	length = SAMP_get_sample_length (GTK_sample_nbr);
	repeat = SAMP_get_sample_repeat (GTK_sample_nbr);
	replen = SAMP_get_sample_replen (GTK_sample_nbr);

	switch (sel_object)
	{

	/* Numero de sample */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_UP:
		MPAN_set_sample_number (INTR_CHGTYPE_REL,
										INTR_inc_speed [0] [RSC_mouse_key],
										RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL);
		break;
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_DOWN:
		MPAN_set_sample_number (INTR_CHGTYPE_REL,
										-INTR_inc_speed [0] [RSC_mouse_key],
										RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL);
		break;
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL:
		if (RSC_mouse_key & 2)
		{
			MPAN_set_sample_number (INTR_CHGTYPE_POP, 0, RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL);
		}
		else
		{
			MPAN_set_sample_number (INTR_CHGTYPE_KBD, 0, RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNUM_VAL);
		}
		break;

	/* Sample name */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNAME:
		SAMP_get_sample_name (GTK_sample_nbr, name_0);
		if (EDIT_edit_string (name_0, RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SNAME_NAME,
									 Sample_NAME_LEN, EditString_TYPE_ALPHA) == 0)
		{
			SAMP_set_sample_name (GTK_sample_nbr, name_0);
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	/* Frequence */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_VAL:
		if (RSC_mouse_key & 2)
		{
			popup_menu.add_line (" 8000 Hz (Phone)", 8000);
			popup_menu.add_line (" 8363 Hz (Protracker samples)", 8363);
			popup_menu.add_line ("11025 Hz", 11025);
			popup_menu.add_line ("16000 Hz", 16000);
			popup_menu.add_line ("22050 Hz", 22050);
			popup_menu.add_line ("32000 Hz (Tape, radio, DAT)", 32000);
			popup_menu.add_line ("44100 Hz (Audio CD, DAT)", 44100);
			popup_menu.add_line ("48000 Hz (DAT)", 48000);
			popup_menu.add_line ("96000 Hz (DVD)", 96000);

			line = popup_menu.select_radio_by_code (SAMP_get_sample_freq (GTK_sample_nbr));
			ret_code = popup_menu.manage (line);
			if (ret_code >= 0)
			{
				SAMP_set_sample_freq (GTK_sample_nbr, ret_code);
				GTK_modified_flag = true;
			}
		}
		else
		{
			sprintf (nbr6_0, "%6ld", (long) SAMP_get_sample_freq (GTK_sample_nbr));
			if (EDIT_edit_string_base (nbr6_0, RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_VAL, 6, 10) == 0)
			{
				val = atol (nbr6_0);
				val = MIN (val, Sample_MAX_FREQ);
				val = MAX (val, Sample_MIN_FREQ);
				SAMP_set_sample_freq (GTK_sample_nbr, val);
				GTK_modified_flag = true;
			}
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_UP:
		val = SAMP_get_sample_freq (GTK_sample_nbr);
		val += INTR_inc_speed [1] [RSC_mouse_key];
		val = MIN (val, Sample_MAX_FREQ);
		val = MAX (val, Sample_MIN_FREQ);
		SAMP_set_sample_freq (GTK_sample_nbr, val);
		GTK_modified_flag = true;
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FREQ_DOWN:
		val = SAMP_get_sample_freq (GTK_sample_nbr);
		val -= INTR_inc_speed [1] [RSC_mouse_key];
		val = MIN (val, Sample_MAX_FREQ);
		val = MAX (val, Sample_MIN_FREQ);
		SAMP_set_sample_freq (GTK_sample_nbr, val);
		GTK_modified_flag = true;
		refresh ();
		break;

	/* Volume */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_VOL_VAL:
		if (RSC_mouse_key & 2)
		{
			SAMP_set_sample_volume_intr (INTR_CHGTYPE_POP, 0);
		}
		else
		{
			SAMP_set_sample_volume_intr (INTR_CHGTYPE_KBD, 0);
		}
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_VOL_UP:
		SAMP_set_sample_volume_intr (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_VOL_DOWN:
		SAMP_set_sample_volume_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	/* Balance */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_VAL:
		val = SAMP_get_sample_balance (GTK_sample_nbr);
		if (val < 0)
		{
			sprintf (nbr6_0, "\?\?\?");
		}
		else
		{
			sprintf (nbr6_0, "%3X", (int) val);
		}
		if (EDIT_edit_string (nbr6_0, RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_VAL, 3, EditString_TYPE_ALPHA) == 0)
		{
			if (strchr (nbr6_0, '\?') != NULL)
			{
				val = -1;
			}
			else
			{
				val = strtol (nbr6_0, NULL, 16);
				val = MAX (MIN (val, 0xFFF), 0);
			}
			SAMP_set_sample_balance (GTK_sample_nbr, (signed int) val);
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_RIGHT:
		val = SAMP_get_sample_balance (GTK_sample_nbr);
		val += INTR_inc_speed [1] [RSC_mouse_key];
		val = MIN (val, 0xFFF);
		val = MAX (val, 0);
		SAMP_set_sample_balance (GTK_sample_nbr, (signed int) val);
		GTK_modified_flag = true;
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_LEFT:
		val = SAMP_get_sample_balance (GTK_sample_nbr);
		val -= INTR_inc_speed [1] [RSC_mouse_key];
		val = MIN (val, 0xFFF);
		val = MAX (val, 0);
		SAMP_set_sample_balance (GTK_sample_nbr, (signed int) val);
		GTK_modified_flag = true;
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR:
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER:
		sbar_width = RSC_get_width (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR);
		slider_width = RSC_get_width (RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR_SLIDER);
		slider_pos = INTR_mouse.x - RSC_absolute_object_pixxpos [RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BAL_SBAR];
		val = (LWORD)slider_pos * 0x1000 / (sbar_width - slider_width);
		val = MIN (val, 0xFFF);
		val = MAX (val, 0);
		SAMP_set_sample_balance (GTK_sample_nbr, (signed int) val);
		GTK_modified_flag = true;
		refresh ();
		break;

	/* Bits */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_BITS:
		/* Conversion en 16 bits */
		if (SAMP_get_sample_resolution (GTK_sample_nbr) == 8)
		{
			if (INTR_dialog_box ("",
										"Do you really want to\n"
										"convert your sample\n"
										"to 16 bits \? Used memory\n"
										"will be twice bigger.",
										"OK\nCancel", 0, 1) == 0)
			{
				GTK_stop_all ();
				if (SAMP_convert_sample_8_2_16 (GTK_sample_nbr))
				{
					INTR_dialog_box ("Error",
										  "Can't convert to 16 bits.",
										  "Cancel", 0, 0);
				}
				else
				{
					GTK_modified_flag = true;
				}
			}
		}

		/* Conversion en 8 bits */
		else
		{
			if (INTR_dialog_box ("",
										"Do you really want to\n"
										"convert your sample\n"
										"to 8 bits \? It may lose\n"
										"quality.",
										"OK\nCancel", 0, 1) == 0)
			{
				GTK_stop_all ();
				if (SAMP_convert_sample_16_2_8 (GTK_sample_nbr))
				{
					INTR_dialog_box ("Error",
										  "Can't convert to 8 bits.",
										  "Cancel", 0, 0);
				}
				else
				{
					GTK_modified_flag = true;
				}
			}
		}

		refresh ();
		break;

	/* Tracks */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_TRKS:
		/* Conversion en stereo */
		if (SAMP_get_sample_stereo (GTK_sample_nbr) == 1)
		{
			if (INTR_dialog_box ("",
										"Do you really want to\n"
										"convert your sample\n"
										"in stereo \? Used memory\n"
										"will be twice bigger.",
										"OK\nCancel", 0, 1) == 0)
			{
				GTK_stop_all ();
				if (SAMP_convert_sample_mono_2_stereo (GTK_sample_nbr))
				{
					INTR_dialog_box ("Error",
										  "Can't convert in stereo.",
										  "Cancel", 0, 0);
				}
				else
				{
					GTK_modified_flag = true;
				}
			}
		}

		/* Conversion en mono */
		else
		{
			if (INTR_dialog_box ("",
										"Do you really want to\n"
										"convert your sample\n"
										"in mono \? It may lose\n"
										"spacial information.",
										"OK\nCancel", 0, 1) == 0)
			{
				GTK_stop_all ();
				if (SAMP_convert_sample_stereo_2_mono (GTK_sample_nbr))
				{
					INTR_dialog_box ("Error",
										  "Can't convert in mono.",
										  "Cancel", 0, 0);
				}
				else
				{
					GTK_modified_flag = true;
				}
			}
		}

		refresh ();
		break;

	/* Import format */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_IMPORTF:
		ret_code = SPLS_import_format_popup_menu_ptr->manage (-1);
		if (ret_code >= 0)
		{
			if (ret_code == 999)
			{
				strcpy (string_0, "*.*");
			}
			else if (ret_code == 998)
			{
				string_0 [0] = '\0';
				for (int cnt = 0; cnt < SPLS_nbr_formats; cnt ++)
				{
					if (SPLS_format_routines [cnt].import_flag)
					{
						strcat (string_0, SPLS_format_routines [cnt].ext_0);
						if (cnt + 1 < SPLS_nbr_formats)
						{
							strcat (string_0, ",");
						}
					}
				}
			}
			else
			{
				strcpy (string_0, SPLS_format_routines [ret_code].ext_0);
			}
			FILE_sample_maskname = string_0;
			refresh ();
		}
		break;

	/* Export format */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_EXPORTF:
		line = SPLS_export_format_popup_menu_ptr->select_radio_by_code (SPLS_export_format);
		ret_code = SPLS_export_format_popup_menu_ptr->manage (line);
		if (ret_code >= 0)
		{
			SPLS_export_format = ret_code;
			refresh ();
		}
		break;

	/* Signed */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SIGNED:
		SPLS_signed_flag = ! SPLS_signed_flag;
		refresh ();
		break;

	/* Load */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOAD:
		SPLS_load_sample ();
		GTK_modified_flag = true;
		refresh ();
		break;

	/* Save */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_SAVE:
		SPLS_save_sample ();
		refresh ();
		break;

	/* D2D */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_D2D:
		toggle_d2d ();
		refresh ();
		break;

	/* Kill */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_KILL:
		SAMP_get_sample_name (GTK_sample_nbr, name_0);
		sprintf (string_0,
		         "Do you really want to kill sample\n# %d ? (%s)",
		         GTK_sample_nbr, name_0);
		if (INTR_dialog_box ("KILL SAMPLE", string_0, "OK\nCancel", 0, 1) == 0)
		{
			SAMP_kill_sample (GTK_sample_nbr);
			GTK_modified_flag = true;
		}
		refresh ();
		MPAN_display_status (true);
		break;

	/* Length */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LEN_VAL:
		if (RSC_mouse_key & 2)
		{
			INTR_select_splpos_unit ();
			refresh ();
		}
		else
		{
			SAMP_set_sample_length_intr (INTR_CHGTYPE_KBD, 0);
		}
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LEN_UP:
		SAMP_set_sample_length_intr (INTR_CHGTYPE_REL, INTR_inc_speed [2] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LEN_DOWN:
		SAMP_set_sample_length_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [2] [RSC_mouse_key]);
		break;

	/* Repeat */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPEAT_VAL:
		if (RSC_mouse_key & 2)
		{
			INTR_select_splpos_unit ();
			refresh ();
		}
		else
		{
			SAMP_set_sample_repeat_intr (INTR_CHGTYPE_KBD, 0, false);
		}
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPEAT_UP:
		SAMP_set_sample_repeat_intr (INTR_CHGTYPE_REL, INTR_inc_speed [2] [RSC_mouse_key], true);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPEAT_DOWN:
		SAMP_set_sample_repeat_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [2] [RSC_mouse_key], true);
		break;

	/* Replen */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPLEN_VAL:
		if (RSC_mouse_key & 2)
		{
			INTR_select_splpos_unit ();
			refresh ();
		}
		else
		{
			SAMP_set_sample_replen_intr (INTR_CHGTYPE_KBD, 0, false);
		}
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPLEN_UP:
		SAMP_set_sample_replen_intr (INTR_CHGTYPE_REL, INTR_inc_speed [2] [RSC_mouse_key], true);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_REPLEN_DOWN:
		SAMP_set_sample_replen_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [2] [RSC_mouse_key], true);
		break;

	/* Repeat buffer */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_RBUF_VAL:
		if (RSC_mouse_key & 2)
		{
			INTR_select_splpos_unit ();
		}
		else
		{
			SAMP_set_sample_loopbuf_intr (INTR_CHGTYPE_KBD, 0);
		}
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_RBUF_UP:
		SAMP_set_sample_loopbuf_intr (INTR_CHGTYPE_REL, INTR_inc_speed [2] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_RBUF_DOWN:
		SAMP_set_sample_loopbuf_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [2] [RSC_mouse_key]);
		break;

	/* Midi note */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_MIDIN_VAL:
		SAMP_set_sample_midi_note_intr (INTR_CHGTYPE_KBD, 0);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_MIDIN_UP:
		SAMP_set_sample_midi_note_intr (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_MIDIN_DOWN:
		SAMP_set_sample_midi_note_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	/* Finetune */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FTUNE_VAL:
		SAMP_set_sample_finetune_intr (INTR_CHGTYPE_KBD, 0);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FTUNE_UP:
		SAMP_set_sample_finetune_intr (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_FTUNE_DOWN:
		SAMP_set_sample_finetune_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	/* Loop */
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NONE:
		SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_NONE, 0, 0);
		SAMP_make_buffers (GTK_sample_nbr);
		GTK_modified_flag = true;
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_NORM:
		if (length > 0)
		{
			SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_FWD, repeat, replen);
			SAMP_make_buffers (GTK_sample_nbr);
			GTK_modified_flag = true;
		}
		else
		{
			INTR_dialog_box ("SAMPLE LOOP",
								  "A null-length sample\n"
								  "can\'t be looped.",
								  "Cancel", 0, 0);
			SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_NONE, 0, 0);
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_LOOP_PP:
		if (length > 1)
		{
			SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_PP, repeat, replen);
			SAMP_make_buffers (GTK_sample_nbr);
			GTK_modified_flag = true;
		}
		else
		{
			INTR_dialog_box ("SAMPLE LOOP",
								  "A sample must have a length of 2 or\n"
								  "more to be looped in ping-pong mode.",
								  "Cancel", 0, 0);
			SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_NONE, 0, 0);
		}
		refresh ();
		break;

	// Group
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_VAL:
		SAMP_set_sample_group_intr (INTR_CHGTYPE_KBD, 0);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_UP:
		SAMP_set_sample_group_intr (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_DOWN:
		SAMP_set_sample_group_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	// Group name
	case	RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_NAME:
		{
			const int		group = SAMP_get_sample_group (GTK_sample_nbr);
			std::string		name = SAMP_get_group_name (group);
			const int		name_len_max = 32;
			char				gname_0 [name_len_max+1] = { '\0' };
			strncpy (gname_0, name.c_str (), name_len_max);
			if (EDIT_edit_string (
				gname_0,
				RSC_OBJ_MP_SUBM_SAMPLES_MAIN_GRP_NAME,
				name_len_max,
				EditString_TYPE_ALPHA
			) == 0)
			{
				SAMP_set_group_name (group, gname_0);
				GTK_modified_flag = true;
			}
			refresh ();
		}
		break;

	}
}



/*==========================================================================*/
/*      Nom: activate                                                       */
/*      Description: Active ou desactive le menu. Celui-ci n'est pas        */
/*                   reaffiche.                                             */
/*      Parametres en entree:                                               */
/*        - activated_flag: indique si le menu doit etre active ou          */
/*                          desactive.                                      */
/*==========================================================================*/

void	PatEdMenuSamplesMain::activate (bool activated_flag)
{
	RSC_pos_flag (RSC_OBJ_MP_SUBM_SAMPLES_MAIN, RSC_ATTR_NOTDISP, ! activated_flag);
	RSC_pos_flag (RSC_OBJ_MP_SUBM_SAMPLES_PICN_MAIN, RSC_ATTR_SELECTED, activated_flag);
}



/*\\\ METHODES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*==========================================================================*/
/*      Nom: toggle_d2d                                                     */
/*      Description: Change le sample conrant residant en memoire en D2D et */
/*                   vice-versa.                                            */
/*      Retour: 0 si tout s'est bien passe.                                 */
/*==========================================================================*/

signed int	PatEdMenuSamplesMain::toggle_d2d (void)
{
	int		convert;
	SPLS_PRIMARY_INFO	sample_info;
	String	total_name;
	char		*old_filename_0;
	FILE		*file_ptr;

/*______________________________________________
 *
 * Conversion Mem -> D2D
 *______________________________________________
 */

	if (SAMP_get_sample_type (GTK_sample_nbr) != 1)
	{
		/* Sample non vide */
		if (SAMP_get_sample_length (GTK_sample_nbr) > 0)
		{
			/* Convertir l'ancien ? */
			convert = INTR_dialog_box ("D2D SAMPLE CONVERSION",
												"Do you want to:\n"
												"- Convert on your disk the\n"
												"sample located in memory,\n"
												"- Abandon the sample in memory\n"
												"and create a new sample on the disk,\n"
												"- Or cancel D2D conversion \?",
												"Convert\nNew\nCancel", 0, 2);
			if (convert == 2)		/* Cancel */
			{
				return (0);
			}

			/* Selection du nom de fichier */
			if (SPLS_select_sample_filename (total_name, "Enter a (new) filename for D2D", true))
			{
				LOG_printf ("SSMSPL_toggle_d2d: Error: sample file selection failed.\n");
				return (-1);	/* Erreur lors de la selection du nom de fichier */
			}
			if (total_name == String(""))
			{
				return (0);
			}

			/* Conversion de l'ancien sample */
			if (convert == 0)
			{
				if (FILE_file_exist (total_name.c_str ()))
				{
					if (INTR_dialog_box ("D2D SAMPLE CONVERSION",
												"File already exists.\n"
												"Should I overwrite existing file \?",
												"OK\nCancel", 0, 1) == 1)
					{
						return (0);
					}
				}

				file_ptr = FILE_fopen (total_name.c_str (), "w+b");
				if (file_ptr == NULL)
				{
					LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't open sample file.\n");
					return (-1);	/* Erreur lors de la creation du fichier */
				}
				SAMP_set_sample_file_ptr (GTK_sample_nbr, file_ptr);

				/*** Conversion en RAW quoi qu'il en soit. A changer ***/
				if (SPLRAW_save_sample (file_ptr, GTK_sample_nbr))
				{
					LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't save sample.\n");
					SAMP_kill_sample (GTK_sample_nbr);
					return (-1);	/* Erreur lors de la sauvegarde (conversion) */
				}

				/* On convertit le chunk maintenant, en lisant le header sauve */
				if (SAMP_read_d2d_header (GTK_sample_nbr))
				{
					LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't read Direct-To-Disk file header.\n");
					SAMP_kill_sample (GTK_sample_nbr);
					return (-1);	/* Erreur lors de la conversion du chunk */
				}

				/* Il ne manque plus que le nom */
				if (SAMP_set_sample_d2d_filename (GTK_sample_nbr, total_name.c_str ()))
				{
					LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't set sample filename.\n");
					SAMP_kill_sample (GTK_sample_nbr);
					return (-1);	/* Erreur lors de la modification du nom */
				}
			}

			/* Pas de conversion de l'ancien sample */
			else
			{
				if (toggle_d2d_new_file (total_name.c_str ()))
				{
					LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't create a new Direct-To-Disk sample file.\n");
					return (-1);	/* Erreur durant la creation du fichier */
				}
			}
		}

		/* Sample vide */
		else
		{
			/* Choisir nom de fichier */
			if (SPLS_select_sample_filename (total_name, "Enter a (new) filename for D2D", true))
			{
				LOG_printf ("SSMSPL_toggle_d2d: Error: sample file selection failed.\n");
				return (-1);	/* Erreur lors de la selection du nom de fichier */
			}
			if (total_name == String (""))
			{
				return (0);
			}

			if (toggle_d2d_new_file (total_name.c_str ()))
			{
				LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't create a new Direct-To-Disk sample file.\n");
				return (-1);	/* Erreur durant la creation du fichier */
			}
		}
	}

/*______________________________________________
 *
 * Conversion D2D -> Mem
 *______________________________________________
 */

	else
	{
		convert = INTR_dialog_box ("D2D SAMPLE CONVERSION",
											"Do you want to:\n"
											"- Close the current file and\n"
											"create a new sample in memory,\n"
											"- Copy the sample from file to\n"
											"memory (if there is enough free memory),\n"
											"- Or cancel the operation \?",
											"New\nConvert\nCancel", 0, 2);

		if (convert == 2)
		{
			return (0);
		}

		old_filename_0 = STRDUP (SAMP_get_sample_d2d_filename (GTK_sample_nbr));

		/* Conversion en memoire */
		if (convert == 1)
		{
			file_ptr = SAMP_get_sample_file_ptr (GTK_sample_nbr);
			SPLS_init_primary_info (&sample_info, GTK_sample_nbr);
			sample_info.signed_flag = true;	/* Le sample de D2D est toujours signe */
			SAMP_kill_sample (GTK_sample_nbr);
			SAMP_set_sample_loop (GTK_sample_nbr, WaveForm_LOOP_TYPE_NONE, 0, 0);
			SAMP_set_sample_balance (GTK_sample_nbr, -1);
			SAMP_set_sample_volume (GTK_sample_nbr, 0x100);
			SAMP_set_sample_finetune (GTK_sample_nbr, 0);
			SAMP_set_sample_freq (GTK_sample_nbr, sample_info.freq);
			SAMP_set_sample_midi_note (GTK_sample_nbr, sample_info.midi_note);
			if (SPLRAW_load_sample (file_ptr, GTK_sample_nbr, &sample_info))
			{
				LOG_printf ("SSMSPL_toggle_d2d: Error: couldn't load Direct-To-Disk sample file.\n");
				FREE (old_filename_0);
				SAMP_kill_sample (GTK_sample_nbr);
				INTR_dialog_box ("D2D SAMPLE CONVERSION",
									  "Can't convert sample.",
									  "Cancel", 0, 0);
				return (-1); 	/* Erreur de chargement */
			}

			fclose (file_ptr);
			SAMP_set_sample_file_ptr (GTK_sample_nbr, NULL);

			SAMP_set_sample_loop (GTK_sample_nbr, sample_info.loop_type,
			                                      sample_info.repeat,
			                                      sample_info.replen);
			SAMP_make_buffers (GTK_sample_nbr);
		}

		/* Nouveau sample */
		else
		{
			SAMP_kill_sample (GTK_sample_nbr);
		}

		/* Destruction du fichier */
		if (INTR_dialog_box ("D2D SAMPLE CONVERSION",
									"Delete the old sample file\?",
									"OK\nCancel", 0, 1) == 0)
		{
			if (remove (old_filename_0))
			{
				INTR_dialog_box ("DELETE FILE",
									  "Can't delete the old sample file.",
									  "Cancel", 0, 0);
			}
		}

		FREE (old_filename_0);
	}

	GTK_modified_flag = true;

	return (0);
}



signed int	PatEdMenuSamplesMain::toggle_d2d_new_file (const char *filename_0)
{
	int		button;
	FILE		*file_ptr;

	/* Si fichier existe */
	if (FILE_file_exist (filename_0))
	{
		button = INTR_dialog_box ("D2D SAMPLE CONVERSION",
										  "File already exists. Do you want to:\n"
										  "- Use the selected file,\n"
										  "- Overwrite this file and create\n"
										  "a new sample,\n"
										  "- Or cancel D2D conversion \?",
										  "Use\nNew\nCancel", 0, 2);

		/* Annulation */
		if (button == 2)
		{
			return (0);
		}

		/* Nouveau */
		else if (button == 1)
		{
			/* Ecraser et nouveau fichier vide */
			file_ptr = FILE_fopen (filename_0, "w+b");
			fclose (file_ptr);
		}
	}

	/* Fichier n'existe pas */
	else
	{
		/* Nouveau fichier vide */
		file_ptr = FILE_fopen (filename_0, "w+b");
		fclose (file_ptr);
	}

	if (SAMP_use_file_for_d2d (GTK_sample_nbr, filename_0))
	{
		INTR_dialog_box ("D2D SAMPLE CONVERSION",
		                 "Sorry, I can't use this sample (inappropriate\n"
		                 "format or corrupted file). Samples must be in\n"
		                 "signed PCM format, in "
		#if (OS_BYTE_ORDER == 0)
		                 "Big Endian (Motorola)\n"
		#else
		                 "Little Endian (Intel)\n"
		#endif
		                 "byte order.",
		                 "Cancel", 0, 0);
		return (-1);
	}

	return (0);
}



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



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