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

        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	"base.h"
#include	"base.hpp"
#include	"base_ct.h"
#include	"EditString.h"
#include	"edstring.h"
#include	"gtracker.h"
#include	"inst.h"
#include	"intrface.h"
#include	"log.h"
#include	"mpannel.h"
#include	"PatEdMenuInstrMain.h"
#include	"resource.h"
#include	"rsc01.h"
#include	"samp.h"
#include	"sliders.h"



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



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

const int	PatEdMenuInstrMain::ENV_OBJECTS [Envelope_NBR_TYPES] =
{
	RSC_OBJ_MP_SUBM_INSTR_MAIN_ENV_VOL_CB,
	RSC_OBJ_MP_SUBM_INSTR_MAIN_ENV_TON_CB,
	RSC_OBJ_MP_SUBM_INSTR_MAIN_ENV_PAN_CB,
	RSC_OBJ_MP_SUBM_INSTR_MAIN_ENV_CUTOFF_CB,
	RSC_OBJ_MP_SUBM_INSTR_MAIN_ENV_RESO_CB
};



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



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



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



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



/*==========================================================================*/
/*      Nom: (constructeur)                                                 */
/*      Description: Initialise                                             */
/*      Parametres en entree:                                               */
/*      Parametres en sortie:                                               */
/*      Parametres en entree/sortie:                                        */
/*==========================================================================*/

PatEdMenuInstrMain::PatEdMenuInstrMain (void)
{
	const SLID_INFO	window_slider =
	{
		RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SBAR,
		RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SBAR_SLIDER,
		0, 0, 0, 0, 0, -1,
		SLID_DIRECTION_VERTICAL,
		false, false, 0, 0
	};

	_window_slider = window_slider;
	_win_pos = Sample_REF_C2;
	_curs_pos = Sample_REF_C2;
	_group_flag = true;
}



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

signed int	PatEdMenuInstrMain::check_ok (void) const
{
	if (this == NULL)
	{
		LOG_printf ("PatEdMenuInstrMain::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	PatEdMenuInstrMain::self_display (void) const
{

	/*** A faire ***/

}



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

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

	refresh ();
}



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

void	PatEdMenuInstrMain::refresh (void)
{
	int		note;
	int		line;
	int		color;
	int		sample;
	int		win_ypos;
	int		spl_win_xpos;
	int		names_win_xpos;
	int		notes_win_xpos;
	int		trans_win_xpos;
	int		name_len;
	int		nbr_lines;
	int		env_type;
	bool		filter_flag;
	signed int	transposition;
	char		name_0 [Sample_NAME_LEN+1];
	char		nbr3_0 [3+1];
	char		nbr6_0 [6+1];

	/* Fenetre spl/note/transp */
	win_ypos = RSC_absolute_object_pixypos [RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SPL];
	spl_win_xpos = RSC_absolute_object_pixxpos [RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SPL];
	names_win_xpos = RSC_absolute_object_pixxpos [RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_NAMES];
	notes_win_xpos = RSC_absolute_object_pixxpos [RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_NOTES];
	trans_win_xpos = RSC_absolute_object_pixxpos [RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_TRANS];
	name_len = RSC_get_width (RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_NAMES) / RSC_CHAR_W;

	note = _win_pos;
	nbr_lines = RSC_get_height (RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SPL) / RSC_CHAR_H;
	for (line = 0; line < nbr_lines; line ++)
	{
		/* Couleur du texte */
		if (note == _curs_pos)
		{
			color = 2;
		}
		else
		{
			color = 1;
		}

		/* Numero du sample */
		sample = INST_get_instr_sample (GTK_instr_nbr, _win_pos + line);
		sprintf (nbr3_0, INTR_base_song_3, sample);
		INTR_graph_ptr->display_string (nbr3_0, spl_win_xpos, win_ypos, color);

		/* Nom du sample */
		SAMP_get_sample_name (sample, name_0);
		name_0 [name_len] = 0;
		INTR_graph_ptr->display_string (name_0, names_win_xpos, win_ypos, color);

		/* Nom de la note */
		INTR_graph_ptr->display_string (INTR_note_names [note], notes_win_xpos, win_ypos, color);

		/* Transposition */
		transposition = INST_get_instr_transp (GTK_instr_nbr, _win_pos + line);
		if (transposition < 0)
		{
			sprintf (nbr3_0, "-%2d", -transposition);
		}
		else
		{
			sprintf (nbr3_0, "+%2d", transposition);
		}
		INTR_graph_ptr->display_string (nbr3_0, trans_win_xpos, win_ypos, color);

		note ++;
		win_ypos += RSC_CHAR_H;
	}

	/* Libere l'ecran qu'on vient d'utiliser */
	INTR_graph_ptr->unlock_screen ();

	/* Ascenseur de la fenetre */
	_window_slider.virtual_len = GTK_NBRNOTES_MAXI - 1;
	_window_slider.virtual_pos = _win_pos - 1;
	_window_slider.virtual_win = nbr_lines;
	SLID_display_slider (&_window_slider);

	/* Group */
	RSC_select_object_display (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_GRP,
										_group_flag);

	/* From note */
	note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FROM_VAL, INTR_note_names [note]);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FROM_VAL);

	/* To note */
	note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_TO_VAL, INTR_note_names [note]);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_TO_VAL);

	/* Volume */
	sprintf (nbr3_0, "%3X", INST_get_instr_volume (GTK_instr_nbr));
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_VOL_VAL, nbr3_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_VOL_VAL);

	/* Envelopes */
	for (env_type = 0; env_type < Envelope_NBR_TYPES; env_type ++)
	{
		RSC_select_object_display (ENV_OBJECTS [env_type],
		                           INST_get_instr_env (GTK_instr_nbr, env_type) != 0);
	}

	/* Filtre */
	filter_flag = INST_get_filter_flag (GTK_instr_nbr);
	RSC_select_object_display (RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FILTER_CB,
	                           filter_flag);
	RSC_select_object_display (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_FREQ_CB,
	                           INST_get_filter_freq_vol_flag (GTK_instr_nbr) && filter_flag);
	RSC_select_object_display (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_RESO_CB,
	                           INST_get_filter_q_vol_flag (GTK_instr_nbr) && filter_flag);

	/* Frequence a vol max */
	if (filter_flag)
	{
		INTR_freq_2_string (nbr6_0, INTR_freq_unit,
		                    INST_get_filter_freq (GTK_instr_nbr, 0), 6);
	}
	else
	{
		*nbr6_0 = '\0';
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_FREQ_VAL, nbr6_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_FREQ_VAL);

	/* Resonnance a vol max */
	if (filter_flag)
	{
		BASE_double_to_fix (nbr6_0, BASE_lin_to_db (INST_get_filter_q (GTK_instr_nbr, 0)), 3, 2);
	}
	else
	{
		*nbr6_0 = '\0';
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_RESO_VAL, nbr6_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_RESO_VAL);

	/* Frequence a vol min */
	if (filter_flag && INST_get_filter_freq_vol_flag (GTK_instr_nbr))
	{
		INTR_freq_2_string (nbr6_0, INTR_freq_unit,
		                    INST_get_filter_freq (GTK_instr_nbr, 1), 6);
	}
	else
	{
		*nbr6_0 = '\0';
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_FREQ_VAL, nbr6_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_FREQ_VAL);

	/* Resonnance a vol min */
	if (filter_flag && INST_get_filter_q_vol_flag (GTK_instr_nbr))
	{
		BASE_double_to_fix (nbr6_0, BASE_lin_to_db (INST_get_filter_q (GTK_instr_nbr, 1)), 3, 2);
	}
	else
	{
		*nbr6_0 = '\0';
	}
	RSC_set_string (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_RESO_VAL, nbr6_0);
	RSC_display_object (RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_RESO_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	PatEdMenuInstrMain::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	PatEdMenuInstrMain::manage (int sel_object, int sel_elder)
{
	int		offset;
	int		sample;
	int		note;
	int		envelope;
	int		start_note;
	int		end_note;
	int		nbr_lines;
	int		env_type;
	signed int	transp;
	double	value;
	bool		filter_flag;
	char		nbr6_0 [6+1];

	nbr_lines = RSC_get_height (RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SPL) / RSC_CHAR_H;
	filter_flag = INST_get_filter_flag (GTK_instr_nbr);
	
	switch (sel_object)
	{

	/* Fenetre */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SPL:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_NAMES:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_TRANS:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_NOTES:
		offset = (INTR_mouse.y - RSC_absolute_object_pixypos [sel_object]) / RSC_CHAR_H;
		_curs_pos = _win_pos + offset;
		_curs_pos = MIN (_curs_pos, GTK_NBRNOTES_MAXI - 1);
		_curs_pos = MAX (_curs_pos, 1);
		refresh ();
		break;

	/* Ascenseur, fleche vers le haut ou le bas */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_UP:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_DOWN:
		if (sel_object == RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_UP)
		{
			_curs_pos -= INTR_inc_speed [0] [RSC_mouse_key];
		}
		else
		{
			_curs_pos += INTR_inc_speed [0] [RSC_mouse_key];
		}
		_curs_pos = MIN (_curs_pos, GTK_NBRNOTES_MAXI - 1);
		_curs_pos = MAX (_curs_pos, 1);
		_win_pos = MAX (_win_pos, _curs_pos - (nbr_lines - 1));
		_win_pos = MIN (_win_pos, _curs_pos);
		refresh ();
		break;

	/* Ascenseur */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SBAR:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SBAR_SLIDER:
		SLID_gere_slider (&_window_slider, sel_object);
		if (_window_slider.changed_pos_flag)
		{
			nbr_lines = _window_slider.virtual_win;
			_win_pos = MIN (_window_slider.virtual_pos + 1,
			                      GTK_NBRNOTES_MAXI - 1 - (nbr_lines - 1));
			_win_pos = MAX (_win_pos, 1);
			_curs_pos = MIN (_curs_pos, _win_pos + (nbr_lines - 1));
			_curs_pos = MAX (_curs_pos, _win_pos);
			refresh ();
		}
		break;

	/* Sample: up */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SMOD_UP:
		sample =   INST_get_instr_sample (GTK_instr_nbr, _curs_pos)
					+ INTR_inc_speed [0] [RSC_mouse_key];
		sample = MIN (sample, SAMP_NBRSAMPLES_MAXI);
		sample = MAX (sample, 1);
		if (_group_flag)
		{
			start_note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
			end_note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
		}
		else
		{
			start_note = _curs_pos;
			end_note = _curs_pos;
		}
		for (note = start_note; note <= end_note; note ++)
		{
			INST_set_instr_sample (GTK_instr_nbr, note, sample);
		}
		GTK_modified_flag = true;
		MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
		break;

	/* Sample: down */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_SMOD_DOWN:
		sample =   INST_get_instr_sample (GTK_instr_nbr, _curs_pos)
					- INTR_inc_speed [0] [RSC_mouse_key];
		sample = MIN (sample, SAMP_NBRSAMPLES_MAXI);
		sample = MAX (sample, 1);
		if (_group_flag)
		{
			start_note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
			end_note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
		}
		else
		{
			start_note = _curs_pos;
			end_note = _curs_pos;
		}
		for (note = start_note; note <= end_note; note ++)
		{
			INST_set_instr_sample (GTK_instr_nbr, note, sample);
		}
		GTK_modified_flag = true;
		MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
		break;

	/* Transpose: up & down */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_TMOD_UP:
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_TMOD_DOWN:
		transp = INST_get_instr_transp (GTK_instr_nbr, _curs_pos);
		if (sel_object == RSC_OBJ_MP_SUBM_INSTR_MAIN_WIN_TMOD_UP)
		{
			transp += INTR_inc_speed [0] [RSC_mouse_key];
		}
		else
		{
			transp -= INTR_inc_speed [0] [RSC_mouse_key];
		}
		transp = MIN (transp, 99);
		transp = MAX (transp, -99);
		if (_group_flag)
		{
			start_note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
			end_note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
		}
		else
		{
			start_note = _curs_pos;
			end_note = _curs_pos;
		}
		for (note = start_note; note <= end_note; note ++)
		{
			INST_set_instr_transp (GTK_instr_nbr, note, transp);
		}
		GTK_modified_flag = true;
		refresh ();
		break;

	/* Group */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_GRP:
		_group_flag = ! _group_flag;
		refresh ();
		break;

	/* From: up */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FROM_UP:
		start_note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
		if (start_note > 1 && start_note < _curs_pos)
		{
			end_note = MIN (start_note + INTR_inc_speed [0] [RSC_mouse_key] - 1,
								 _curs_pos - 1);
			sample = INST_get_instr_sample (GTK_instr_nbr, start_note - 1);
			transp = INST_get_instr_transp (GTK_instr_nbr, start_note - 1);
			for (note = start_note; note <= end_note; note ++)
			{
				INST_set_instr_sample (GTK_instr_nbr, note, sample);
				INST_set_instr_transp (GTK_instr_nbr, note, transp);
			}
			GTK_modified_flag = true;
			MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
		}
		break;

	/* From: down */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FROM_DOWN:
		end_note = INST_get_instr_zone_start (GTK_instr_nbr, _curs_pos);
		if (end_note > 1)
		{
			start_note = MAX (end_note - INTR_inc_speed [0] [RSC_mouse_key], 1);
			sample = INST_get_instr_sample (GTK_instr_nbr, _curs_pos);
			transp = INST_get_instr_transp (GTK_instr_nbr, _curs_pos);
			for (note = start_note; note < end_note; note ++)
			{
				INST_set_instr_sample (GTK_instr_nbr, note, sample);
				INST_set_instr_transp (GTK_instr_nbr, note, transp);
			}
			GTK_modified_flag = true;
			MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
		}
		break;

	/* To: up */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_TO_UP:
		start_note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
		if (start_note < GTK_NBRNOTES_MAXI - 1)
		{
			end_note = MIN (start_note + INTR_inc_speed [0] [RSC_mouse_key], GTK_NBRNOTES_MAXI - 1);
			sample = INST_get_instr_sample (GTK_instr_nbr, _curs_pos);
			transp = INST_get_instr_transp (GTK_instr_nbr, _curs_pos);
			for (note = start_note + 1; note <= end_note; note ++)
			{
				INST_set_instr_sample (GTK_instr_nbr, note, sample);
				INST_set_instr_transp (GTK_instr_nbr, note, transp);
			}
			GTK_modified_flag = true;
			MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
		}
		break;

	/* To: down */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_TO_DOWN:
		end_note = INST_get_instr_zone_end (GTK_instr_nbr, _curs_pos);
		if (   end_note < GTK_NBRNOTES_MAXI - 1
		    && end_note > _curs_pos)
		{
			start_note = MAX (end_note - INTR_inc_speed [0] [RSC_mouse_key] + 1,
								 _curs_pos + 1);
			sample = INST_get_instr_sample (GTK_instr_nbr, start_note + 1);
			transp = INST_get_instr_transp (GTK_instr_nbr, start_note + 1);
			for (note = start_note; note <= end_note; note ++)
			{
				INST_set_instr_sample (GTK_instr_nbr, note, sample);
				INST_set_instr_transp (GTK_instr_nbr, note, transp);
			}
			MPAN_set_instrument_number (INTR_CHGTYPE_REL, 0, 0);	// En cas d'interdependance instrument-sample
			GTK_modified_flag = true;
		}
		break;

	/* Volume */
	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_VOL_VAL:
		if (RSC_mouse_key == 2)
		{
			INST_set_instr_volume_intr (INTR_CHGTYPE_POP, 0);
		}
		else
		{
			INST_set_instr_volume_intr (INTR_CHGTYPE_KBD, 0);
		}
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_VOL_UP:
		INST_set_instr_volume_intr (INTR_CHGTYPE_REL, INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_VOL_DOWN:
		INST_set_instr_volume_intr (INTR_CHGTYPE_REL, -INTR_inc_speed [0] [RSC_mouse_key]);
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_GRP_FILTER_CB:
		INST_set_filter_flag (GTK_instr_nbr, ! INST_get_filter_flag (GTK_instr_nbr));
		GTK_modified_flag = true;
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_FREQ_CB:
		if (filter_flag)
		{
			INST_set_filter_freq_vol_flag (GTK_instr_nbr, ! INST_get_filter_freq_vol_flag (GTK_instr_nbr));
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_RESO_CB:
		if (filter_flag)
		{
			INST_set_filter_q_vol_flag (GTK_instr_nbr, ! INST_get_filter_q_vol_flag (GTK_instr_nbr));
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_FREQ:
		if (filter_flag)
		{
			value = INST_get_filter_freq (GTK_instr_nbr, 0);
			INTR_set_freq_intr (INTR_CHGTYPE_KBD, 0,
			                    RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_FREQ_VAL,
			                    INTR_freq_unit, value);
			value = MAX (value, 0.01);
			INST_set_filter_freq (GTK_instr_nbr, 0, value);
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_RESO:
		if (filter_flag)
		{
			BASE_double_to_fix (nbr6_0, BASE_lin_to_db (INST_get_filter_q (GTK_instr_nbr, 0)), 3, 2);
			EDIT_edit_string (nbr6_0, RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MAXV_RESO_VAL,
			                  6, EditString_TYPE_FLO);
			if (sscanf (nbr6_0, "%lf", &value) == 1)
			{
				value = MIN (value, 80.0);
				value = MAX (value, -80.0);
				INST_set_filter_q (GTK_instr_nbr, 0, BASE_db_to_lin (value));
				GTK_modified_flag = true;
			}
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_FREQ:
		if (filter_flag && INST_get_filter_freq_vol_flag (GTK_instr_nbr))
		{
			value = INST_get_filter_freq (GTK_instr_nbr, 1);
			INTR_set_freq_intr (INTR_CHGTYPE_KBD, 0,
			                    RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_FREQ_VAL,
			                    INTR_freq_unit, value);
			value = MAX (value, 0.01);
			INST_set_filter_freq (GTK_instr_nbr, 1, value);
			GTK_modified_flag = true;
		}
		refresh ();
		break;

	case	RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_RESO:
		if (filter_flag && INST_get_filter_q_vol_flag (GTK_instr_nbr))
		{
			BASE_double_to_fix (nbr6_0, BASE_lin_to_db (INST_get_filter_q (GTK_instr_nbr, 1)), 3, 2);
			EDIT_edit_string (nbr6_0, RSC_OBJ_MP_SUBM_INSTR_MAIN_FILTER_MINV_RESO_VAL,
			                  6, EditString_TYPE_FLO);
			if (sscanf (nbr6_0, "%lf", &value) == 1)
			{
				value = MIN (value, 80.0);
				value = MAX (value, -80.0);
				INST_set_filter_q (GTK_instr_nbr, 1, BASE_db_to_lin (value));
				GTK_modified_flag = true;
			}
		}
		refresh ();
		break;

	/* Les envelopes */
	default:
		for (env_type = 0; env_type < Envelope_NBR_TYPES; env_type ++)
		{
			if (sel_object == ENV_OBJECTS [env_type])
			{
				envelope =   (INST_get_instr_env (GTK_instr_nbr, env_type) == 0)
				           ? GTK_instr_nbr : 0;
				INST_set_instr_env_intr (INTR_CHGTYPE_ABS, envelope, env_type);
				break;
			}
		}
		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	PatEdMenuInstrMain::activate (bool activated_flag)
{
	RSC_pos_flag (RSC_OBJ_MP_SUBM_INSTR_MAIN, RSC_ATTR_NOTDISP, ! activated_flag);
	RSC_pos_flag (RSC_OBJ_MP_SUBM_INSTR_PICN_MAIN, RSC_ATTR_SELECTED, activated_flag);
}



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



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



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