/*****************************************************************************
  Matrix GUI JavaScript for expert users.
  2009/03/18 Yonebayashi
*****************************************************************************/

var user_mode = null;
var periods = 1;     // number of periods

/*
 * Set the user mode (easy/expert).
 * @param mode 'expert' or 'easy'
 */
function userMode(mode) {
	var genre = document.getElementById('genre_box');
	var lyric = document.getElementById('lyric_box');
	var easy = document.getElementById('easy_view');
	var expert = document.getElementById('matrix_view');

	user_mode = mode;
	if (user_mode == '') {   // when the first visit
		user_mode = document.getElementById('usermode_in').value;
		if (user_mode == '') { user_mode = 'easy'; }
		
		if (user_mode == 'easy') {
			setGenre();
		} else if (user_mode == 'expert') {
			// we can consider that the server 'modified' the options
			// from the genre default
			matrix.option_modified = true;
			matrix.update_column();
		}
	}
	
	if (user_mode == 'easy') { // when returning from the expert mode
		// set to 'easy' mode
		genre.style.display = 'block';
		lyric.style.display = 'block';
		easy.style.display = 'block';
		expert.style.display = 'none';
	} else if (user_mode == 'expert') {  // when moving into the expert mode
		// set to 'expert' mode
		genre.style.display = 'none';
		lyric.style.display = 'none';
		easy.style.display = 'none';
		expert.style.display = 'block';
		
		// display the genre description in the 'detail' compo-box
		document.getElementById('genre_description').innerHTML 
		= getGenreDescription();
	}
}

// RegExp object counting non-empty lines
var regexp = new RegExp(".*[^ \t\r\n\f]+[ \t\r\n\f]*$", "gm");

function debug_regexp() {
	var result = "aaa\n b\nccc".match(regexp);
	for (i = 0 ; i < result.length ; i++) {
		window.alert(result[i]);
	}
}

function ellipsis_string(str, max_length) {
	var temp = new String(str);
	return ((temp.length <= max_length) 
	        ? temp 
	        : (temp.substring(0, max_length - 2) + "...."));
}

/* matrix GUI data */
var matrix = {
	
	option_modified: false,
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the lyrics */
	lyric_value: [
		"",
		"",
		""
	],
	
	/* list of short descriptions of the lyrics */
	lyric_desc: [
		"",
		"",
		""
	],
	
	/* list of HTML input element IDs for the lyric param values */
	lyric_input: [
		"lyric_in1",  // for period 1
		"lyric_in2",  // for period 2
		"lyric_in3"   // for period 3
	],
	
	/* list of HTML element IDs for displaying the descriptions */
	lyric_elm: [
		'lyric1',     // for period 1
		'lyric2',     // for period 2
		'lyric3'      // for period 3
	],
	
	/* 
	 * Save a lyric parameter input into the matrix.
	 * @param value  lyric text
	 */
	save_lyric: function(value){
		var description = ellipsis_string(value, 12);
		
		matrix.lyric_value[matrix.period] = value;
		matrix.lyric_desc[matrix.period] = description;
		document.getElementById(matrix.lyric_elm[matrix.period]).innerHTML 
		= description;
	},
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the rhythm param values */
	rhythm_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of HTML input element IDs for the rhythm param values */
	rhythm_input: [
		"rhythm_in1",  // for period 1
		"rhythm_in2",  // for period 2
		"rhythm_in3"   // for period 3
	],
	
	/* list of HTML element IDs for displaying the descriptions */
	rhythm_elm: [
		'rhythm1',     // for period 1
		'rhythm2',     // for period 2
		'rhythm3'      // for period 3
	],
	
	/* 
	 * Save a rhythm parameter input into the matrix.
	 * @param value        rhythm value ("0", "1", etc.)
	 */
	save_rhythm: function(value){
		matrix.rhythm_value[matrix.period] = value;
		document.getElementById(matrix.rhythm_elm[matrix.period]).innerHTML 
		= get_selection_description(rhythm_selections, value);
		
		matrix.option_modified = true;
	},
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the chords param values */
	chords_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	], 
	
	/* list of HTML input element IDs for the chords param values */
	chords_input: [
		"chords_in1",    // for period 1
		"chords_in2",    // for period 2
		"chords_in3"     // for period 3
	], 
	
	/* list of HTML element IDs for displaying the descriptions */
	chords_elm: [
		'chords1',     // for period 1
		'chords2',     // for period 2
		'chords3'      // for period 3
	], 
	
	/* 
	 * Save a chords parameter input into the matrix.
	 * @param value        chords value ("0", "1", etc.)
	 */
	save_chords: function(value){
		matrix.chords_value[matrix.period] = value;
		document.getElementById(matrix.chords_elm[matrix.period]).innerHTML 
		= get_selection_description(chords_selections, value);
		
		matrix.option_modified = true;
	},
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the acmp-style param values */
	acmp_style_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of the acmp-prog param values */
	acmp_prog_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of HTML input element IDs for the acmp-style param values */
	acmp_style_input: [
		"acmp_style_in1",    // for period 1
		"acmp_style_in2",    // for period 2
		"acmp_style_in3"     // for period 3
	],
	
	/* list of HTML input element IDs for the acmp-prog param values */
	acmp_prog_input: [
		"acmp_prog_in1",    // for period 1
		"acmp_prog_in2",    // for period 2
		"acmp_prog_in3"     // for period 3
	],
	
	/* list of HTML element IDs for displaying the descriptions */
	acmp_elm: [
		'acmp_main1', // for period 1
		'acmp_main2', // for period 2
		'acmp_main3'  // for period 3
	],
	
	/* 
	 * Save acmp-style/acmp-prog parameters input into the matrix.
	 * @param prog_value        acmp-prog value ("0", "1", etc.)
	 * @param style_value       acmp-style value ("0", "1", etc.)
	 */
	save_acmp: function(prog_value, style_value){
		matrix.acmp_prog_value[matrix.period] = prog_value;
		matrix.acmp_style_value[matrix.period] = style_value;
		
		var desc;
		var prog_desc 
		= get_selection_description(acmp_prog_selections, prog_value);
		var style_desc 
		= get_selection_description(acmp_style_selections, style_value);
		
		if (style_desc != EMPTY_ACMP) {
			desc = new String(prog_desc);
			desc = desc.concat(":");
			desc = desc.concat(style_desc);
		} else {
			desc = new String(EMPTY_ACMP);
		}
		
		document.getElementById(matrix.acmp_elm[matrix.period]).innerHTML 
		= ellipsis_string(desc, 10);
		
		matrix.option_modified = true;
	},
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the acmp-style param values */
	acmp_style_amb_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of the acmp-prog param values */
	acmp_prog_amb_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of HTML input element IDs for the acmp-style param values */
	acmp_style_amb_input: [
		"acmp_style_amb_in1",    // for period 1
		"acmp_style_amb_in2",    // for period 2
		"acmp_style_amb_in3"     // for period 3
	],
	
	/* list of HTML input element IDs for the acmp-prog param values */
	acmp_prog_amb_input: [
		"acmp_prog_amb_in1",    // for period 1
		"acmp_prog_amb_in2",    // for period 2
		"acmp_prog_amb_in3"     // for period 3
	],
	
	/* list of HTML element IDs for displaying the descriptions */
	acmp_amb_elm: [
		'acmp_amb1', // for period 1
		'acmp_amb2', // for period 2
		'acmp_amb3'  // for period 3
	],
	
	/* 
	 * Save acmp-style/acmp-prog parameters input into the matrix.
	 * @param prog_value        acmp-prog value ("0", "1", etc.)
	 * @param style_value       acmp-style value ("0", "1", etc.)
	 */
	save_acmp_amb: function(prog_value, style_value){
		matrix.acmp_prog_amb_value[matrix.period] = prog_value;
		matrix.acmp_style_amb_value[matrix.period] = style_value;
		
		var desc;
		var prog_desc 
		= get_selection_description(acmp_prog_amb_selections, prog_value);
		var style_desc 
		= get_selection_description(acmp_style_amb_selections, style_value);
		
		if (style_desc != EMPTY_ACMP) {
			desc = new String(prog_desc);
			desc = desc.concat(":");
			desc = desc.concat(style_desc);
		} else {
			desc = new String(EMPTY_ACMP);
		}
		
		document.getElementById(matrix.acmp_amb_elm[matrix.period]).innerHTML 
		= ellipsis_string(desc, 10);
		
		matrix.option_modified = true;
	},
	
	///////////////////////////////////////////////////////////////////////////
	
	/* list of the perc param values */
	perc_value: [
		"0",           // for period 1
		"0",           // for period 2
		"0"            // for period 3
	],
	
	/* list of HTML input element IDs for the perc param values */
	perc_input: [
		"perc_in1",  // for period 1
		"perc_in2",  // for period 2
		"perc_in3"   // for period 3
	],
	
	/* list of HTML element IDs for displaying the descriptions */
	perc_elm: [
		'perc1',     // for period 1
		'perc2',     // for period 2
		'perc3'      // for period 3
	],
	
	/* 
	 * Save a perc parameter input into the matrix.
	 * @param value        perc value ("0", "1", etc.)
	 */
	save_perc: function(value){
		matrix.perc_value[matrix.period] = value;
		document.getElementById(matrix.perc_elm[matrix.period]).innerHTML 
		= get_selection_description(perc_selections, value);
		
		matrix.option_modified = true;
	},
	
	///////////////////////////////////////////////////////////////////////////

	/* effectors for the matrix columns */
	column2: null,
	column3: null,

	/* period which the user is editing (0-origin) */
	period: -1, 
	
	/* 
	 * Initialize the matrix view.
	 */
	initialize: function(){
//		window.alert('update_view() invoked');
		periods = parseInt(document.getElementById('periods_in').value);
		if (isNaN(periods)) { periods = 1; }
		
		var elm;
		var elmProg;
		var elmStyle;
		for(i = 0 ; i < matrix.lyric_value.length ; i++) {
			matrix.period = i;
			matrix.save_lyric("");
			
			elm = document.getElementById(matrix.rhythm_input[i]);
			matrix.save_rhythm(elm.value);
			
			elm = document.getElementById(matrix.chords_input[i]);
			matrix.save_chords(elm.value);
			
			elmProg = document.getElementById(matrix.acmp_prog_input[i]);
			elmStyle = document.getElementById(matrix.acmp_style_input[i]);
			matrix.save_acmp(elmProg.value, elmStyle.value);
			
			elmProg = document.getElementById(matrix.acmp_prog_amb_input[i]);
			elmStyle = document.getElementById(matrix.acmp_style_amb_input[i]);
			matrix.save_acmp_amb(elmProg.value, elmStyle.value);
			
			elm = document.getElementById(matrix.perc_input[i]);
			matrix.save_perc(elm.value);
		}
		matrix.option_modified = false;
		
		matrix.column2 = new Fx.Slide('period2', {mode: 'horizontal'});
		matrix.column3 = new Fx.Slide('period3', {mode: 'horizontal'});
	}, 
	
	/* 
	 * Update the columns of the matrix view.
	 */
	update_column: function(){
		// Update the lyrics elements in the matrix
		var lyrics = document.getElementById('lyric').value.match(regexp);
		var lyric_count = (lyrics != null) ? lyrics.length : 0;
		for(i = 0 ; i < matrix.lyric_value.length ; i++) {
			matrix.period = i;
			matrix.save_lyric((i < lyric_count) ? lyrics[i] : "");
		}
		
		// matrix parameters initialization for the current genre
		// if the options are modified by the user, we should not update them.
		if (matrix.option_modified == false) { setGenre(); }
		
		// Update the matrix column size
		if (user_mode == 'expert') {
			if (periods >= 2) {
				matrix.column2.show();
			} else {
				matrix.column2.hide();
			}
			if (periods >= 3) {
				matrix.column3.show();
			} else {
				matrix.column3.hide();
			}
		}
	},
	
	/* 
	 * Write matrix content into the html form.
	 */
	write_form_data: function(){
		if ((user_mode == 'easy') && (matrix.option_modified == false)) {
			matrix.update_column();
		} else {
			// in case of expert mode, 
			// the matrix is already updated on the mode transition or 
			// on matrix edition by the user.
		}
		
		// remove all the newline characters in the lyric
		for (i = 0 ; i < matrix.lyric_value.length ; i++) {
			matrix.lyric_value[i] 
			= matrix.lyric_value[i].replace(/[\r\n\f]/g, "");
		}
		
/*		window.alert("periods: " + periods + '\n'
		             + "lyric1: " + matrix.lyric_value[0] + '\n'
		             + "lyric2: " + matrix.lyric_value[1] + '\n'
		             + "lyric3: " + matrix.lyric_value[2] + '\n'
		             + "rhythm1: " + matrix.rhythm_value[0] + '\n'
		             + "rhythm2: " + matrix.rhythm_value[1] + '\n'
		             + "rhythm3: " + matrix.rhythm_value[2] + '\n'
		             + "chords1: " + matrix.chords_value[0] + '\n'
		             + "chords2: " + matrix.chords_value[1] + '\n'
		             + "chords3: " + matrix.chords_value[2] + '\n'
		             + "acmp_style1: " + matrix.acmp_style_value[0] + '\n'
		             + "acmp_style2: " + matrix.acmp_style_value[1] + '\n'
		             + "acmp_style3: " + matrix.acmp_style_value[2] + '\n'
		             + "acmp_prog1: " + matrix.acmp_prog_value[0] + '\n'
		             + "acmp_prog2: " + matrix.acmp_prog_value[1] + '\n'
		             + "acmp_prog3: " + matrix.acmp_prog_value[2] + '\n'
	             + "acmp_amb_style1: " + matrix.acmp_style_amb_value[0] + '\n'
	             + "acmp_amb_style2: " + matrix.acmp_style_amb_value[1] + '\n'
	             + "acmp_amb_style3: " + matrix.acmp_style_amb_value[2] + '\n'
	             + "acmp_amb_prog1: " + matrix.acmp_prog_amb_value[0] + '\n'
	             + "acmp_amb_prog2: " + matrix.acmp_prog_amb_value[1] + '\n'
	             + "acmp_amb_prog3: " + matrix.acmp_prog_amb_value[2] + '\n'
		             + "perc1: " + matrix.perc_value[0] + '\n'
		             + "perc2: " + matrix.perc_value[1] + '\n'
		             + "perc3: " + matrix.perc_value[2] + '\n'
		);
*/		
		document.getElementById('periods_in').value = periods;
		
		for(i = 0 ; i < matrix.lyric_elm.length ; i++) {
			document.getElementById(matrix.lyric_input[i]).value 
			= matrix.lyric_value[i];
		}
		for(i = 0 ; i < matrix.rhythm_elm.length ; i++) {
			document.getElementById(matrix.rhythm_input[i]).value 
			= matrix.rhythm_value[i];
		}
		for(i = 0 ; i < matrix.chords_elm.length ; i++) {
			document.getElementById(matrix.chords_input[i]).value 
			= matrix.chords_value[i];
		}
		for(i = 0 ; i < matrix.acmp_elm.length ; i++) {
			document.getElementById(matrix.acmp_style_input[i]).value 
			= matrix.acmp_style_value[i];
			document.getElementById(matrix.acmp_prog_input[i]).value 
			= matrix.acmp_prog_value[i];
		}
		for(i = 0 ; i < matrix.acmp_amb_elm.length ; i++) {
			document.getElementById(matrix.acmp_style_amb_input[i]).value 
			= matrix.acmp_style_amb_value[i];
			document.getElementById(matrix.acmp_prog_amb_input[i]).value 
			= matrix.acmp_prog_amb_value[i];
		}
		for(i = 0 ; i < matrix.perc_elm.length ; i++) {
			document.getElementById(matrix.perc_input[i]).value 
			= matrix.perc_value[i];
		}
	}
};

var lyric_area = null;

/*
 * count the song periods and update the matrix size
 */
function checkPeriods() {
	if (lyric_area == null) {
		lyric_area = document.getElementById('lyric');
	}
	
	var result = lyric_area.value.match(regexp);
	var number = (result != null) ? result.length : 1;
	if (periods != number && number >= 1 && number <= 3) {
		periods = number;
		
		if (number > 3) {
			window.alert("3 lyrics at maximum.");
		}
	}
}

/*
 * Update the lyrics compo-box in case of expert->easy mode transition
 */
function update_lyrics() {
	var lyric_text = "";
	for (i = 0 ; i < matrix.lyric_value.length ; i++) {
		lyric_text += matrix.lyric_value[i].replace(/[\r\n\f]/g, "") + '\n';
	}
	document.getElementById('lyric').value 
	= lyric_text.replace(/^\n+/, "").replace(/\n+$/, "");
	lyric_instruction = false;
}

function hide_pulldownlist() {
	document.getElementById('tempo').style.display = 'none';
}

function show_pulldownlist() {
	document.getElementById('tempo').style.display = 'inline';
}

var box = {};

window.addEvent('domready', function(){
	box 
	= new MultiBox('mb', {
		descClassName: 'multiBoxDesc', 
		useOverlay: true, 
		container: document.getElementById('box_container'), 
		showNumbers: false, 
		onOpen: hide_pulldownlist, 
		onClose: show_pulldownlist
	});
});

/* 
 * Set the callback function for OK button.
 * @param func  callback function
 */
function setCallbackOK(func) {
	box.options.onOK = func;
}

function getGenreDescription() {
	var elm = document.getElementById('genre_select');
	return elm.options[elm.selectedIndex].text;
}
