function popup(url)
{
	var w = window.open(url, 'name', 'scrollbars=yes,width=512,height=384,left=0,top=0,screenX=0,screenY=0');
	if (window.focus)
		w.focus();
	return false;
}

//------------------------------------------------------------------------------

function check_int(val, first, last)
{
	if (val.length == 0 || val.length > 1 && val.charAt(0) == '0')
		return false;
	for (var i = 0; i < val.length; i++)
		if (val.charAt(i) < '0' || val.charAt(i) > '9')
			return false;

	var v = parseInt(val, 10);
	if (v < first || v > last)
		return false;

	return true;
}

//------------------------------------------------------------------------------

function alg_get_output(alg_form, output)
{
	if (output != '')
	{
		document.PITCH.ORIGINAL.value = output;
		document.DURATION.ORIGINAL.value = output;
		norm_enable(alg_form, PITCHOPTS, PITCH);
		norm_enable(alg_form, DURATIONOPTS, DURATION);
	}
}

//------------------------------------------------------------------------------

function alg_set_controls(alg_form)
{
	alg_form.get_output.disabled = (alg_form.get_output_disabled.value == "false" ? false : true);
}

//------------------------------------------------------------------------------

function norm_calc_scaled_values(method, range_start, range_end, nums)
{
	var range_size = range_end - range_start;
	var min = nums[0];
	var max = nums[0];
	
	for (var i = 1; i < nums.length; i++)
		if (nums[i] < min)
			min = nums[i];
		else if (nums[i] > max)
			max = nums[i];
	
	if (method == 0)
		for (var i = 0; i < nums.length; i++)
			if (max == min)
				nums[i] = range_start;
			else
			{
				var frac = (nums[i] - min) / (max - min);
				nums[i] = range_start + Math.floor(frac * range_size);
			}
	else
		for (var i = 0; i < nums.length; i++)
			nums[i] = range_start + (nums[i] - 0) % (range_size + 1);
}

//------------------------------------------------------------------------------

function norm_scale_values(opts_form, vals_form, max_range)
{
	var output_string = vals_form.MOD.value == "" ? vals_form.ORIGINAL.value : vals_form.MOD.value;
	var nums_temp = output_string.split(',');
	var nums = new Array(nums_temp.length);
	var derived_string = new String();
	
	if (!check_int(opts_form.range_start.value, 0, max_range))
	{
		alert("The beginning of the range is not a number between 0 and " + max_range + " ... please re-enter.");
		return;
	}
	if (!check_int(opts_form.range_end.value, 0, max_range))
	{
		alert("The end of the range is not a number between 0 and " + max_range + " ... please re-enter.");
		return;
	}

	var range_start = parseInt(opts_form.range_start.value);
	var range_end = parseInt(opts_form.range_end.value);
	if (range_start > range_end)
	{
		alert("The last number in the range must be at least as large as the first number ... please re-enter.");
		return;
	}
	
	for (var i = 0; i < nums_temp.length; i++)
		nums[i] = parseInt(nums_temp[i], 10);
	
	norm_calc_scaled_values(opts_form.scaling[0].checked ? 0 : 1, range_start, range_end, nums);
	
	for (var i = 0; i < nums.length; i++)
	{
		derived_string += nums[i];
		if (i < nums.length - 1)
			derived_string += ','
	}

	vals_form.MOD.value = derived_string;
	opts_form.swap_old_disabled.value = "false";
	opts_form.swap_new_disabled.value = "false";
	opts_form.swap_values_disabled.value = "false";
	opts_form.modify_values_disabled.value = "false";
	opts_form.modify_swap_disabled.value = "false";
	opts_form.modify_reverse_disabled.value = "false";
	opts_form.modify_invert_disabled.value = "false";
	norm_set_controls(opts_form, vals_form);
	
	if (document.PITCH.MOD.value != "" && document.DURATION.MOD.value != "")
	{
		document.COMPOSE.play_disabled.value = "false";
		document.COMPOSE.savemidi_disabled.value = "false";
		document.COMPOSE.notate_disabled.value = "false";
		compose_set_controls();
	}
}

//------------------------------------------------------------------------------

function norm_modify_values(opts_form, vals_form, max_range)
{
	if(opts_form.modify[0].checked)
	{
		norm_swap_values(opts_form, vals_form, max_range);
	}
	else if(opts_form.modify[1].checked)
	{
		norm_reverse_values(opts_form, vals_form, max_range);
	}
	else if(opts_form.modify[2].checked)
	{
		norm_invert_values(opts_form, vals_form, max_range);
	}
}

//------------------------------------------------------------------------------

function norm_swap_values(opts_form, vals_form, max_range)
{
	var output_string = vals_form.MOD.value;
	var nums_temp = output_string.split(',');
	var nums = new Array(nums_temp.length);
	var derived_string = new String();
	
	if (!check_int(opts_form.swap_old.value, 0, max_range))
	{
		alert("The value to be replaced is not a number between 0 and " + max_range + " ... please re-enter.");
		return;
	}
	if (!check_int(opts_form.swap_new.value, 0, max_range))
	{
		alert("The substitution value is not a number between 0 and " + max_range + " ... please re-enter.");
		return;
	}
	
	var oldv = parseInt(opts_form.swap_old.value);
	var newv = parseInt(opts_form.swap_new.value);
	
	for (var i = 0; i < nums_temp.length; i++)
		nums[i] = parseInt(nums_temp[i]);
	for (var i = 0; i < nums.length; i++)
	{
		if (nums[i] != oldv)
			derived_string += nums[i];
		else
			derived_string += newv;
		if (i < nums.length - 1)
			derived_string += ','
	}

	vals_form.MOD.value = derived_string;
}

//------------------------------------------------------------------------------

function norm_reverse_values(opts_form, vals_form, max_range)
{
	var input = vals_form.MOD.value.split(",");
	var output = new Array(input.length);
	var derived_string = new String();
	for (var i = 0; i < input.length; i++)
	{
		output[i] = input[input.length - 1 - i];
	}
	for (var j = 0; j < output.length; j++)
	{
		derived_string += output[j];
		if (j < output.length - 1)
		{
			derived_string += ',';
		}
	}
	vals_form.MOD.value = derived_string;
}

//------------------------------------------------------------------------------

function norm_invert_values(opts_form, vals_form, max_range)
{
	var input = vals_form.MOD.value.split(",");
	var output = new Array(input.length);
	var derived_string = new String();
	output[0] = parseInt(input[0]);
	var interval = 0;
	for (var i = 1; i < input.length; i++)
	{
		interval = parseInt(input[i]) - parseInt(input[i-1]);
		output[i] = parseInt(output[i-1]) - interval;

		if (!check_int(output[i], 0, max_range))
		{
			alert("The inverted interval between " + input[0] + " and " + input[i] + " produces a result " + output[i] + " that is outside the allowed range.");
			return;
		}
	}
	for (var j = 0; j < output.length; j++)
	{
		derived_string += output[j];
		if (j < output.length - 1)
		{
			derived_string += ',';
		}
	}
	vals_form.MOD.value = derived_string;
}

//------------------------------------------------------------------------------

function norm_reset(opts_form, vals_form)
{
	vals_form.MOD.value = "";
	opts_form.swap_old_disabled.value = "true";
	opts_form.swap_new_disabled.value = "true";
	opts_form.swap_values_disabled.value = "true";
	opts_form.modify_values_disabled.value = "true";
	opts_form.modify_swap_disabled.value = "true";
	opts_form.modify_reverse_disabled.value = "true";
	opts_form.modify_invert_disabled.value = "true";
	norm_set_controls(opts_form, vals_form);
	document.COMPOSE.play_disabled.value = "true";
	document.COMPOSE.savemidi_disabled.value = "true";
	document.COMPOSE.notate_disabled.value = "true";
	compose_set_controls();
}

//------------------------------------------------------------------------------

function norm_set_controls(opts_form, vals_form)
{
	if (opts_form == DURATIONOPTS)
	{
		opts_form.use_uniform_durs.disabled = (opts_form.use_uniform_durs_disabled.value == "false" ? false : true);
		opts_form.uniform_duration.disabled = (opts_form.uniform_duration_disabled.value == "false" ? false : true);
	}
	opts_form.range_start.disabled = (opts_form.range_start_disabled.value == "false" ? false : true);
	opts_form.range_end.disabled = (opts_form.range_end_disabled.value == "false" ? false : true);
	opts_form.scaling[0].disabled = (opts_form.scaling_div_disabled.value == "false" ? false : true);
	opts_form.scaling[1].disabled = (opts_form.scaling_mod_disabled.value == "false" ? false : true);
	opts_form.modify[0].disabled = (opts_form.modify_swap_disabled.value == "false" ? false : true);
	opts_form.modify[1].disabled = (opts_form.modify_reverse_disabled.value == "false" ? false : true);
	opts_form.modify[2].disabled = (opts_form.modify_invert_disabled.value == "false" ? false : true);
	opts_form.scale_values.disabled = (opts_form.scale_values_disabled.value == "false" ? false : true);
	opts_form.swap_old.disabled = (opts_form.swap_old_disabled.value == "false" ? false : true);
	opts_form.swap_new.disabled = (opts_form.swap_new_disabled.value == "false" ? false : true);
	opts_form.swap_values.disabled = (opts_form.swap_values_disabled.value == "false" ? false : true);
	opts_form.modify_values.disabled = (opts_form.modify_values_disabled.value == "false" ? false : true);
	vals_form.reset_values.disabled = (vals_form.reset_values_disabled.value == "false" ? false : true);

}

//------------------------------------------------------------------------------

function norm_enable(alg_form, opts_form, vals_form)
{
	alg_form.get_output_disabled.value = "true";
	alg_set_controls(alg_form);
	
	if (opts_form == DURATIONOPTS && opts_form.use_uniform_durs.checked)
	{
		opts_form.use_uniform_durs_disabled.value = "false";
		opts_form.uniform_duration_disabled.value = "false";
		set_uniform_durations();
	}
	else
	{
		opts_form.range_start_disabled.value = "false";
		opts_form.range_end_disabled.value = "false";
		opts_form.scaling_div_disabled.value = "false";
		opts_form.scaling_mod_disabled.value = "false";
		opts_form.scale_values_disabled.value = "false";
		opts_form.swap_old_disabled.value = "true";
		opts_form.swap_new_disabled.value = "true";
		opts_form.swap_values_disabled.value = "true";
		opts_form.modify_values_disabled.value = "true";
		opts_form.modify_swap_disabled.value = "true";
		opts_form.modify_reverse_disabled.value = "true";
		opts_form.modify_invert_disabled.value = "true";
		vals_form.reset_values_disabled.value = "false";
	}

	norm_set_controls(opts_form, vals_form);
}

//------------------------------------------------------------------------------

function norm_disable(alg_form, opts_form, vals_form)
{
	alg_form.get_output_disabled.value = "false";
	alg_set_controls(alg_form);
	
	if (opts_form == DURATIONOPTS && opts_form.use_uniform_durs.checked)
	{
		opts_form.use_uniform_durs_disabled.value = "true";
		opts_form.uniform_duration_disabled.value = "true";
	}
	else
	{
		opts_form.range_start_disabled.value = "true";
		opts_form.range_end_disabled.value = "true";
		opts_form.scaling_div_disabled.value = "true";
		opts_form.scaling_mod_disabled.value = "true";
		opts_form.scale_values_disabled.value = "true";
		opts_form.swap_old_disabled.value = "true";
		opts_form.swap_new_disabled.value = "true";
		opts_form.swap_values_disabled.value = "true";
		opts_form.modify_values_disabled.value = "true";
		opts_form.modify_swap_disabled.value = "true";
		opts_form.modify_reverse_disabled.value = "true";
		opts_form.modify_invert_disabled.value = "true";
		vals_form.reset_values_disabled.value = "true";
	}

	norm_set_controls(opts_form, vals_form);
	vals_form.MOD.value = "";
}

//------------------------------------------------------------------------------

function duration_checkbox_clicked()
{
	if (DURATIONOPTS.use_uniform_durs.checked)
	{
		DURATIONOPTS.uniform_duration_disabled.value = "false";
		DURATIONOPTS.range_start_disabled.value = "true";
		DURATIONOPTS.range_end_disabled.value = "true";
		DURATIONOPTS.scaling_div_disabled.value = "true";
		DURATIONOPTS.scaling_mod_disabled.value = "true";
		DURATIONOPTS.scale_values_disabled.value = "true";
		DURATIONOPTS.swap_old_disabled.value = "true";
		DURATIONOPTS.swap_new_disabled.value = "true";
		DURATIONOPTS.swap_values_disabled.value = "true";
		DURATIONOPTS.modify_values_disabled.value = "true";
		DURATIONOPTS.modify_swap_disabled.value = "true";
		DURATIONOPTS.modify_reverse_disabled.value = "true";
		DURATIONOPTS.modify_invert_disabled.value = "true";
		DURATION.reset_values_disabled.value = "true";
		set_uniform_durations();
	}
	else
	{
		DURATIONOPTS.uniform_duration_disabled.value = "true";
		DURATIONOPTS.range_start_disabled.value = "false";
		DURATIONOPTS.range_end_disabled.value = "false";
		DURATIONOPTS.scaling_div_disabled.value = "false";
		DURATIONOPTS.scaling_mod_disabled.value = "false";
		DURATIONOPTS.scale_values_disabled.value = "false";
		DURATIONOPTS.swap_old_disabled.value = "true";
		DURATIONOPTS.swap_new_disabled.value = "true";
		DURATIONOPTS.swap_values_disabled.value = "true";
		DURATIONOPTS.modify_values_disabled.value = "false";
		DURATIONOPTS.modify_swap_disabled.value = "false";
		DURATIONOPTS.modify_reverse_disabled.value = "false";
		DURATIONOPTS.modify_invert_disabled.value = "false";
		DURATION.reset_values_disabled.value = "false";
		DURATION.MOD.value = "";
	}
	norm_set_controls(DURATIONOPTS, DURATION);
	
	if (document.PITCH.MOD.value != "" && document.DURATION.MOD.value != "")
	{
		document.COMPOSE.play_disabled.value = "false";
		document.COMPOSE.savemidi_disabled.value = "false";
		document.COMPOSE.notate_disabled.value = "false";
	}
	else
	{
		document.COMPOSE.play_disabled.value = "true";
		document.COMPOSE.savemidi_disabled.value = "true";
		document.COMPOSE.notate_disabled.value = "true";
	}
	compose_set_controls();
}

//------------------------------------------------------------------------------

function set_uniform_durations()
{
	var notes = DURATION.ORIGINAL.value.split(',').length;
	var derived_string = new String();
	var ud = DURATIONOPTS.uniform_duration.value;
	var i;
	
	for (i = 0; i < notes; i++)
	{
		derived_string += ud;
		if (i < notes - 1)
			derived_string += ','
	}
	DURATION.MOD.value = derived_string;
}

//------------------------------------------------------------------------------

function page_disable_all(alg_form)
{
	norm_disable(alg_form, PITCHOPTS, PITCH);
	norm_disable(alg_form, DURATIONOPTS, DURATION);
	compose_disable();
}

//------------------------------------------------------------------------------

function compose_disable()
{
	document.COMPOSE.play_disabled.value = "true";
	document.COMPOSE.savemidi_disabled.value = "true";
	document.COMPOSE.notate_disabled.value = "true";
	compose_set_controls();
}

//------------------------------------------------------------------------------

function compose_set_controls()
{
	document.COMPOSE.play.disabled = (document.COMPOSE.play_disabled.value == "false" ? false : true);
	document.COMPOSE.savemidi.disabled = (document.COMPOSE.savemidi_disabled.value == "false" ? false : true);
	document.COMPOSE.notate.disabled = (document.COMPOSE.notate_disabled.value == "false" ? false : true);
}

//------------------------------------------------------------------------------

var w = null;

function popup_play()
{

	if (w != null && !w.closed)
	{
		w.focus();
		return;
	}
	w = window.open('', 'w', 'width=761,height=400,left=0,top=0,screenX=0,screenY=0');
	w.document.writeln("<title>MIDI Player</title>");
	w.document.writeln("<body bgcolor='808080'></body>");
	w.document.writeln("<applet code='MidiPlayer.class' archive='midiplayer.jar' codebase='../' width='750' height='350'>");
	w.document.writeln("<param name='pitch' value='" + document.PITCH.MOD.value + "'>");
	w.document.writeln("<param name='duration' value='" + document.DURATION.MOD.value + "'>");
	w.document.writeln("</applet>");
	w.document.close();
}

//------------------------------------------------------------------------------

function newpage_savemidi()
{
	document.COMPOSE.PITCH.value = document.PITCH.MOD.value;
	document.COMPOSE.DURATION.value = document.DURATION.MOD.value;
	document.COMPOSE.action = "../midi/dmidi.php";
	document.COMPOSE.submit();
}

//------------------------------------------------------------------------------

function newpage_notate()
{
	document.COMPOSE.PITCH.value = document.PITCH.MOD.value;
	document.COMPOSE.DURATION.value = document.DURATION.MOD.value;
	document.COMPOSE.action = "../NotationOutput.php";
	document.COMPOSE.submit();
}

//------------------------------------------------------------------------------
