//##############################################################
// submit_pes_form
// author: Scott Ingram
//
// permits multiple widgets to register their own onSubmit handlers
//
// The developer can have his own custom functions automatically execute
// onSubmit by using the following functions.
// add_pre_validator_cmd(function_name)
// add_validator_cmd(function_name)
// add_post_validator_cmd(function_name)
//
// Validation handlers are registered with add_validator_cmd(function_name)
// All validation handlers are executed and their messages are accumulated.
// Messages come in two varieties: errors and warnings.  
// The validation handlers register these using add_err(msg) and add_warn(msg).
// The presence of any errors will abort submission and prevent the execution
// of the post_validator_stack.  Warnings prompt the user to "ok" or "cancel"
// the submission.
//
// Submit handlers are registered with add_pre_validator_cmd(function_name)
// and add_post_validator_cmd(function_name)
// If any submit handler fails to return true, the remaining handlers are skipped,
// and submission is aborted.

// The validator() function is defined by the (pes:form> tag in a different file
// very surprising!  org.apache.jasper.JasperException is thrown if 
// I put taglib tags in these comments!  Quite dumb.

var pre_validator_stack = [];
var validator_stack = ["validator"];
var post_validator_stack = [];
var error_msg_stack_1 = [];
var error_msg_stack_2 = [];
var error_obj_name_stack_1 = [];
var error_obj_name_stack_2 = [];
var warning_msg_stack = [];
var do_validation = true;
var abort_on_err = true;
var is_super_user = false;

var override_msg = localize("PCC_OVERRIDE_MSG");
var error_msg_prefix = localize("ERROR_MSG_PREFIX");
var missing_required_msg_prefix = localize("MISSING_REQUIRED_MSG_PREFIX");

function unshift(array,x)
//##############################################################
{	var n = array.length;
	for (var i=n; i>0; i--)
	{	array[i] = array[i-1];
	}
	array[0] = x;
}

function push(array,x)
//##############################################################
{	array[array.length] = x;
}

function pop(array)
//##############################################################
{	var n = array.length;
	if (n==-1) { return; }

	var last = array[n]; // get last value
	array.length = n - 1; // remove last value
	return last; // return last value
}

function concat(a,b)
//##############################################################
{	var z = [];
	var i;

	var la = (a && (a.constructor == Array)) ? a.length : 0;
	var lb = (b && (b.constructor == Array)) ? b.length : 0;

	for (i=0; i<la; i++) { z[i] = a[i]; }
	for (i=0; i<lb; i++) { z[la+i] = b[i]; }
	return z;
}

function set_super_user(flag)
//##############################################################
{
	is_super_user = flag;
}

function submit_pes_form(form)
//##############################################################
{
	var do_submit = true;

        // clear error label stacks
	unhighlight_error_fields(error_obj_name_stack_1);
	unhighlight_error_fields(error_obj_name_stack_2);

	execute_cmd_stack(form, pre_validator_stack);
	execute_cmd_stack(form, validator_stack);

	do_submit = show_errors();

	//alert("DEBUG: 5 do_submit=(" +do_submit+ ")" );

	if (do_submit)
	{
		//alert("DEBUG: post_validator_stack=" + post_validator_stack );
		do_submit = execute_cmd_stack(form, post_validator_stack, abort_on_err);
	}

	clear_msg_stacks();
	do_validation = true;

	return do_submit;
}

function highlight_error_fields(err_stack)
//##############################################################
// turns input fields red
{
	set_error_highlights(err_stack, "red", "error");
}
function unhighlight_error_fields(err_stack)
//##############################################################
// turns input fields black
{
	set_error_highlights(err_stack, "black", "");
        err_stack.length = 0;
}

function set_error_highlights(err_stack, color, class_name)
//##############################################################
// clear existing red input fields
{
	var len = err_stack.length;
	for (var i=0;i<len;i++)
	{
		// turn error input fields and labels BLACK
		var field_name = err_stack[i];

		var div_block = document.getElementById(field_name);
		if (div_block)
		{
			div_block.style.color = color;
		}

		if (field_name != undefined)
		{
			var input_object = get_pes_obj(field_name);
			if (input_object)
			{
				input_object.className = class_name;
			}
		}
	}
}

function show_errors()
//##############################################################
// returns false to abort the form submission
{
	var has_err_1 = (error_msg_stack_1.length > 0) ? true : false;
	var has_err_2 = (error_msg_stack_2.length > 0) ? true : false;
	var has_warn  = (warning_msg_stack.length > 0) ? true : false;
	var has_err   = has_err_1 || has_err_2;

        document.getElementById("validator_err").innerHtml = "";

	if (do_validation && (has_err_1 || has_err_2 || has_warn))
	{
		// display missing required fields
		// as per CR 6802648: Improve Error Message - SI 21-APR-2009
		var err_msg_req_html = "";
		var err_msg_req_stars = "";
		if (has_err_2)
		{
			var err_msg_req_bullets = error_msg_stack_2.join("</li>\n<li>");
			err_msg_req_stars = "* " + error_msg_stack_2.join("\n * ");
			err_msg_req_html = 
				missing_required_msg_prefix 
				+ '\n<ul>\n<li>' 
				+ err_msg_req_bullets 
				+ '</li>\n</ul>\n';

		}

		// display other errors and warnings
		var err_msg_others_html = "";
		var err_msg_stars = "";
		if (has_err_1)
		{
			var all_msg = concat(error_msg_stack_1, warning_msg_stack);
			var all_msg_bullets = all_msg.join("</li>\n<li>");
			err_msg_stars = "* " + all_msg.join("\n * ");
			err_msg_others_html =
				error_msg_prefix
				+ '\n<ul>\n<li>' 
				+ all_msg_bullets
				+ '</li>\n</ul>\n';

		}

		// G25/G29 compliant error message block with bulleted list
		// CR 6615890 http://www.sun.com/webdesign/components/g25.html
		var err_msg_html = '<div class="g29 g29v0"><div class="g29w1"><div class="g29w2"><p>'
			+ err_msg_req_html
			+ err_msg_others_html
			+ '</p></div></div></div>';

		if (is_super_user) 
		{
			// CC_ADMIN override pops open a window with "Ok" & "Cancel" buttons
			var override = confirm (err_msg_req_stars + err_msg_stars + "\n\n" + override_msg);
			set_pes_val("pcc_override", ""+override); // convert boolean into string
			return override;
		}
		else if(has_err)
		{
			// moved the "trun_msg" logic into validator.js where it belongs.
			//alert(err_msg);
                        //alert(err_msg_html);
                        // Write the error messages into the error div
                        document.getElementById("validator_err").innerHTML = err_msg_html;
                        scroll(0,0); // move to the top of page so the user can see the error messages

			highlight_error_fields(error_obj_name_stack_1);
			highlight_error_fields(error_obj_name_stack_2);

			return false;
		}
		else // has_warn is true
		{
			return confirm (err_msg + "\n\n" + override_msg)
		}
	}
	else
	{
		document.getElementById("validator_err").innerHTML = "";
	}

	return true;
}

function execute_cmd_stack(form, stack, do_abort_on_err)
//##############################################################
{	var i;
	for (i=0; i<stack.length; i++)
	{	var function_name = stack[i];
		//alert("DEBUG: execute_cmd_stack - function_name=(" +function_name+ ")" );
		
		var exists = window[function_name];
		if (exists)
		{
			ok = eval (function_name + "(form);");
			if (!ok)
			{	if (do_abort_on_err)
				{	return false;
				}
			}
		}
		else
		{	alert("DEBUG: submit_pes_form ERROR: '" +function_name+ "' handler does not exist");
		}
	}

	return true;
}

	
function downgrade_errors_into_warnings()
//##############################################################
{
	var tmp;
	tmp = error_msg_stack_1.concat(error_msg_stack_2);
	tmp = error_msg_stack_1.concat(warning_msg_stack);
	warning_msg_stack = tmp;
	error_msg_stack_1 = [];
	error_msg_stack_2 = [];
}

function has_errors()
//##############################################################
{
	return ((error_msg_stack_1.length > 0) || (error_msg_stack_2.length > 0));
}

function has_warnings()
//##############################################################
{
	return (warning_msg_stack.length > 0);
}

function add_pre_validator_cmd(name)
//##############################################################
{	push(pre_validator_stack,name);
}

function add_validator_cmd(name)
//##############################################################
{	push(validator_stack,name);
}

function add_post_validator_cmd(name)
//##############################################################
{	push(post_validator_stack,name);
}

function add_err(err)
//##############################################################
{	push(error_msg_stack_1,err);
}

function add_err(err, fieldname)
//##############################################################
{	push(error_msg_stack_1,err);
	push(error_obj_name_stack_1,fieldname);
}

function add_err_group_2(err, fieldname)
//##############################################################
// same as add_err(), but creates a second grouping of errors
// that are displayed in their own paragraph
// as per CR 6802648: Improve Error Message - SI 21-APR-2009
{	push(error_msg_stack_2,err);
	push(error_obj_name_stack_2,fieldname);
}

function add_warning(err)
//##############################################################
{	push(warning_msg_stack,err);
}

function clear_msg_stacks()
//##############################################################
{
	error_msg_stack_1.length = 0;
	error_msg_stack_2.length = 0;
	warning_msg_stack.length = 0;
        
}

function cancel_validation()
//##############################################################
// called by the pes:button tag
{	do_validation = false;
}

function create_error_html(err) {
    
    error_html += "<li><ul>" + err.join("</ul><ul>") + "</ul></li>";
    
}
