// Start of Script (validate_script.js)

// Added by Kenny Kwok, integrated focus / alert combo function

//	Enhanced function err() to accept optional stuff_obj, as placement reference of the in-page error message
//	err();				// Remove any in-page error message, if any, without generating a new one
//	err("auto pop-up message"						);
//	err("enforced pop-up message",				false		);
//	err("pop-up when err_auto_inpage != true",		obj		);
//	err("in-page when err_auto_inpage == true",		obj		);
//	err("enforced pop-up message (with focus object)",	obj, false	);
//	err("enforced in-page message",				obj, stuff_obj	);
window.err_auto_inpage = true;	// Automatic upgrade existing err(msg, obj) call to in-page error message
window.err_auto_inpage = false;	// Enhanced feature is for future, and is turned off in Firmware 5.0.0
function err(msg, focus_obj, stuff_obj)
{
	if (window.err_auto_inpage && stuff_obj == undefined) { stuff_obj = focus_obj; }
	// We cannot bare anymore "error" within err(), in case, all possible "error"(s) are suppressed here.
	try { $(".__err__").remove(); } catch(e) {}
	if (msg && msg.length > 0)
	{
		try {
			if (stuff_obj)
			{
				$("<div/>").addClass("__err__").addClass("errormsg").html(msg).appendTo($(stuff_obj).parent());
			}
			else
			{
				alert(msg);
			}
		} catch (e) {}
	}
	try {
		if (focus_obj) { focus_obj.focus(); }
	} catch (e) {}
	return false;	// err always help return false
}


// Added by Kenny Kwok, integrated set of scripts

function checkNameFormat(str)
{
	return /^[0-9A-Z_-]+([0-9A-Z _-]*[0-9A-Z_-]+)*$/i.test(str);
}

function checkDomainFormat(str)
{
/*
	This function is designed under RFC1035, with minor modifications
	to meet the real life requirement:
	<domain> ::= <subdomain> "." <label>
	<subdomain> ::= <label> | <subdomain> "." <label>
	<label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
	<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
	<let-dig-hyp> ::= <let-dig> | "-"
	<let-dig> ::= <letter> | <digit> | "_"
	<letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
	<digit> ::= any one of the ten digits 0 through 9
*/
	return /^([0-9A-Z_]([0-9A-Z_-]*[0-9A-Z_])?[.])+[0-9A-Z_]([0-9A-Z_-]*[0-9A-Z_])?$/i.test(str);
}

function checkMACFormat(str)
{
	return /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/.test(str);
}

function checkAlphanumeric(str)
{
	return /^[0-9A-Z]+$/i.test(str);
}

function checkIntFormat(v, min_value, max_value)
{
	if (!checkint(v)) return false;
	if (min_value && smallerthan(v, min_value)) return false;
	if (max_value && greaterthan(v, max_value)) return false;
	return true;
}

function checkSafeFormat(str)
{
	return (/^[^$\"`]*$/.test(str));
}

function checkWPAKeyFormat(str)
{
	return (/^[^\"`]*$/.test(str));
}
function checkWEPKeyFormat(str)
{
	return checkWPAKeyFormat(str);
}

// Network / IP address checking manipulation functions
//	Added by Kenny Kwok, 2009/09/09
function inet_aton(ipaddr)
{
	var arr = ipaddr.split(".");
	var n = 0;
	for (var i = 0; i < 4; i++)
	{
		n += arr[i]*Math.pow(256,3-i);
	}
	return n;
}
function inet_ntoa(ipn)
{
	var arr = new Array();
	var n = ipn;
	for (var i = 3; i >= 0; i--)
	{
		arr[i] = n % 256;
		n = Math.floor(n / 256);
	}
	return arr.join(".");
}
function checkNetwork(ip, network, maskn)
{	// 1.2.3.4, 1.2.0.0, 16
	var ipn1 = inet_aton(ip);
	var ipn2 = inet_aton(network);
	var maskv = Math.pow(2,32-maskn);
	var v1 = Math.floor(ipn1 / maskv);
	var v2 = Math.floor(ipn2 / maskv);
	return (v1 == v2? true: false);
}

// Trim functions for removing leading / trialing whitespaces or custom defined set of characters

function trim(str, chars)
{
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars)
{
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars)
{
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

// Special Control Initialization Scripts

//	To use init_smart_status(), the page must have predefined control:
//	<div id="smart_status" class="smart_status" style="display:none;"></div>
function init_smart_status(msg, alert_error)
{
	var obj = document.getElementById("smart_status");
	if (!obj)
	{
		if (alert_error) alert("ERR: init_smart_status(): smart_status is not defined");
		return;	// Error, no smart status in this page, actually!
	}
	var hasMsg = (((msg == undefined) || (msg == "") || (msg == "MSG"+"$"))? false: true);
	obj.innerHTML = (hasMsg? msg: "");
	obj.style.display = (hasMsg? "": "none");
	return;
}


// Form elements initialization scripts

function init_radio(obj, value)
{
	for (var i = 0; i < obj.length; i++)
	{
		if (obj[i].value == value)
		{
			obj[i].checked = true;
			break;
		}
	}
}

function init_select(obj, value)
{
	for (var i = 0; i < obj.options.length; i++)
	{
		if (obj.options[i].value == value)
		{
			obj.options[i].selected = true;
			break;
		}
	}
}

function init_checkbox(obj, value)
{
	if (value == "1" || value == "yes" || value == "on" || value == "enable")
	{
		obj.checked = true;
	}
	else
	{
		obj.checked = false;
	}
}

function init_checkbox_group(obj, value)
{
	if (!obj) return;
	if (obj.length != undefined)
	{
		for (var i = 0; i < obj.length; i++)
		{
			if (obj[i].value == value)
			{
				obj[i].checked = true;
			}
		}
	}
	else
	{
		if (obj.value == value)
		{
			obj.checked = true;
		}
	}
	return;
}

function clear_checkbox_group(obj)
{
	if (!obj) return;
	if (obj.length != undefined)
	{
		for (var i = 0; i < obj.length; i++)
		{
			obj[i].checked = false;
		}
	}
	else
	{
		obj.checked = false;
	}
	return;
}

function enable_checkbox_group(obj, is_enable)
{
	if (!obj) return;
	if (is_enable == undefined) is_enable = true;
	if (obj.length != undefined)
	{
		for (var i = 0; i < obj.length; i++)
		{
			obj[i].disabled = !is_enable;
		}
	}
	else
	{
		obj.disabled = !is_enable;
	}
	return;
}

function insert_select_option(selectObj, optionObj)
{
	try
	{
		selectObj.add(optionObj, null);	// standard compliant; doesn't work in IE
	}
	catch (e)
	{
		selectObj.add(optionObj);	// IE only syntax
	}
	return;
}

function replace_select_array(selectObj, option_list, default_value)
{
	while (selectObj.options.length > 0)
	{
		selectObj.remove(0);
	}
	for (var i = 0; i < option_list.length; i++)
	{
		var newOption = new Option(option_list[i][0], option_list[i][1]);
		insert_select_option(selectObj, newOption);
	}
	if (default_value == undefined && option_list.length > 0)
	{
		default_value = option_list[0][1];
	}
	if (default_value != undefined)
	{
		init_select(selectObj, default_value);
	}
	return true;
}

// From elements enquiry scripts

// Retrieve the selected value (value of checked option) of the radio object
function selected_radio_value(obj)
{
	for (var i = 0; i < obj.length; i++)
	{
		if (obj[i].checked)
		{
			return obj[i].value;
		}
	}
	return "";      // Nothing is found
}

// Retrieve the selected value (or first selected values) of the select object
function selected_select_value(obj)
{
	var opt = obj.options;
	for (var i = 0; i < opt.length; i++)
	{
		if (opt[i].selected)
		{
			return opt[i].value;
		}
	}
	return "";      // Nothing is selected
}

// Retrieve the selected text (or first selected values) of the select object
function selected_select_text(obj)
{
	var opt = obj.options;
	for (var i = 0; i < opt.length; i++)
	{
		if (opt[i].selected)
		{
			return opt[i].text;
		}
	}
	return "";      // Nothing is selected
}

function exist_select_value(obj, value)
{
	var options = (obj.options? obj.options: obj);
	for (var i = 0; i < options.length; i++)
	{
		if (options[i].value == value)
		{
			return true;
		}
	}
	return false;
}

// Retrieve the string form of all values of the select object,
//	each value seperated by 'seperator'.
// If seperator is not defined, the default seperator will be ' '.
// If 'selected_only' is true, retrieve the string from of selected values.
function serialized_select_value(obj, seperator, selected_only)
{
	var result = '';
	var sep = '';
	var opt = obj.options;
//alert("seperator = ("+seperator+")");
	if (seperator == undefined) seperator = ' ';
	for (var i = 0; i < opt.length; i++)
	{
		if (!selected_only || opt[i].selected)
		{
			result += sep + obj.item(i).value;
			sep = seperator;
		}
	}
	return result;
}

// Retrieve the string form of selected values of the select object,
//	each value seperated by 'seperator'.
function serialized_selected_select_value(obj, seperator)
{
	return serialized_select_value(obj, seperator, true);
}


// Utility function to validate the supplied network address
//	n.n.n.n
// or	n.n.n.n/m
//	where 0<=n<=255, 0<=m<=32
// Return Value:
//	Success	- Cleaned version of supplied network address:
//			Array(ip_string, mask_value)
//	Failed	- false
//
// (Note: This is the javascript version of ipa_mask analyzer
//	derived from original PHP version in PCMS system.)
function validate_ipa_mask(network_addr)
{
	// Ensure each network address is either n.n.n.n or n.n.n.n/n
	if (!/^([0-9]+[.]){3}[0-9]+(\/[0-9]*)?$/.test(network_addr))
	{
//alert("Non well-formed network address: (" + network_addr + ")");
		return false;
	}
	// Pretty Safe Extraction, ipaddr = {n,n,n,n} mask = n
	{
		var addr = network_addr.split("/");
		// Validate IP Address, prepare cleaned version in ip
		{
			// Allow maximum of 4 parts only, remaining are discarded
			var iparr = addr[0].split(".", 4);
			// Ensure the IP Address numbers are within 0-255
			for (var i = 0; i < 4; i++)
			{
				iparr[i] = parseInt(iparr[i], 10);
				if (iparr[i] < 0 || 255 < iparr[i])
				{
//alert("BAD IP Token" + i + "): (" + iparr[i] + ")");
					return false;
				}
			}
			var ip = iparr.join('.');
		}
		// Validate Subnet Mask, prepare cleaned version in mask
		{
			var mask = (addr[1] && (addr[1].length > 0)? parseInt(addr[1], 10): 32);
			// Ensure the Subnet Mask value is within 0-32
			if (mask < 0 || 32 < mask)
			{
//alert("BAD Mask Token: (" + mask + ")");
				return false;
			}
		}
	}
	return Array(ip, mask);
}


// Netmask options initialization scripts
// Normal Mode (direct = 0): <option value="24">255.255.255.0</option>
// Direct Mode (direct = 1): <option value="255.255.255.0">255.255.255.0</option>
function print_netmask_options_generic(start_mask_index, end_mask_index, selected_index, direct)
{
	if ((typeof(start_mask_index) == 'undefined') || (start_mask_index < 1))
	{
		start_mask_index = 1;
	}
	if ((typeof(end_mask_index) == 'undefined') || (end_mask_index > 32))
	{
		end_mask_index = 32;
	}
	if (start_mask_index > end_mask_index)
	{
		var tmp = start_mask_index;
		start_mask_index = end_mask_index;
		end_mask_index = tmp;
	}
	var bigNumber = 0;
	for (var i = 1; i <= 32; i++)
	{
		bigNumber += (1 << (32-i));
		if (start_mask_index <= i && i <= end_mask_index)
		{
			var text =	((bigNumber >> 24) & 0xFF)
				+ "." + ((bigNumber >> 16) & 0xFF)
				+ "." + ((bigNumber >> 8) & 0xFF)
				+ "." + (bigNumber & 0xFF);
			var selected = (i == selected_index? "selected": "");
			var value = (direct? text: i);
text += " (/" + i + ")";
			document.write('<option value="'+value+'" '+selected+'>'+text+'</option>');
		}
	}
}
function print_netmask_options(start_mask_index, end_mask_index, selected_index)
{
	print_netmask_options_generic(start_mask_index, end_mask_index, selected_index, 0);
}
function print_netmask_options_direct(start_mask_index, end_mask_index, selected_index)
{
	print_netmask_options_generic(start_mask_index, end_mask_index, selected_index, 1);
}

// Help Icon / Header2 in JS related scripts
function helpIconString(help_index)
{
	var helpIcon = '../../en/images/onlinehelp.gif';
	var helpIconHL = '../../en/images/onlinehelp_F2.gif';
	var resultString = '<img border="0" src="' + helpIcon + '" '
		+ 'width="20" height="20" style="vertical-align:top" '//hspace="4" '
		+ 'onMouseOver="shiftIMG(this, ' + "'" + helpIconHL + "'" + ');" '
		+ 'onMouseOut="restoreIMG(this);" '
		+ 'onClick="help(Help[' + help_index + ']);" '
		+ 'class="helpIcon" '
		+ 'alt="(?)" '
		+ 'title="">';
	return resultString;
}
function getHeader(title, help_index)
{
	var titleString = title;
	if (help_index > 0)
	{
		titleString =
		'<div style="float:left; padding: 3px 0px 0px 3px;">' + title + '</div>'
		+ '<div style="float:right;">' + helpIconString(help_index) + '</div>';
	}
	else
	{
		titleString =
		'<div>' + title + '</div>';
	}
	return titleString;
}
function printHeader(title, help_index, colspan)
{
	if (!(colspan > 0)) colspan = 99;
	var rowString =
		'<tr><td class="tabletitle" colspan="' + colspan + '">'
		+ getHeader(title, help_index) + '</td></tr>';
	document.write(rowString);
	return;
}
function getHeader2(title, help_index, custom_anything)
{
	var customStr = "";
	if (custom_anything && custom_anything.length > 0)
	{
		customStr = " " + custom_anything;
	}
	titleString = "<div style='margin:2px 0px'" + customStr + ">" + title + "<div>";
	if (help_index > 0)
	{
		titleString = "<div style='float:right'>" + helpIconString(help_index) + "</div>"
				+ titleString;
	}
	return titleString;
}
function printHeader2(title, help_index, className, custom_styles, custom_anything)
{
	if (className == undefined)
	{
		className = "tabletitle2";
	}
	var styleStr = "";
	if (custom_styles && custom_styles.length > 0)
	{
		styleStr = ' style="' + custom_styles + '"';
	}
	var rowString =
		'<td class="' + className + '" bgcolor="#FFFFFF" width="30%" valign="top"' + styleStr + '>'
		+ getHeader2(title, help_index, custom_anything) + '</td>';
	document.write(rowString);
	return;
}

function addNumberSeperator(value, seperator, inD, outD)
{
	if (!(inD && inD.length > 0)) { inD = "."; }
	if (!(outD && outD.length > 0)) { outD = "."; }
	if (seperator == undefined || seperator.length <= 0) { seperator = ","; }
	value += "";
	var arr = value.split(inD);
	var s = arr[0];
	var s_end = (arr.length > 1? outD + arr[1]: "");
	var regexp = /(\d+)(\d{3})/;
	while (regexp.test(s))
	{
		s = s.replace(regexp, "$1" + seperator + "$2");
	}
	return s + s_end;
}

function getConnMethodString(conn_method)
{
	var str;
	switch (conn_method)
	{
	case "static":	str = "Static IP";	break;
	case "pppoe":	str = "PPPoE";		break;
	case "dhcp":	str = "DHCP";		break;
	case "gre":	str = "GRE";		break;
	case "ppp":	str = "PPP";		break;
	case "pppgre":	str = "GRE over PPP";	break;
	default:	str = "Not Configured";	break;
	}
	return str;
}

// End of Script (validate_script.js)

