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

GRAOUMF TRACKER 2

Copyright (c) 1996 - 2002 Laurent de Soras

This program 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Contact the author : laurent@ohmforce.com
More information about this license : http://www.gnu.org/licenses/gpl.html

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



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

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

#include	"base.h"
#include	"base_ct.h"
#include	"edstring.h"
#include	"intrface.h"
#include	"log.h"
#include	"os.h"
#include	"PatEdMenuPrefPlayer.h"
#include	"player.h"
#include	"Popup.h"
#include	"resource.h"
#include	"rsc01.h"
#include	"SoundDriver.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	PatEdMenuPrefPlayer::check_ok (void) const
{
	if (this == NULL)
	{
		LOG_printf ("PatEdMenuPrefPlayer::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	PatEdMenuPrefPlayer::self_display (void) const
{

	/*** A faire ***/

}



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

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

	refresh ();
}



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

void	PatEdMenuPrefPlayer::refresh (void)
{
	/* Period slides */
	const Player &	player = Player::use_instance ();
	if (player.get_linear_period_flag ())
	{
		RSC_select_radio_button_display (RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_LINEAR,
													RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_AMIGA);
	}
	else
	{
		RSC_select_radio_button_display (RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_AMIGA,
													RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_AMIGA);
	}

	/* Latency time */
	char			nbr4_0 [4+1];
	const int	latency = OS_sound_driver.get_latency ();
	sprintf (nbr4_0, "%4d", latency);
	RSC_set_string (RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_NBR_VAL, nbr4_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_NBR_VAL);

	refresh_dynamic (true);
}



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

void	PatEdMenuPrefPlayer::refresh_dynamic (bool force_flag)
{

	/*** A faire ***/

}



/*==========================================================================*/
/*      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	PatEdMenuPrefPlayer::manage (int sel_object, int sel_elder)
{
	Player &			player = Player::use_instance ();

	switch (sel_object)
	{
	/* Amiga period slides */
	case	RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_AMIGA:
		player.set_linear_period_flag (false);
		refresh ();
		break;

	/* Linear period slides */
	case	RSC_OBJ_MP_SUBM_PREF_PLAY_PSL_LINEAR:
		player.set_linear_period_flag (true);
		refresh ();
		break;

	/* Latency time */
	case	RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_NBR:
		if (RSC_mouse_key & 2)
		{
			set_latency (INTR_CHGTYPE_POP, 0);
		}
		else
		{
			set_latency (INTR_CHGTYPE_KBD, 0);
		}
		break;

	case	RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_U:
		set_latency (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_D:
		set_latency (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		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	PatEdMenuPrefPlayer::activate (bool activated_flag)
{
	RSC_pos_flag (RSC_OBJ_MP_SUBM_PREF_PLAY, RSC_ATTR_NOTDISP, ! activated_flag);
	RSC_pos_flag (RSC_OBJ_MP_SUBM_PREF_PICN_PLAY, RSC_ATTR_SELECTED, activated_flag);
}



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



/*==========================================================================*/
/*      Nom: set_latency                                                    */
/*      Description: Change le temps de latence du driver son 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,                                    */
/*                3 = Entree au pop-up.                                     */
/*        - value: le parametre en question.                                */
/*      Retour: 0 si tout s'est bien passe.                                 */
/*==========================================================================*/

signed int	PatEdMenuPrefPlayer::set_latency (int type, signed long value)
{
	long		new_value;
	signed int	line;
	signed long	code;
	char		nbr4_0 [4+1];
	Popup		popup_menu;

	new_value = OS_sound_driver.get_latency ();

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

	/* Entree au clavier */
	case	INTR_CHGTYPE_KBD:
		sprintf (nbr4_0, "%4d", (int)new_value);
		EDIT_edit_string_base (nbr4_0, RSC_OBJ_MP_SUBM_PREF_PLAY_DRIVER_LAT_NBR_VAL, 4, 10);
		new_value = strtol (nbr4_0, NULL, 10);
		break;

	/* Position absolue  */
	case	INTR_CHGTYPE_ABS:
		new_value = value;
		break;

	/* Pop-up */
	case	INTR_CHGTYPE_POP:
		const int	time_arr [] =
		{
			0, 5, 10, 15, 20, 25, 30, 50, 70, 100, 150, 200, 250, 300, 400, 500
		};
		const int	time_arr_len = sizeof (time_arr) / sizeof (*time_arr);
		for (int i = 0; i < time_arr_len; ++i)
		{
			char	line_0 [15+1];
			sprintf (line_0, "%4d ms", time_arr [i]);
			popup_menu.add_line (line_0, time_arr [i]);
		}
		line = popup_menu.select_radio_by_code (new_value);
		code = popup_menu.manage (line);
		if (code >= 0)
		{
			new_value = code;
		}
		break;
	}

	new_value = MIN (new_value, SoundDriver::MAX_LATENCY);
	new_value = MAX (new_value, 0);
	if (OS_sound_driver.set_latency (new_value))
	{
		LOG_printf ("PatEdMenuPrefPlayer::set_latency: Error: "
		            "Couldn't set latency time to %ld ms.\n", new_value);
		return (-1);
	}
	refresh ();

	return (0);
}



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



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