// global variables
var bLoadingData = false;	//global var to determine if a change is being made to a row while loading
							//or due to changes made by the user. Should be set appropriately before and after
var bChangeDataduringLoad = false;							
							//loading data into cells Row colouring should be carried out only when changes
							//are made by the user

var bacMode;//1-UDP;0-1+1
var TypeFlag = 0;//1-card; 2-rf port; 3-channel
var CARD_TYPE = 1;
var PORT_TYPE = 2;
var CHANNEL_TYPE = 3;

var card_index;
var port_index;
var channel_index;

var CardPortNum;//每个卡最大的RF端口数
var PortChannelNum;//每个rf最大的频点数
var channelUdpNum;//每个频点最大的UDP端口数
var ExitChannel = [];//两个rf实际建立的频点号，32位的整数，从第一位开始表示第一个频点存在与否，0表示不存在，1表示存在

var MAX_GBE_NUM = 4;
var maxUdpNumber;

var bacMode10Gbe;
var MAX_10GBE_NUM;

var gpairOptionLength = 0;
var g10pairOptionLength = 0;

var ROW_NUM = 11;

var BASE_ROW_HEIGHT;
var BASE_ROW_HEIGHT_INT;

/****base colume index****/
var INDEX_BASE = 0;
var ROW = 1;
var CHANNEL = 2;
var IP = 3;
var UDP = 4;
var ACTIVE = 5;
var INGRESS_PORT = 6;
var GBE_PORT = 7;
var STREAM_TYPE = 8;
var BAC_ENABLED = 9;
var BAC_ROW = 10;
var PRO_NUM_IN = 11;
var PRO_NUM_OUT = 12;
var PMV = 13;
var DATA_ENABLED = 14;
var DATA_RATE = 15;
var SWITCH_RATE = 16;
var SOURCE_IP = 17;
var BLOCKED_PIDS = 18;
var MEMORY_ADDRESS = 19;
/**end**/

/**adv colume index****/
var INDEX_ADV = 0;
var SRC_IP = 1;
var BLO_PIDS = 2;
var MEM_ADDR = 3;
/***end**/

/***colume id***/
var GBE_PORT_ID = "g";
var STREAM_TYPE_ID = "h";
var BAC_ENABLED_ID = "i";
var BAC_ROW_ID = "j";
var PRO_NUM_IN_ID = "k";
var PRO_NUM_OUT_ID = "l";
var PMV_ID = "m";
var DATA_ENABLED_ID = "n";
var DATA_RATE_ID = "o";
var SWITCH_RATE_ID = "p";
var SRC_IP_ID = "q";
var BLOCKED_PIDS_ID = "r";
var MEMORY_ADDRESS_ID = "s";
/**end**/
var mainIPAddr;
var h;
var language;
var userName;

function mouseOverRuleApply(obj)
{
	if(obj.disabled == false)
	{
		obj.style.background = "url(../images/btn3_hover.png)";
	}
}
function mouseOutRuleApply(obj)
{
	if(obj.disabled == false)
	{
		obj.style.background = "url(../images/btn3_normal.png)";
	}
}

function mouseOverShow(obj)
{
	if(obj.disabled == false)
	{
		obj.style.background = "url(../images/btn4_hover.png)";
	}
}
function mouseOutShow(obj)
{
	if(obj.disabled == false)
	{
		obj.style.background = "url(../images/btn4_normal.png)";
	}
}

function GetChDisplay(card, port, channel)
{
	return card + "/" + port + "." + channel;
}

function chIndexToDisplay(devChannel)
{
	var devPort = 0;
	var card, port, channel;
	devPort = parseInt(devChannel/PortChannelNum);
	card = parseInt(devPort/CardPortNum);
	port = devPort%CardPortNum;
	channel = devChannel%PortChannelNum;
	return (card + 1) + "/" + (port + 1) + "." + (channel + 1);
}

function GetDeviceChIndex(card, port, channel)
{
	var devPort = (card - 1) * CardPortNum + port - 1;
	var devChannel = devPort * PortChannelNum + channel - 1;
	return devChannel;
}

var start_chn = "0/0.0", end_chn = "0/0.0";
window.onload = function()
{
	if(bd.browser == "IE")
	{
		BASE_ROW_HEIGHT = "24px";
		BASE_ROW_HEIGHT_INT = 24;
	}
	else
	{
		BASE_ROW_HEIGHT = "22px";
		BASE_ROW_HEIGHT_INT = 22;
	}
	language = document.getElementById("language").value;
	document.body.style.cursor = "wait";
	window.status = "Retrieving data, please wait...";
	disabledButton(document.getElementById("BaseRuleApply"), true);
	disabledButton(document.getElementById("AdvRuleApply"), true);
	if(bLoadingData == false)
	{
		ToggleLoading();
	}

	DisableApply(true);
	DisableReset(true);
	
	var args = getArgs();
	var nodeId = args["nodeId"];
	var group = args["group"];
	userName = args["userName"];
	mainIPAddr = args["mainIPAddr"];
	h = (document.body.scrollHeight - 400);     
	$("body").append('<iframe style="display:none;" id="agent" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://' + mainIPAddr + '/../asp/agent.asp?t='+ new Date().getTime()+'#height=' + h + '" ></iframe>');     
	if(nodeId == null)
	{
		nodeId = parent.curTree.getSelectedNodes()[0].id;
	}
	var apply1 = document.getElementById("BaseApply");
	var apply2 = document.getElementById("AdvApply");
	applyDispay(group, apply1);
	applyDispay(group, apply2);
	var str = nodeId.toString();
	if(str.length == 1)
	{
		TypeFlag = CARD_TYPE;
		card_index = (nodeId);
	}
	else if(str.length == 2)
	{
		TypeFlag = PORT_TYPE;
		card_index = parseInt(nodeId/10);
		port_index = nodeId%10;
	}
	else if(str.length >= 3)
	{
		TypeFlag = CHANNEL_TYPE;
		var len = str.length;
		var cardVal = Math.pow(10, (len - 1));
		var portVal = Math.pow(10, (len - 2));
		card_index = parseInt(nodeId/cardVal);
		port_index = parseInt((nodeId%cardVal)/portVal);
		channel_index = (nodeId%portVal);
	}
	
	GetDeviceInfo();
	/********DataRate is greyed out on load of the page**********/
	document.getElementById("AdvSectionDiv").style.display = "none";
}

function ToggleLoading()	// test function to toggle the global var for loading
{
	bLoadingData = !bLoadingData;
}

function DisabledColumes()
{
	if(bacMode == 1)//UDP
	{
		for(var i = 0; i < ROW_NUM; i++)
		{
			document.getElementById(BAC_ENABLED_ID + i).disabled = false;
			document.getElementById(BAC_ROW_ID + i).disabled = false;
			document.getElementById(SWITCH_RATE_ID + i).disabled = false;
			document.getElementById(GBE_PORT_ID + i).disabled = false;
		}
		document.getElementById("gbePortRule").disabled = false;
		document.getElementById("UdpBackupRule").disabled = false;
		document.getElementById("SwitchRateRule").disabled = false;
	}
	else//1+1
	{
		for(var i = 0; i < ROW_NUM; i++)
		{
			document.getElementById(BAC_ENABLED_ID + i).disabled = true;
			document.getElementById(BAC_ROW_ID + i).disabled = true;
			document.getElementById(SWITCH_RATE_ID + i).disabled = true;
			document.getElementById(GBE_PORT_ID + i).disabled = true;
		}
		document.getElementById("gbePortRule").disabled = true;
		document.getElementById("UdpBackupRule").disabled = true;
		document.getElementById("SwitchRateRule").disabled = true;
		document.getElementById("SwitchRateRule").value = 0;
	}
}

function gbeAdjust(gbeNum)
{
	if(gbeNum == 2)
	{
		for(var i=0; i<11; i++)
		{
			document.getElementById("f" + i).disabled = false;
		}
		$("#ingressPortRule").attr("disabled", true);
	}
}

function GetDeviceInfo()
{
	var xmlhttp = false;
	xmlhttp = getHTTPObject();
	var inputFlag;
	var option;
	
	var params = "type=2&cmd=1&getDeviceInfo=1";
	
	xmlhttp.open("POST", "/goform/formIPQAM", true);
	xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xmlhttp.setRequestHeader("Content-length", params.length);
	xmlhttp.onreadystatechange = function()
	{
		if(xmlhttp.readyState == 4)
		{
			var response = xmlhttp.responseText;
			var DeviceInfo = response.slice(7, -8).split("&");
			bacMode = parseInt(DeviceInfo[0]);
			CardPortNum = parseInt(DeviceInfo[1]);
			PortChannelNum = parseInt(DeviceInfo[2]);
			channelUdpNum = parseInt(DeviceInfo[3]);
			for(var i = 0; i < CardPortNum; i++)
			{
				var portValue = parseInt(DeviceInfo[4].split(",")[i]);
				ExitChannel.push(portValue);//仅RF有用
			}
			if(TypeFlag == CARD_TYPE)
			{
				start_chn = GetChDisplay(card_index, 1, 1);
				end_chn = GetChDisplay(card_index, CardPortNum, PortChannelNum);
			}
			else if(TypeFlag == PORT_TYPE)
			{
				start_chn = GetChDisplay(card_index, port_index, 1);
				end_chn = GetChDisplay(card_index, port_index, PortChannelNum);
			}
			else if(TypeFlag == CHANNEL_TYPE)
			{
				start_chn = GetChDisplay(card_index, port_index, channel_index);
				end_chn = start_chn;
			}
			
			MAX_GBE_NUM = parseInt(DeviceInfo[5]);
			maxUdpNumber = parseInt(DeviceInfo[6]);
			//gbeAdjust(MAX_GBE_NUM);
			bacMode10Gbe = parseInt(DeviceInfo[7]);
			MAX_10GBE_NUM = parseInt(DeviceInfo[8]);
			for(var i = 0; i < ROW_NUM; i++)
			{
				var $selectObj = $("#f" + i);
				$selectObj.empty();
				if(MAX_GBE_NUM % 2 == 0)
				{
					gpairOptionLength = MAX_GBE_NUM/2;
				}
				else
				{
					gpairOptionLength = MAX_GBE_NUM/2 + 1;
				}
				if(MAX_10GBE_NUM % 2 == 0)
				{
					g10pairOptionLength = MAX_10GBE_NUM/2;
				}
				else
				{
					g10pairOptionLength = MAX_10GBE_NUM/2 + 1;
				}
				for(var j = 0; j < gpairOptionLength; j++)
				{
					option = $("<option>").text("GPair" + (j + 1)).val(j);
					$("#f" + i).append(option);
				}
				for(var j = 0; j < g10pairOptionLength; j++)
				{
					option = $("<option>").text("10GPair" + (j + 1)).val(16 + j);
					$("#f" + i).append(option);
				}
			}
			$("#ingressPortRule").empty();
			for(var j = 0; j < gpairOptionLength; j++)
			{
				option = $("<option>").text("GPair" + (j + 1)).val(j);
				$("#ingressPortRule").append(option);
			}
			for(var j = 0; j < g10pairOptionLength; j++)
			{
				option = $("<option>").text("10GPair" + (j + 1)).val(16 + j);
				$("#ingressPortRule").append(option);
			}

			//DisabledColumes();
			
			PopulateImpRulesCombos();
			GetStreamMapRows();
		}
	}
	xmlhttp.send(params);
	return false;
}

function AddSelectChannel(card, port, channel)
{
	var elOptNew1 = document.createElement("option");
	elOptNew1.text = GetChDisplay(card, port, channel);
	elOptNew1.value = GetDeviceChIndex(card, port, channel);
	var elSel1 = document.getElementById("QamBaseStart");
	elSel1.add(elOptNew1, null); // Non IE

	var elOptNew2 = document.createElement("option");
	elOptNew2.text  = GetChDisplay(card, port, channel);
	elOptNew2.value = GetDeviceChIndex(card, port, channel);
	var elSel2 = document.getElementById("QamBaseEnd");
	elSel2.add(elOptNew2, null); // Non IE

	var elOptNew3 = document.createElement("option");
	elOptNew3.text = GetChDisplay(card, port, channel);
	elOptNew3.value = GetDeviceChIndex(card, port, channel);
	var elSel3 = document.getElementById("QamAdvStart");
	elSel3.add(elOptNew3, null); // Non IE

	var elOptNew4 = document.createElement("option");
	elOptNew4.text = GetChDisplay(card, port, channel);
	elOptNew4.value = GetDeviceChIndex(card, port, channel);
	var elSel4 = document.getElementById("QamAdvEnd");
	elSel4.add(elOptNew4, null); // Non IE
}

function AddSelectChannelIE(card, port, channel)
{
	var elOptNew1 = document.createElement("option");
	elOptNew1.text = GetChDisplay(card, port, channel);
	elOptNew1.value = GetDeviceChIndex(card, port, channel);
	var elSel1 = document.getElementById("QamBaseStart");
	elSel1.add(elOptNew1);

	var elOptNew2 = document.createElement("option");
	elOptNew2.text  = GetChDisplay(card, port, channel);
	elOptNew2.value = GetDeviceChIndex(card, port, channel);
	var elSel2 = document.getElementById("QamBaseEnd");
	elSel2.add(elOptNew2);

	var elOptNew3 = document.createElement("option");
	elOptNew3.text = GetChDisplay(card, port, channel);
	elOptNew3.value = GetDeviceChIndex(card, port, channel);
	var elSel3 = document.getElementById("QamAdvStart");
	elSel3.add(elOptNew3);

	var elOptNew4 = document.createElement("option");
	elOptNew4.text = GetChDisplay(card, port, channel);
	elOptNew4.value = GetDeviceChIndex(card, port, channel);
	var elSel4 = document.getElementById("QamAdvEnd");
	elSel4.add(elOptNew4);
}

function PopulateImpRulesCombos()
{
	var len = document.getElementById("QamBaseStart").length;
	for(var i = 0; i < len; i++)
	{
		document.getElementById("QamBaseStart").remove(0);
		document.getElementById("QamBaseEnd").remove(0);
		document.getElementById("QamAdvStart").remove(0);
		document.getElementById("QamAdvEnd").remove(0);
	}
	if(TypeFlag == CARD_TYPE)
	{
		for(var j = 0; j < CardPortNum; j++)
		{
			for(var i = 0; i < PortChannelNum; i++)
			{
				try
				{
					AddSelectChannel(card_index, (j + 1), (i + 1));
				}
				catch(ex)
				{
					AddSelectChannelIE(card_index, (j + 1), (i + 1));
				}
			}
		}
	}
	else if(TypeFlag == PORT_TYPE)
	{
		for(var i = 0; i < PortChannelNum; i++)
		{
			try
			{
				AddSelectChannel(card_index, port_index, (i + 1));
			}
			catch(ex)
			{
				AddSelectChannelIE(card_index, port_index, (i + 1));
			}
		}
	}
	else if(TypeFlag == CHANNEL_TYPE)
	{
		try
		{
			AddSelectChannel(card_index, port_index, channel_index);
		}
		catch(ex)
		{
			AddSelectChannelIE(card_index, port_index, channel_index);
		}
	}
}

var init_row = true;
var row_index;
function GetStreamMapRows()
{
	var xmlhttp = false;
	
	xmlhttp = getHTTPObject();

	if(init_row)
	{
		row_index = 0;
		//getParams = getParams + "&" + start_chn + "&" + end_chn;
	}
	var getParams = "type=2&cmd=1&mapGetString=" + start_chn + "|" + end_chn + "|" + row_index;

	xmlhttp.open("POST", "/goform/formIPQAM", true);
	xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xmlhttp.setRequestHeader("Content-length", getParams.length);
	xmlhttp.onreadystatechange = function()
	{
		if((xmlhttp.readyState == 4) && (xmlhttp.status == 200))
		{

			var response = xmlhttp.responseText;
			var s_map_response = response.slice(7, -8).split("&");
			var s_map_len = s_map_response.length;

			FillInternalTable(s_map_response);
			if(init_row == true)
			{
				RenderBaseTable();
				RenderAdvTable();
			}

			init_row = false;
			
			if(s_map_response[s_map_len - 1].indexOf("start_chn") != -1)
			{
				var cur_row_string = s_map_response[s_map_len - 1].split(",");
				start_chn = cur_row_string[1]; //The element before-last in response array stores the value of "start_chn"
				row_index = cur_row_string[3];
			}

			if(s_map_response[s_map_len - 1] == "end")
			{
				init_row = true;
				if(bLoadingData == true)
				{
					ToggleLoading();
				}
				if(bChangeDataduringLoad)
				{
					DisableApply(false);
					bChangeDataduringLoad = false;
				}	
				DisableReset(false);
				resizeWidth();
				document.body.style.cursor = "auto";
				window.status = "Done";
				return true;
			}
			setTimeout("GetStreamMapRows()", 5);
		}
	}
	xmlhttp.send(getParams);
	return true;
}

function resizeWidth()
{
	var width = document.body.offsetWidth;
	document.getElementById("mapDiv").style.width = (width - 16);
	document.getElementById("baseTable").style.width = (width - 34);
	document.getElementById("advTable").style.width = (width - 34);
	document.getElementById("baseTabDiv").style.width = (width - 36);
	document.getElementById("baseRulesDiv").style.width = (width - 36);
	document.getElementById("advTabDiv").style.width = (width - 36);
	document.getElementById("advRulesDiv").style.width = (width - 36);
	/*
	if(g_StreamMapRows.length <= 11)
	{
		document.getElementById("baseTable").style.width = (width - 16);
		document.getElementById("BaseTableDiv").style.width = 0;
		document.getElementById("advTable").style.width = (width - 16);
		document.getElementById("AdvTableDiv").style.width = 0;
	}
	else
	{
		document.getElementById("baseTable").style.width = (width - 34);
		document.getElementById("BaseTableDiv").style.width = 18;
		document.getElementById("advTable").style.width = (width - 34);
		document.getElementById("AdvTableDiv").style.width = 18;
	}
	*/
	setTimeout("resizeWidth()", 500);
}


var g_StreamMapRows = [];	// Contains array of strings - each element containing , separated values
var curFocus;				// UI Element that has got current keyboard focus (that was last clicked)
var lastRowRendered;		// Used to handle insertion

// This variable holds the default values that need to appear when a new row is created. Channel number has to be adjusted before use.


var scrollLock = false;
function FillInternalTable(s_map)
{
	var len = s_map.length;
	for(var i = 0; i < len; i++)
	{
		if(s_map[i] == "end")
		{
			continue;	// The last value is "end"
		}
		if(s_map[i].indexOf("start_chn") != -1)
		{
		// The current row is "row_index". Hence skip.
			continue;	
		}
		var rowFields = s_map[i].split(",");
		var card = parseInt(rowFields[1].split("/")[0]);
		var port = parseInt(rowFields[1].split("/")[1].split(".")[0]);
		var channel = parseInt(rowFields[1].split("/")[1].split(".")[1]);
		var ChanNo = GetDeviceChIndex(card, port, channel);
		rowFields[1] = ChanNo;
		
		var saveRowString = rowFields[0];
		for(var j = 1; j < rowFields.length; j++)
		{
			saveRowString = saveRowString + "," + rowFields[j];
		}
		// & separated rows with , separated fields
		saveRowString = "C," + saveRowString; // When loading the rows are Clean
		g_StreamMapRows.push(saveRowString);

		// Create a row in the invisible table - this is used in adjusting the scrollbar
		var row = document.getElementById("InvisibleTable").insertRow(-1);
		row.style.height = BASE_ROW_HEIGHT; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
		var cell = row.insertCell(0);
		cell.innerHTML = g_StreamMapRows.length;

		row = document.getElementById("AdvInvisibleTable").insertRow(-1);
		row.style.height = "22px"; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
		cell = row.insertCell(0);
		cell.innerHTML = g_StreamMapRows.length;
	}
}

function isValidBlockedPID(input)
{

	var len = input.length;
	var index = 0;
	if(len == 0)
	{
		return false;
	}
	
	if((input.charAt(0) == "-"))
	{
		for(index = 1; index < len; index++)
		{
			if(isNaN((input.charAt(index))))
			{
				return false;
			}
		}
	}
	else
	{
		for(index = 0; index < len; index++)
		{
			if(isNaN((input.charAt(index))))
			{
				return false;
			}
		}
	}
	
	return true;
}

function DisableApply(bDisable)
{
	var baseApply = document.getElementById("BaseApply");
	var advApply = document.getElementById("AdvApply");
	disabledButton(baseApply, bDisable);
	disabledButton(advApply, bDisable);
	/* If the Apply is being enabled during Load, set it to Disable again */
	if((bLoadingData == true) && (bDisable == false))
	{
		disabledButton(baseApply, true);
		disabledButton(advApply, true);
		bChangeDataduringLoad = true;
    }
}


function DisableReset(bDisable)
{
	document.getElementById("BaseReset").disabled = bDisable;
	document.getElementById("AdvReset").disabled = bDisable;
	document.getElementById("BaseAddRow").disabled = bDisable;
}


function PerformReload()
{
	DisableApply(true);
	DisableReset(true);

	bLoadingData = true;
	// Clear displays
	var RowsToDisplay = parseInt(document.getElementById("BaseSettings").rows.length, 10) - 2;
	var BaseTable = document.getElementById("BaseTableBody");
	var AdvTable = document.getElementById("AdvTableBody");

	for(var i = 0; i < RowsToDisplay; i++)
	{
		var Row = BaseTable.rows[i];
		var Child = Row.firstChild;

		{
			while(Child != null)
			{
				if((Child.firstChild) && (Child.firstChild.nodeName == "INPUT"))
				{
					Child.firstChild.value = "";
				}
				else if((Child.firstChild) && (Child.firstChild.nodeName == "SELECT"))
				{
					Child.firstChild.value = -1;
				}
				Child = Child.nextSibling;
			}
		}
	}

	for(var i = 0; i < RowsToDisplay; i++)
	{
		var Row = AdvTable.rows[i];
		var Child = Row.firstChild;

		while(Child != null)
		{
			if((Child.firstChild) && (Child.firstChild.nodeName == "INPUT"))
			{
				Child.firstChild.value = "";
			}
			else if((Child.firstChild) && (Child.firstChild.nodeName == "SELECT"))
			{
				Child.firstChild.value = -1;
			}
			Child = Child.nextSibling;
		}
	}

	g_StreamMapRows.length = 0;


	var len = document.getElementById("InvisibleTable").rows.length - 1;
	var table = document.getElementById("InvisibleTable");
	for(var i = 0; i < len; i++)
	{
		table.deleteRow(-1);
	}

	len = document.getElementById("AdvInvisibleTable").rows.length - 1;
	table = document.getElementById("AdvInvisibleTable");
	for(var i = 0; i < len; i++)
	{
		table.deleteRow(-1);
	}

	if(bd.browser == "IE")
	{
		document.getElementById("BaseTableDiv").scrollTop = 0;
		document.getElementById("AdvTableDiv").scrollTop = 0;
	}

	GetDeviceInfo();
}
function ValidateBeforeApply(data)
{
	if(Validate_IP_Format(data[IP]) == false)
	{
		if(language == 0)
		{
			alert("Invalid IP Address. Please enter a valid Multicast IP Address.");
		}
		else
		{
			alert("无效的IP地址，请输入一个有效的组播IP地址。");
		}
		return false;
	}
	
	if(validateNumber(data[UDP]) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for UDP Port.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的UDP端口号。");
		}
		return false;
	}
	if((data[UDP] < 1)|| (data[UDP] > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Destination UDP Port is 1 - 65535.");
		}
		else
		{
			alert("目的UDP端口号的取值范围是1 - 65535。");
		}
		return false;
	}
	
	if((bacMode == 1) && (data[BAC_ENABLED] == "1"))
	{
		if(validateNumber(data[BAC_ROW]) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Backup UDP Port.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的备份UDP端口号。");
			}
			return false;
		}
		if((data[BAC_ROW] < 0) || (data[BAC_ROW] > 65535))
		{
			if(language == 0)
			{
				alert("Valid range for Backup UDP Port is 0 - 65535.");
			}
			else
			{
				alert("备份UDP端口号的范围是0 - 65535。");
			}
			return false;
		}
	}
	
	if(validateNumber(data[PRO_NUM_IN]) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Input Program Number.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的输入节目号。");
		}
		return false;
	}
	if((data[PRO_NUM_IN] < 0) || (data[PRO_NUM_IN] > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Input Program Number is 0 - 65535.");
		}
		else
		{
			alert("输入节目号的范围是0 - 65535。");
		}
		return false;
	}
	
	if(validateNumber(data[PRO_NUM_OUT]) == false )
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Output Program Number.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的输出节目号。");
		}
		return false;
	}
	if((data[PRO_NUM_OUT] < 1) || (data[PRO_NUM_OUT] > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Output Program Number is 1 - 65535.");
		}
		else
		{
			alert("输出节目号的范围是1 - 65535。");
		}
		return false;
	}
	
	if(validateNumber(data[PMV]) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for PMV.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的PMV。");
		}
		return false;
	}
	if((data[PMV] < 0) || (data[PMV] > 510))
	{
		if(language == 0)
		{
			alert("Valid range for PMV is 0 - 510.");
		}
		else
		{
			alert("PMV的范围是0 - 510。");
		}
		return false;
	}
	
	if(data[DATA_ENABLED] == "1")
	{
		if(validateNumber(data[DATA_RATE]) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Data Rate.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的数据码率。");
			}
			return false;
		}
		if((data[DATA_RATE] < 0) || (data[DATA_RATE] > 200000))
		{
			if(language == 0)
			{
				alert("Valid range for Data Rate is 0 - 200000.");
			}
			else
			{
				alert("数据码率的范围是0 - 200000。");
			}
			return false;
		}
	}
	
	if(bacMode == 1)
	{
		if(validateNumber(data[SWITCH_RATE]) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Switch Rate.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的切换码率。");
			}
			return false;
		}
		if((data[SWITCH_RATE] < 0) || (data[SWITCH_RATE] > 200000))
		{
			if(language == 0)
			{
				alert("Valid range for Switch Rate is 0 - 200000.");
			}
			else
			{
				alert("切换码率的范围是0 - 200000。");
			}
			return false;
		}
	}
	
	if(Validate_IP_Format(data[SOURCE_IP]) == false)
	{
		if(language == 0)
		{
			alert("Invalid IP Address. Please enter a valid Source IP Address.");
		}
		else
		{
			alert("无效的IP地址，请输入有效的源IP地址。");
		}
		return false;
	}
		
	// Special handling for updating BlockedPIDs
	var pidLen = data[BLOCKED_PIDS];
	for(var i = 0; i < pidLen; i++)
	{
		var checkBlockedPid = data[i + BLOCKED_PIDS + 1];	
		if(isValidBlockedPID(checkBlockedPid) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Blocked PIDs.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的PID值。");
			}
			return false;
		}
	}
	if(pidLen > 1024)
	{
		if(language == 0)
		{
			alert("The total number of entered Blocked PIDs is greater than 1024.");
		}
		else
		{
			alert("PID总个数不能超过1024个。");
		}
		return false;
	}
	if((pidLen % 2) != 0)
	{
		if(language == 0)
		{
			alert("Please enter Blocked PIDs in pairs.");
		}
		else
		{
			alert("PID请成对输入。");
		}
		return false;
	}
}

var addCount = 0;
var modifyCount = 0;
var deleteCount = 0;

var addRows = [];
var modifyRows = [];
var deleteRows = [];
function PerformApply()
{
	var len = g_StreamMapRows.length;
	for(var i = 0; i < len; i++)
	{
		if(g_StreamMapRows[i].slice(0,1) == "N")
		{
			// Added row
			var newRow;
			var data = g_StreamMapRows[i].split(",");
			if(ValidateBeforeApply(data) == false)
			{
				DisableApply(false);
				DisableReset(false);
				document.body.style.cursor="auto";
				window.status = "Done";
				return false;
			}
			else
			{
				DisableApply(true);
				DisableReset(true);

				window.status = "Applying settings, please wait...";
				document.body.style.cursor = "wait";
			}
			if(data[ACTIVE] != "50") // Dont add the row in the backend if the status of the new row is set to DELETE
			{
				addCount++;

				data[CHANNEL] = chIndexToDisplay(parseInt(data[CHANNEL]));
				newRow = data[ROW]; // Local index (index within the channel)
				for(var j = CHANNEL; j < data.length; j++)
				{
					newRow = newRow + "," + data[j];
				}
				addRows.push(newRow);
			}
		}//if
		
		// Modified row
		else if(g_StreamMapRows[i].slice(0,1) == "M")
		{
			var modRow;
			var data = g_StreamMapRows[i].split(",");
			if(ValidateBeforeApply(data) == false)
			{
				DisableApply(false);
				DisableReset(false);
				document.body.style.cursor="auto";
				window.status = "Done";
				return false;
			}
			else
			{
				DisableApply(true);
				DisableReset(true);

				window.status = "Applying settings, please wait...";
				document.body.style.cursor = "wait";
			}
			// Modified row
			modifyCount++;

			data[CHANNEL] = chIndexToDisplay(parseInt(data[CHANNEL]));
			modRow = data[ROW]; // Local index (index within the channel)
			for(var j = CHANNEL; j < data.length; j++)
			{
				modRow = modRow + "," + data[j];
			}
			modifyRows.push(modRow);
		}//else if
		
		// Delete row
		else if(g_StreamMapRows[i].slice(0,1) == "D")
		{
			DisableApply(true);
			DisableReset(true);
			// Deleted row
			deleteCount++;
			var data = g_StreamMapRows[i].split(",");
			data[CHANNEL] = chIndexToDisplay(parseInt(data[CHANNEL]));
			var delRow =  data[data.length - 1] + "," + data[CHANNEL];
			deleteRows.push(delRow);

		}//else if
	}
	if((addCount - deleteCount) > maxUdpNumber)
	{
		if(maxUdpNumber == 0)
		{
			if(language == 0)
			{
				alert("The udp port number is maximum, can't add a new port!");
			}
			else
			{
				alert("UDP端口个数已经是最大值，不能再添加新的端口！");
			}
		}
		else
		{			
			if(language == 0)
			{
				alert("You can add " + maxUdpNumber + " UDP port at most!");
			}
			else
			{
				alert("最多还可以添加" + maxUdpNumber + "个端口！");
			}
		}
		addCount = 0;
		modifyCount = 0;
		deleteCount = 0;
		
		addRows = [];
		modifyRows = [];
		deleteRows = [];
		return;
	}
	
	// Show a confirmation box when the time taken for apply is expected to be high
	if(addCount + modifyCount + deleteCount > 10)
	{
		if(language == 0)
		{
			alert("This operation may take a long time. Please do not navigate away from this page or close the browser till the confirmation box is shown.");
		}
		else
		{
			alert("该操作将会需要很长时间，请不要跳转其它页面或者关闭浏览器直到成功设置确认框弹出为止。");
		}
	}
	
	for(var i = 0; i < modifyCount; i++)
	{
		addRows.push(modifyRows[i]);
	}
	
	first = 1;
	setPostData();	
	setStreamData();
}

function GetRowChannelInfo(modifyString)
{
	var RowInfo = "";
	var info = modifyString.split(",");
	RowInfo = info[info.length - 1] + "," + info[1];
	return RowInfo;
}

var deleteCnt;//post delete row count
var deleteNumCnt;//post delete loop count
var addCnt;//post add row count
var addNumCnt;//post add loop count
function setPostData()
{
	deleteCnt = deleteCount;
	deleteNumCnt = parseInt(deleteCnt / deletePerPost);
	if((deleteCnt % deletePerPost) > 0)
	{
		deleteNumCnt = deleteNumCnt + 1;
	}
	
	addCnt = addCount + modifyCount;
	addNumCnt = parseInt(addCnt / addPerPost);
	if((addCnt % addPerPost) > 0)
	{
		addNumCnt = addNumCnt + 1;
	}
}

var postString = "";
var postDeleteString = "";
var postAddString = "";

var loopDelCnt = 1;
var deletePerPost = 32;

var loopAddCnt = 1;
var addPerPost = 10;

var first = 1;//add flag
function setStreamData()
{
	if(loopDelCnt == deleteNumCnt)
	{
		var j = (loopDelCnt - 1) * deletePerPost;
		var postDelCnt = deleteCnt - j;
		for(var i = j; i < (j + postDelCnt); i++)
		{
			if(i == j)	
			{
				postDeleteString = deleteRows[i];
			}
			else
			{
				postDeleteString = postDeleteString + "|" + deleteRows[i];//postDeleteString  = postDeleteString +"#"+postStream[0];
			}
		}	
		postString = "DELETE#" + postDelCnt + "#" + postDeleteString;		
		loopDelCnt++;
		PostStreamMapRows(postString);
	}
	else if(loopDelCnt < deleteNumCnt)
	{
		var j = (loopDelCnt - 1) * deletePerPost;
		for(var i = j; i < (j + deletePerPost); i++)
		{
			if(i == j)	
			{
				postDeleteString = deleteRows[i];
			}
			else
			{
				postDeleteString = postDeleteString + "|" + deleteRows[i];
			}
		}			
		postString = "DELETE#" + deletePerPost + "#" + postDeleteString;		
		loopDelCnt++;
		PostStreamMapRows(postString);
	}
	else if((loopDelCnt > deleteNumCnt) && (first ==1))
	{
		first = 0;
	}
//Last iteration
	if(first == 0)
	{
		if(loopAddCnt == addNumCnt)
		{
			var j = (loopAddCnt - 1) * addPerPost;
			postAddCnt =  addCnt - j;
			for(var i = j; i < (j + postAddCnt); i++)
			{
				if(i == j)
				{
					postAddString = addRows[i];
				}
				else
				{
					postAddString = postAddString + "|" + addRows[i];
				}
			}
			postString = "INSERT#" + postAddCnt + "#" + postAddString;
			loopAddCnt++;
			PostStreamMapRows(postString);
			return;
		}
		else if(loopAddCnt < addNumCnt)
		{
			var j = (loopAddCnt - 1) * addPerPost;
			for(var i = j; i < (j + addPerPost); i++)
			{
				if(i == j)
				{
					postAddString = addRows[i];
				}
				else
				{
					postAddString = postAddString + "|" + addRows[i];
				}
			}
			postString = "INSERT#" + addPerPost + "#" + postAddString;
			loopAddCnt++;
			PostStreamMapRows(postString);
			return;
		}
		else if(loopAddCnt > addNumCnt)
		{
			if(language == 0)
			{
				alert("Stream Map rows modified successfully.");
			}
			else
			{
				alert("映射表页面设置成功。");
			}
			window.location.reload();
			return;
		}
	}
}

function PostStreamMapRows(sValueString)
{
	var params = "type=2&cmd=2&userName=" + userName + "&mapSetString=" + sValueString;

	var xmlhttp = false;
	
	xmlhttp = getHTTPObject();
	xmlhttp.open("POST", "/goform/formIPQAM", true);
	xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xmlhttp.setRequestHeader("Content-length", params.length);

	xmlhttp.onreadystatechange = function()
   	{
    	if(xmlhttp.readyState == 4)
    	{
       		setTimeout("setStreamData()", 50);
		}
	}

	xmlhttp.send(params);
	return false;
}


function MM_showHideLayers() 
{ 
	var d; 
	var height;
	var but = document.getElementById("AdvSetDisplay");

	if(language == 0)
	{
		if(but.value == "Hide Advanced Settings")
		{
			but.value = "Show Advanced Settings";
			d = "none";
		}
		else
		{
			but.value = "Hide Advanced Settings"; 
			d = "";
			//PerformReload();
		}
	}
	else
	{
		if(but.value == "隐藏高级选项")
		{
			but.value = "显示高级选项";
			d = "none";
		}
		else
		{
			but.value = "隐藏高级选项"; 
			d = "";
			//PerformReload();
		}
	}
    document.getElementById("AdvSectionDiv").style.display = d;
    if(d != "none")
    {
		var BaseScroll = parseInt(document.getElementById("BaseTableDiv").scrollTop, 10);
		var AdvScroll = BaseScroll;

    	document.getElementById("AdvTableDiv").scrollTop = AdvScroll; // This will trigger the OnAdvScroll() event handler
		RenderAdvTable();
		height = h + 500;
	}
	else
	{
		height = h;
	}
	document.getElementById("agent").src = "http://" + mainIPAddr + "/../asp/agent.asp?t=" + new Date().getTime() + "#height=" + height;
}

function OnRuleScroll()
{
	document.getElementById("baseTable").scrollLeft = document.getElementById("baseRule").scrollLeft;
}

function OnBaseScroll()
{
	if (scrollLock == true)
	{
		scrollLock = false;
	}
	else
	{
		scrollLock = true;

		// Adjust the adv window"s scroll bar in proportionate to the base window"s scroll

		var BaseScroll = parseInt(document.getElementById("BaseTableDiv").scrollTop, 10);
		var AdvScroll = BaseScroll;

		document.getElementById("AdvTableDiv").scrollTop = AdvScroll; // This will trigger the OnAdvScroll() event handler
	}

	SyncDisplay(); // TODO: Check if this can be moved inside the else condition above
}

function OnAdvScroll()
{
	if (scrollLock == true)
	{
		scrollLock = false;
	}
	else
	{
		scrollLock = true;
		// Adjust the base window"s scroll bar in proportionate to the advanced window"s scroll
		var AdvScroll = parseInt(document.getElementById("AdvTableDiv").scrollTop, 10);
		var BaseScroll = ((AdvScroll * BASE_ROW_HEIGHT_INT) / 22); // AdvScroll;

		document.getElementById("BaseTableDiv").scrollTop = BaseScroll; // This will trigger the OnBaseScroll() event handler
	}

	SyncDisplay(); // TODO: Check if this can be moved inside the else condition above
}

function SyncDisplay()
{
	RenderBaseTable();
	RenderAdvTable();
}

function RenderBaseTable()
{
	var RowNo = parseInt(document.getElementById("BaseTableDiv").scrollTop, 10);
	
	RowNo = parseInt((RowNo) / BASE_ROW_HEIGHT_INT, 10); // 22 is the height of a single row in fox while 24 in IE
	var RowsToDisplay = parseInt(document.getElementById("BaseSettings").rows.length, 10);
	RowsToDisplay = RowsToDisplay - 2; // 2 rows in the heading table
	for(var i = RowNo; i < (RowNo + RowsToDisplay); i++)
	{
		if(i >= g_StreamMapRows.length)
		{
			RenderBlankRow(i - RowNo);
			continue;
		}
		RenderBaseRow(i, (i - RowNo), g_StreamMapRows[i]);
	}

	if(i >= g_StreamMapRows.length)
	{
		lastRowRendered = g_StreamMapRows.length - 1;
	}
	else
	{
		lastRowRendered = i - 1;
	}
}

function RenderAdvTable()
{
	var value;
	if(language == 0)
	{
		value = "Hide Advanced Settings";
	}
	else
	{
		value = "隐藏高级选项";
	}
	if(document.getElementById("AdvSetDisplay").value == value)
	{
		var RowNo = parseInt(document.getElementById("BaseTableDiv").scrollTop, 10); // Since the tables are "in-sync" we use BaseTableDiv here

		RowNo = parseInt((RowNo) / BASE_ROW_HEIGHT_INT, 10); // 22 is the height of a single row in fox while 24 in IE
		var RowsToDisplay = parseInt(document.getElementById("AdvSettings").rows.length, 10);
		RowsToDisplay = RowsToDisplay - 1; // 1 rows in the heading table

		for(var i = RowNo; i < (RowNo + RowsToDisplay); i++)
		{
			if (i >= g_StreamMapRows.length)
			{
				RenderAdvBlankRow(i - RowNo);
				continue;
			}
			RenderAdvRow(i, (i - RowNo), g_StreamMapRows[i]);
		}
	}

}

function RenderBaseRow(index, rowNo, rowData)
{
	var fields = rowData.split(",");
	var smapRow = document.getElementById("BaseSettings").rows[2 + rowNo];
	var smapRowCells = smapRow.cells;

	smapRowCells[INDEX_BASE].innerHTML = index; // Master index
	smapRowCells[ROW].innerHTML = fields[ROW];
	smapRowCells[CHANNEL].innerHTML = chIndexToDisplay(parseInt(fields[CHANNEL]));

	for (var i = IP; i <= SWITCH_RATE; i++)
	{
		smapRowCells[i].firstChild.value = fields[i];
	}
	DisableBeforeRender(rowNo);


	if(fields[0] == "M")
	{
		// Highlight modified row
		smapRow.style.backgroundColor = "yellow";
	}
	else if(fields[0] == "D")
	{
		// Highlight deleted row
		smapRow.style.backgroundColor = "red";
	}
	else if(fields[0] == "N")
	{
		// Highlight newly created row
		smapRow.style.backgroundColor = "green";
	}
	else
	{
		// Normal row
		smapRow.style.backgroundColor = "white";
	}
	
	smapRow.style.display = "";
	//smapRow.style.visibility = "visible";
}

function DisableBeforeRender(rowNo)
{
	var gbePairValue = parseInt($("#f" + rowNo).val(), 10);
	if(gbePairValue < 16)
	{
		if(bacMode == 1)
		{
			$("#g" + rowNo).attr("disabled", false);
		}
		else
		{
			$("#g" + rowNo).attr("disabled", true);
		}
	}
	else
	{
		if(bacMode10Gbe == 1)
		{
			$("#g" + rowNo).attr("disabled", false);	
		}
		else
		{
			$("#g" + rowNo).attr("disabled", true);
		}
	}
	var backupEnabled = document.getElementById(BAC_ENABLED_ID + rowNo);
	if((backupEnabled.disabled == false) && (backupEnabled.value == "1"))
	{
		document.getElementById(BAC_ROW_ID + rowNo).disabled = false;
	}
	else
	{
		document.getElementById(BAC_ROW_ID + rowNo).disabled = true;
	}
	
	if(document.getElementById(DATA_ENABLED_ID + rowNo).value == "1")
	{
		document.getElementById(DATA_RATE_ID + rowNo).disabled = false;
	}
	else
	{
		document.getElementById(DATA_RATE_ID + rowNo).disabled = true;
		document.getElementById(DATA_RATE_ID + rowNo).value = 0;
	}
	
	if((document.getElementById(STREAM_TYPE_ID + rowNo).value == "0")		//流类型为Normal也可设置PID
		|| (document.getElementById(STREAM_TYPE_ID + rowNo).value == "1") 
		|| (document.getElementById(STREAM_TYPE_ID + rowNo).value == "3"))
	{
		document.getElementById(BLOCKED_PIDS_ID + rowNo).disabled = false;
	}
	else
	{
		document.getElementById(BLOCKED_PIDS_ID + rowNo).disabled = true;
	}
}

function RenderAdvRow(index, rowNo, rowData)
{
	var fields = rowData.split(",");
	var smapRow = document.getElementById("AdvSettings").rows[1 + rowNo];
	var smapRowCells = smapRow.cells;

	smapRowCells[INDEX_ADV].innerHTML = index; // Master index

	smapRowCells[SRC_IP].firstChild.value = fields[SRC_IP + SWITCH_RATE];

	// Blocked PIDs
	var BlockedPID = "";
	for(var i = 0; i < fields[BLOCKED_PIDS]; i++)
	{
		BlockedPID = BlockedPID + "," + fields[BLOCKED_PIDS + i + 1];
	}
	smapRowCells[BLO_PIDS].firstChild.value = BlockedPID.substr(1);
	smapRowCells[MEM_ADDR].innerHTML = fields[MEMORY_ADDRESS + i];

	if(fields[0] == "M")
	{
		// Highlight modified row
		smapRow.style.backgroundColor = "yellow";
	}
	else if(fields[0] == "D")
	{
		// Highlight deleted row
		smapRow.style.backgroundColor = "red";
	}
	else if(fields[0] == "N")
	{
		// Highlight newly created row
		smapRow.style.backgroundColor = "green";
	}
	else
	{
		// Normal row
		smapRow.style.backgroundColor = "white";
	}

	smapRow.style.display = "";
	//smapRow.style.visibility = "visible";
}


function RenderBlankRow(rowNo)
{
	var smapRow = document.getElementById("BaseSettings").rows[2 + rowNo];
	smapRow.style.display = "none";
}

function RenderAdvBlankRow(rowNo)
{
	var smapRow = document.getElementById("AdvSettings").rows[1 + rowNo];
	smapRow.style.display = "none";
}


function OnStreamMapCellChange(obj)
{
	var row = obj.parentNode.parentNode; // This will give us the row objects reference
	var index = parseInt(row.cells[0].innerHTML);
	var GuiRowNo = parseInt(obj.id.substr(1), 10); // if id is "a2" GuiRowNo will be 2

	// Find out which field has changed
	var fieldIndex = obj.id.charCodeAt(0) - 97 + 1; // 97 is the char code for "a"
	var rowValue = g_StreamMapRows[index]; // This will be , separated
	var rowFields = rowValue.split(",");

	
	if(fieldIndex == IP)
	{
		if(Validate_IP_Format(obj.value) == false)
		{
			if(language == 0)
			{
				alert("Invalid IP Address. Please enter a valid Multicast IP Address.");
			}
			else
			{
				alert("无效的IP地址，请输入一个有效的组播IP地址。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == UDP)
	{
		if(validateNumber(obj.value) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for UDP Port.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的UDP端口。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value< 1) || (obj.value > 65535))
		{
			if(language == 0)
			{
				alert("Valid range for Destination UDP Port is 1 - 65535.");
			}
			else
			{
				alert("UDP端口的范围是1 - 65535。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == BAC_ROW)
	{
		if(validateNumber(obj.value) == false )
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Backup UDP Port.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的备份UDP端口。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value < 0) || (obj.value > 65535))
		{
			if(language == 0)
			{
				alert("Valid range for Backup UDP Port is 0 - 65535.");
			}
			else
			{
				alert("备份UDP端口的范围是0 - 65535。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == PRO_NUM_IN)
	{
		if(validateNumber(obj.value) == false )
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Input Program Number.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的输入节目号。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value < 0) || (obj.value > 65535))
		{
			if(language == 0)
			{
				alert("Valid range for Input Program Number is 0 - 65535.");
			}
			else
			{
				alert("输入节目号的范围是0 - 65535。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == PRO_NUM_OUT)
	{
		if(validateNumber(obj.value) == false )
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Output Program Number.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的输出节目号。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value < 1) || (obj.value > 65535))
		{
			if(language == 0)
			{
				alert("Valid range for Output Program Number is 1 - 65535.");
			}
			else
			{
				alert("输出节目号的范围是1 - 65535。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == PMV)
	{
		if(validateNumber(obj.value) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for PMV.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的PMV。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value < 0) || (obj.value > 510))
		{
			if(language == 0)
			{
				alert("Valid range for PMV is 0 - 510.");
			}
			else
			{
				alert("PMV的范围是0 - 510。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == DATA_RATE)
	{
		if(validateNumber(obj.value) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Data Rate.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的数据码率。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if ( (obj.value < 0) || (obj.value > 200000))
		{
			if(language == 0)
			{
				alert("Valid range for Data Rate is 0 - 200000.");
			}
			else
			{
				alert("数据码率的范围是0 - 200000。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == SWITCH_RATE)
	{
		if(validateNumber(obj.value) == false)
		{
			if(language == 0)
			{
				alert("Invalid number. Please enter a valid numeric value for Switch Rate.");
			}
			else
			{
				alert("无效的数字，请输入一个有效的切换码率。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		if((obj.value < 0) || (obj.value > 200000))
		{
			if(language == 0)
			{
				alert("Valid range for Switch Rate is 0 - 200000.");
			}
			else
			{
				alert("切换码率的范围是0 - 200000。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	else if(fieldIndex == SOURCE_IP)
	{
		if(Validate_IP_Format(obj.value) == false)
	    {
			if(language == 0)
			{
				alert("Invalid IP Address. Please enter a valid Source IP Address.");
			}
			else
			{
				alert("无效的IP地址，请输入一个有效的源IP地址。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
	}
	
	if(fieldIndex == BLOCKED_PIDS)
	{
		var pidLen;
		if(obj.value == "")
		{
			pidLen = 0;
		}
		else
		{
			// Special handling for updating BlockedPIDs
			var blockedPids = obj.value.split(",");
			pidLen = blockedPids.length;
		}
		for(var i = 0; i < pidLen; i++)
		{
			var checkBlockedPid = blockedPids[i];	
			if(isValidBlockedPID(checkBlockedPid) == false)
			{
				if(language == 0)
				{
					alert("Invalid number. Please enter a valid numeric value for Blocked PIDs.");
				}
				else
				{
					alert("无效的数字，请输入一个有效的PID值。");
				}
				return false;
			}
		}
		
		if(pidLen > 1024)
		{
			if(language == 0)
			{
				alert("The total number of entered Blocked PIDs is greater than 1024.");
			}
			else
			{
				alert("PID总个数不能超过1024个。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
		
		if((pidLen % 2) != 0)
		{
			if(language == 0)
			{
				alert("Please enter Blocked PIDs in pairs.");
			}
			else
			{
				alert("PID请成对输入。");
			}
			setTimeout(function () {obj.focus()}, 50);
			obj.select();
			return false;
		}
			
		// Check if the length is sufficient
		// rowFields[18] & (rowFields.length - 18 - 1) should EXACTLY be the same
		rowFields[BLOCKED_PIDS] = pidLen;
		for(var i = 0; i < pidLen; i++)
		{
			if((i + BLOCKED_PIDS + 1) < (rowFields.length - 1))
			{
				rowFields[i + BLOCKED_PIDS + 1] = blockedPids[i];
			}
			else
			{
				rowFields.splice(rowFields.length - 1, 0, blockedPids[i]);
			}
		}
		// If the length of rowFields is greater, trim the excess elements from the array.
		if((rowFields.length - 1) > (pidLen + BLOCKED_PIDS + 1))
		{
			rowFields.splice((pidLen + BLOCKED_PIDS + 1), (rowFields.length - 1 - pidLen - BLOCKED_PIDS - 1));
		}
	}//if
	else
	{
		// Update the row with the new value
		rowFields[fieldIndex] = obj.value;
	}

	if(rowFields[0] != "N") // Update the status according to modification only for existing and not for new rows
	{
		if(rowFields[ACTIVE] == 50) // The Active column is set to DELETE
		{
			rowFields[0] = "D";
		}
		else
		{
			rowFields[0] = "M";
		}
	}
	// Build a new row string and update g_StreamMapRows
	var newRowString = rowFields[0];
	for(var i = 1; i < rowFields.length; i++)
	{
		newRowString = newRowString + "," + rowFields[i];
	}

	g_StreamMapRows[index] = newRowString;

	RenderBaseRow(index, GuiRowNo, g_StreamMapRows[index]);
	RenderAdvRow(index, GuiRowNo, g_StreamMapRows[index]);

	DisableApply(false);
	DisableReset(false);
}


function ValidateBaseImplementRules()
{
	var StartQamChannel = parseInt(document.getElementById("QamBaseStart").value);
	var EndQamChannel = parseInt(document.getElementById("QamBaseEnd").value);
	var BaseStartRow = parseInt(document.getElementById("BaseStartRow").value);
	var BaseEndRow = parseInt(document.getElementById("BaseEndRow").value);

	if((ValidateDestIP() == false) || (ValidateDestUDP() == false) || (ValidateInProgBase() == false) || (ValidateOutProgBase() == false) || 
(ValidatePMVBase() == false) || (ValidateRowInc_IPaddress() == false) || (ValidateRowInc_UDPport() == false) || (ValidateRowInc_InProgNum() == false) || 
(ValidateRowInc_OutProgNum() == false) || (ValidateRowInc_PMV() == false) || (ValidateChanneloffset_IPaddr() == false) || 
(ValidateChanneloffset_UDP() == false) || (Validate_RowStart() == false) || (Validate_RowEnd() == false))
	{
		return false;
	}
	
	if(bacMode == 1)
	{
		if(document.getElementById("UdpBackupRule").value == 1)
		{
			if(ValidateBacRow() == false)
			{
				return false;
			}
		}
		if(ValidateSwitchRate() == false)
		{
			return false;
		}
	}
	
	if(document.getElementById("RateAdjustRule").value == 1)
	{
		if(ValidateDataRate() == false)
		{
			return false;
		}
	}
	
	
	if((StartQamChannel > EndQamChannel))
	{
		if(language == 0)
		{
			alert("Start QAM Channel is greater than End QAM Channel.");
		}
		else
		{
			alert("起始频点大于结束频点。");
		}
		return false;
	}
	if(BaseStartRow > BaseEndRow)
	{
		if(language == 0)
		{
			alert("Start Row is greater than End Row.");
		}
		else
		{
			alert("起始行大于结束行。");
		}
		return false;
	}
	return true;
}



//var validate_flag = 0; //delete by wyq at 11/10/13

function ValidateDestIP()
{
	var obj = document.getElementById("DestIpBase");
	var destIPaddr = obj.value;
	
	if(Validate_IP_Format(destIPaddr) == false)
	{
		if(language == 0)
		{
			alert("Invalid IP Address. Please enter a valid Multicast IP Address.");
		}
		else
		{
			alert("无效的IP地址，请输入有效的组播IP地址。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateDestUDP()
{
	var obj = document.getElementById("UdpBase");
	var UDPPort = obj.value;
	
	if(validateNumber(UDPPort) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for UDP Port."); 
		}
		else
		{
			alert("无效的数字，请输入有效的UDP端口。"); 
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((UDPPort < 1) || (UDPPort  > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for destination UDP Port is 1 - 65535.");
		}
		else
		{
			alert("UDP端口的范围是1 - 65535。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateBacRow()
{
	var obj = document.getElementById("BacRowRule");
	var BacRow = obj.value;
		
	if(validateNumber(BacRow) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Backup UDP Port.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的备份UDP端口。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((BacRow < 0) || (BacRow  > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Backup UDP Port is 0 - 65535.");
		}
		else
		{
			alert("备份UDP端口的范围是0 - 65535。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateInProgBase()
{
	var obj = document.getElementById("InProgBase");
	var inpPrgNum = obj.value;
	if(validateNumber(inpPrgNum) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Input Program Number."); 
		}
		else
		{
			alert("无效的数字，请输入一个有效的输入节目号。"); 
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((inpPrgNum < 0) || (inpPrgNum > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Input Program Number is 0 - 65535.");
		}
		else
		{
			alert("输入节目号的范围是0 - 65535。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}


function ValidateOutProgBase()
{
	var obj = document.getElementById("OutProgBase");
	var outPrgNum = obj.value;
	if(validateNumber(outPrgNum) == false )
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Output Program Number."); 
		}
		else
		{
			alert("无效的数字，请输入一个有效的输出节目号。"); 
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((outPrgNum  < 1) || (outPrgNum  > 65535))
	{
		if(language == 0)
		{
			alert("Valid range for Output Program Number is 1- 65535.");
		}
		else
		{
			alert("输出节目号的范围是1 - 65535。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidatePMVBase()
{
	var obj = document.getElementById("PmvBase");
	var PMVvalue = obj.value;
	if(validateNumber(PMVvalue) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for PMV."); 
		}
		else
		{
			alert("无效的数字，请输入一个有效的PMV。"); 
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((PMVvalue < 0) || (PMVvalue > 510))
	{
		if(language == 0)
		{
			alert("Valid range for PMV is 0 - 510.");
		}
		else
		{
			alert("PMV的范围是0 - 510。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateDataRate()
{
	var obj = document.getElementById("DataRateRule");
	var dataRate = obj.value;
		
	if(validateNumber(dataRate) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Data Rate.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的数据码率。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((dataRate < 0) || (dataRate > 200000))
	{
		if(language == 0)
		{
			alert("Valid range for Data Rate is 0 - 200000.");
		}
		else
		{
			alert("数据码率的范围是0 - 200000。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateSwitchRate()
{
	var obj = document.getElementById("SwitchRateRule");
	var switchRate = obj.value;

	if(validateNumber(switchRate) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Switch Rate."); 
		}
		else
		{
			alert("无效的数字，请输入有效的切换码率。"); 
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((switchRate < 0) || (switchRate  > 200000))
	{
		if(language == 0)
		{
			alert("Valid range for Switch Rate is 0 - 200000.");
		}
		else
		{
			alert("切换码率的范围是0 - 200000。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function changeBackup()
{
	var UdpBackup = document.getElementById("UdpBackupRule").value;
	EnableBaseRuleApply();
	if(UdpBackup == 1)
	{
		document.getElementById("BacRowRule").disabled = false;
	}
	else
	{
		document.getElementById("BacRowRule").disabled = true;
		document.getElementById("BacRowRule").value = 0;
	}
}

function changeRateEnabled()
{
	var RateEnabled = document.getElementById("RateAdjustRule").value;
	EnableBaseRuleApply();
	if(RateEnabled == 1)
	{
		document.getElementById("DataRateRule").disabled = false;
	}
	else
	{
		document.getElementById("DataRateRule").disabled = true;
		document.getElementById("DataRateRule").value = 0;
	}
}

function ValidateRowInc_IPaddress()
{
	var obj = document.getElementById("DestIpIncr");
	var destIPaddr = obj.value;
	if(validateNumber(destIPaddr) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for IP Address Row Increment.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的IP地址行增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateRowInc_UDPport()
{
	var obj = document.getElementById("UdpPortIncr");
	var udpIncValue = obj.value;
	if(validateNumber(udpIncValue) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for UDP Port Row Increment.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的UDP端口行增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateRowInc_InProgNum()
{
	var obj = document.getElementById("InProgIncr");
	var inpPrgNum = obj.value;
	if(validateNumber(inpPrgNum) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Input Program Number Row Increment.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的输入节目号行增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateRowInc_OutProgNum()
{
	var obj = document.getElementById("OutProgIncr");
	var outPrgNum = obj.value;
	if(validateNumber(outPrgNum) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Output Program Number Row Increment.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的输出节目号行增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateRowInc_PMV()
{
	var obj = document.getElementById("PmvIncr");
	var PMVIncValue = obj.value;
	if(validateNumber(PMVIncValue) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for PMV Row Increment.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的PMV行增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateChanneloffset_IPaddr()
{
	var obj = document.getElementById("DestIpChOffset");
	var chOffsetIPaddr = obj.value;
	if(validateNumber(chOffsetIPaddr) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for IP Address Channel Offset.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的IP地址频点增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateChanneloffset_UDP()
{
	var obj = document.getElementById("UdpPortChOffset");
	var chOffsetUDP = obj.value;
	
	if(validateNumber(chOffsetUDP) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for UDP Port Channel Offset.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的UDP端口频点增量。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function Validate_RowStart()
{
	var obj = document.getElementById("BaseStartRow");
	var rowStart = obj.value;
	if(validateNumber(rowStart) == false )
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Row Start in base table.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的起始行。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((rowStart < 0) || (rowStart  >= channelUdpNum))
	{
		if(language == 0)
		{
			alert("Valid range for Row Start in base table is 0 - " + (channelUdpNum - 1) + ".");
		}
		else
		{
			alert("起始行的范围是0 - " + (channelUdpNum - 1) + "。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}



function Validate_RowEnd()
{
	var obj = document.getElementById("BaseEndRow");
	var rowEnd = obj.value;
	if(validateNumber(rowEnd)==false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Row End in base table.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的结束行。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((rowEnd < 0) || (rowEnd  >= channelUdpNum))
	{
		if(language == 0)
		{
			alert("Valid range for Row End in base table is 0 - " + (channelUdpNum - 1) + ".");
		}
		else
		{
			alert("结束行的范围是0 - " + (channelUdpNum - 1) + "。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function ValidateAdvImplementRules()
{
	var SrcIp = document.getElementById("SrcIp").value;
	var AdvStartRow	= parseInt(document.getElementById("AdvStartRow").value);
	var AdvEndRow = parseInt(document.getElementById("AdvEndRow").value);
	var QamAdvStart	= parseInt(document.getElementById("QamAdvStart").value);
	var QamAdvEnd = parseInt(document.getElementById("QamAdvEnd").value);

	
	if((ValidateNonTabIPAddress() == false) || (Validate_RowStart_Advancedtable() == false) || (Validate_RowEnd_Advancedtable() == false))
	{
		return false;
	}
	
	if(AdvStartRow > AdvEndRow)
	{
		if(language == 0)
		{
			alert("Start Row of advanced settings is greater than End Row of adavanced settings.");
		}
		else
		{
			alert("高级规则的起始行大于结束行。");
		}
		return false;
	}
	
	if(QamAdvStart > QamAdvEnd)
	{
		if(language == 0)
		{
			alert("Start QAM Channel of advanced settings is greater than End QAM Channel of adavanced settings.");
		}
		else
		{
			alert("高级规则的起始频点大于结束频点。");
		}
		return false;
	}

	return true;
}


function ValidateNonTabIPAddress()    // used to validate ip addresses in fields not belonging to
{                                           // any of the tables -- Base Settings or Advanced Settings.
	var obj = document.getElementById("SrcIp");
	var advSourceIPaddr = obj.value;
	if(Validate_IP_Format(advSourceIPaddr) == false)
	{
		if(language == 0)
		{
			alert("Invalid IP Address. Please enter a valid Source IP address.");
		}
		else
		{
			alert("无效的IP地址，请输入一个有效的源IP地址。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function Validate_RowStart_Advancedtable()
{
	var obj = document.getElementById("AdvStartRow");
	var rowStartAdvTable = obj.value;
	if(validateNumber(rowStartAdvTable) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Row Start in advanced settings.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的高级规则起始行。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((rowStartAdvTable < 0) || (rowStartAdvTable  >= channelUdpNum))
	{
		if(language == 0)
		{
			alert("Valid range for Row Start in advanced settings is 0 - " + (channelUdpNum - 1) + ".");
		}
		else
		{
			alert("高级规则起始行的范围是0 - " + (channelUdpNum - 1) + "。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}

function Validate_RowEnd_Advancedtable()
{
	var obj = document.getElementById("AdvEndRow");
	var rowEndAdvTable = obj.value;
	if(validateNumber(rowEndAdvTable) == false)
	{
		if(language == 0)
		{
			alert("Invalid number. Please enter a valid numeric value for Row End in advanced settings.");
		}
		else
		{
			alert("无效的数字，请输入一个有效的高级规则结束行。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	if((rowEndAdvTable < 0) || (rowEndAdvTable  >= channelUdpNum))
	{
		if(language == 0)
		{
			alert("Valid range for Row End in base table is 0 - " + (channelUdpNum - 1) + ".");
		}
		else
		{
			alert("高级规则结束行的范围是0 - " + (channelUdpNum - 1) + "。");
		}
		setTimeout(function () {obj.focus()}, 50);
		obj.select();
		return false;
	}
	return true;
}


var g_defaultNewRowString = "N,0,0,0.0.0.0,00000,0,0,0,0,0,0,0,1,2,0,0,0,0.0.0.0,0,65535"; 
function AddRowToTable()
{
	var ChanNo;
	var index = lastRowRendered; // Where to insert the new row? Inserting in the row next to the row that has focus;
								 // Or when there is no focus, insert in the last row of the visible region 
								 // (which is lastRowRendered)
	if(TypeFlag == CHANNEL_TYPE)
	{
		if(g_StreamMapRows.length >= channelUdpNum)
		{
			if(language == 0)
			{
				alert("Can't add the UDP Port. The maximum value of UDP Port number in one channel is " + channelUdpNum + ".");
			}
			else
			{
				alert("不能添加UDP端口。每个频点的UDP端口个数最大值是" + channelUdpNum + "。");
			}
			return;
		}
		
	}
	if(lastRowRendered != -1)
	{
		if(curFocus != null)
		{
			// If there is a keyboard focus, take that position
			var row = curFocus.parentNode.parentNode;
			index = parseInt(row.cells[0].innerHTML);
			ChanNo = getChannelNo(index);
		}
		else
		{
			// There is no keyboard focus, but there are some rows rendered
			ChanNo = getChannelNo(lastRowRendered);
		}
	}
	else
	{
		if(TypeFlag == CHANNEL_TYPE)
		{
			ChanNo = GetDeviceChIndex(card_index, port_index, channel_index); 
		}
		else if(TypeFlag == PORT_TYPE)
		{
			var channel;
			if(ExitChannel[port_index - 1] != 0)
			{
				// No rows rendered (table is empty) and obviously, no keyboard focus either.
				for(var i = 0; i < PortChannelNum; i++)
				{
					if(((ExitChannel[port_index - 1] >>> i) & 1) != 0)
					{
						channel = (i + 1);
						break;
					}
				}
				// Starting channel for the current selection is used when there is no rows for a series of channels.
				ChanNo = GetDeviceChIndex(card_index, port_index, channel); 
			}
			else
			{
				if(language == 0)
				{
					alert("No Channels! Please add Channels in Card Setting page.");
				}
				else
				{
					alert("没有频点，请在卡设置页面添加频点。");
				}
				return;
			}
		}
	}

	var data = g_defaultNewRowString.split(","); // Channel number of default new row should be modified
	
	data[CHANNEL] = ChanNo;
	var newRow = data[0]; 

	for(var i = 1; i < data.length; i++)
	{
		newRow = newRow + "," + data[i];
	}


	g_StreamMapRows.splice(index, 0, newRow);

	// Create a row in the invisible table - this is used in adjusting the scrollbar
	var row = document.getElementById("InvisibleTable").insertRow(-1);
	row.style.height = BASE_ROW_HEIGHT; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
	var cell = row.insertCell(0);
	cell.innerHTML = g_StreamMapRows.length;

	row = document.getElementById("AdvInvisibleTable").insertRow(-1);
	row.style.height = "22px"; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
	cell = row.insertCell(0);
	cell.innerHTML = g_StreamMapRows.length;

	RenderBaseTable();
	RenderAdvTable();
}

function UpdateBaseTableRow(row_index, DestIP, Udp, Status, Ingress, Gbe, Type, UdpBackup, BacRow, InProg, OutProg, Pmv, DataEnabled, DataRate, SwitchRate)
{
	var modifiedRow = g_StreamMapRows[row_index];
	var data = modifiedRow.split(",");
	
	if(data[0] != "N") // If the row is already NEW we should not set it to modified. NEW rows remain NEW till Applied.
	{
		if(Status == 50)
		{
			data[0] = "D";
		}
		else
		{
			data[0] = "M";
		}
	}
	
	data[IP] = DestIP;
	data[UDP] = Udp;
	data[ACTIVE] = Status;
	data[INGRESS_PORT] = Ingress;
	data[GBE_PORT] = Gbe;
	data[STREAM_TYPE] = Type;
	data[BAC_ENABLED] = UdpBackup;
	data[BAC_ROW] = BacRow;
	data[PRO_NUM_IN] = InProg;
	data[PRO_NUM_OUT] = OutProg;
	data[PMV] = Pmv;
	data[DATA_ENABLED] = DataEnabled;
	data[DATA_RATE] = DataRate;
	data[SWITCH_RATE] = SwitchRate;

	modifiedRow = data[0];
	for(var i = 1; i < data.length; i++)
	{
		modifiedRow = modifiedRow + "," + data[i];
	}

	g_StreamMapRows.splice(row_index, 1, modifiedRow); // Replace the row at row_index with modifiedRow
}

function UpdateAdvTableRow(row_index, SrcIp)
{
	var modifiedRow = g_StreamMapRows[row_index];
	var data = modifiedRow.split(",");

	if(data[0] == "C")
	{
		// If the row is clean, make it MODIFIED
		data[0] = "M";
	}

	data[SOURCE_IP] = SrcIp;

	modifiedRow = data[0];

	for(var i = 1; i < data.length; i++)
	{
		modifiedRow = modifiedRow + "," + data[i];
	}

	g_StreamMapRows.splice(row_index, 1, modifiedRow); // Replace the row at row_index with modifiedRow
}
// Master index is the position where the row needs to be added in g_StreamMapRows
// Sub index is the running index within the channel - used for DB operations
function AddRowToMasterTable(master_index, sub_index, channel, destIP, UDP, Status,
											Ingress, Gbe, Type, UdpBackup, BacRow, InProg, 
											OutProg, Pmv, DataEnabled, DataRate, SwitchRate,
											sourceIP, blockedPids)
{
	if(Status == 50)
	{
		return false;
	}
	if(TypeFlag == PORT_TYPE)
	{
		var displayCh = chIndexToDisplay(channel);
		var portCh = parseInt(displayCh.split("/")[1].split(".")[1]) - 1;
		if(((ExitChannel[port_index - 1] >>> portCh) & 1) == 0)
		{
			return false;
		}
	}
	var newRow = "N," + sub_index + "," + channel + "," + destIP + "," + UDP + "," + Status + "," + Ingress+ "," + Gbe + "," + 
											Type + "," + UdpBackup + "," + BacRow + "," + InProg+ "," + OutProg + "," + 
											Pmv + "," + DataEnabled + "," + DataRate + "," + SwitchRate + "," +
											sourceIP + "," + blockedPids + "," + "65535";

	g_StreamMapRows.splice(master_index, 0, newRow);

	// Create a row in the invisible table - this is used in adjusting the scrollbar
	var row = document.getElementById("InvisibleTable").insertRow(-1);
	row.style.height = BASE_ROW_HEIGHT; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
	var cell = row.insertCell(0);
	cell.innerHTML = g_StreamMapRows.length;

	row = document.getElementById("AdvInvisibleTable").insertRow(-1);
	row.style.height = "22px"; // This value has to match the stream map row"s height. Only then the scrollbar"s thumb will be of proper size.
	cell = row.insertCell(0);
	cell.innerHTML = g_StreamMapRows.length;
	return true;
}

function GetNextIP(BaseIP, Incr)
{
	var IPArray = BaseIP.split(".");
	for(var i=0;i<IPArray.length;i++)
	{
		IPArray[i] = parseInt(IPArray[i]);
	}
	var offset = (IPArray[3] + Incr) % 255;
	Incr = ((IPArray[3] + Incr) - offset) / 255;
	IPArray[3] = offset;

	offset = (IPArray[2] + Incr) % 255;
	Incr = ((IPArray[2] + Incr) - offset) / 255;
	IPArray[2] = offset;

	offset = (IPArray[1] + Incr) % 255;
	Incr = ((IPArray[1] + Incr) - offset) / 255;
	IPArray[1] = offset;

	offset = (IPArray[0] + Incr) % 255;
	Incr = ((IPArray[0] + Incr) - offset) / 255;
	IPArray[0] = offset;

	return IPArray[0] + "."+ IPArray[1] + "." + IPArray[2] + "." + IPArray[3];
}

function getChannelNo(index)
{
	var channel = parseInt(g_StreamMapRows[index].split(",")[2]);
	return channel;
}

function ImplementBaseRules()
{
	if(ValidateBaseImplementRules() == false)
	{
		return;
	}
	
	var BaseIP, BaseUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, BaseInProg, BaseOutProg, BasePMV;
	var DataEnabled, DataRate, SwitchRate, RowIncrIP, RowIncrUDP, ChanIncrIP, ChanIncrUDP;
	var RowIncrInProg, RowIncrOutProg, RowIncrPMV, StartChan, EndChan;
	var StartRow, EndRow;
	
	BaseIP = document.getElementById("DestIpBase").value;
	BaseUDP = document.getElementById("UdpBase").value;
	Enabled = document.getElementById("RowActiveRule").value;
	IngressPort = document.getElementById("ingressPortRule").value;
	GbePort = document.getElementById("gbePortRule").value; 
	
	StreamType = document.getElementById("StreamTypeRule").value;
	UdpBackup = document.getElementById("UdpBackupRule").value;
	BackRow = document.getElementById("BacRowRule").value;
	
	BaseInProg = document.getElementById("InProgBase").value;
	BaseOutProg = document.getElementById("OutProgBase").value;
	BasePMV = document.getElementById("PmvBase").value;
	
	DataEnabled = document.getElementById("RateAdjustRule").value;
	DataRate = document.getElementById("DataRateRule").value;
	SwitchRate = document.getElementById("SwitchRateRule").value;
	RowIncrIP = parseInt(document.getElementById("DestIpIncr").value, 10);
	RowIncrUDP = parseInt(document.getElementById("UdpPortIncr").value, 10);
	RowIncrInProg = parseInt(document.getElementById("InProgIncr").value, 10);
	RowIncrOutProg = parseInt(document.getElementById("OutProgIncr").value, 10);
	RowIncrPMV = parseInt(document.getElementById("PmvIncr").value, 10);
	ChanIncrIP = parseInt(document.getElementById("DestIpChOffset").value, 10);
	ChanIncrUDP = parseInt(document.getElementById("UdpPortChOffset").value, 10);
	StartChan = parseInt(document.getElementById("QamBaseStart").value, 10);
	EndChan = parseInt(document.getElementById("QamBaseEnd").value, 10);
	StartRow = parseInt(document.getElementById("BaseStartRow").value, 10);
	EndRow = parseInt(document.getElementById("BaseEndRow").value, 10);
	if(document.getElementById("QamBaseStart").value == "")
	{
		if(language == 0)
		{
			alert("No Channels! Please add Channels in Card Setting page.")
		}
		else
		{
			alert("没有频点，请在卡设置页面添加频点。")
		}
		return;
	}
	
	var len = g_StreamMapRows.length;
	
	var curIP = BaseIP;
	var curUDP = BaseUDP;
	var curInProg = BaseInProg;
	var curOutProg = BaseOutProg;
	var curPMV = BasePMV;
	
	// Start and End row numbers are given
	for(var i = 0; i < len; i++)
	{
		var curChan = getChannelNo(i);
		var curRowNo = parseInt(g_StreamMapRows[i].split(",")[1], 10);
		
		// Handle Case when channels missing in top. 
		if((i == 0) && (curChan > StartChan))
		{
			// There are some missing channels in the given channel range
			var MissingChannels;
			if(EndChan >= curChan)
			{
				MissingChannels = curChan - StartChan;
			}
			else
			{
				MissingChannels = EndChan - StartChan + 1;
			}
			for(var newChan = StartChan; newChan < (StartChan + MissingChannels); newChan++)
			{
				curIP = GetNextIP(BaseIP, ChanIncrIP * (newChan - StartChan));
				curUDP = parseInt(BaseUDP, 10) + parseInt(ChanIncrUDP * (newChan - StartChan), 10);
				curInProg = BaseInProg;
				curOutProg = BaseOutProg;
				curPMV = BasePMV;
				
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable(i, row, newChan, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, 
					curInProg, curOutProg, curPMV, DataEnabled, DataRate, SwitchRate, "0.0.0.0", "0") == true)
					{
						i++;
						len++;
					}
					curIP = GetNextIP(curIP, RowIncrIP);
					curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
					curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
					curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
					curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);
				}
			}
		}
		
		if((curChan >= StartChan) && (curChan <= EndChan))
		{
			// On the beginning of a new channel, offset the IP and UDP by channel offsets
			if(g_StreamMapRows[i].split(",")[1] == "0")
			{
				curIP = GetNextIP(BaseIP, ChanIncrIP * (curChan - StartChan));
				curUDP = parseInt(BaseUDP, 10) + parseInt(ChanIncrUDP * (curChan - StartChan), 10);
				curInProg = BaseInProg;
				curOutProg = BaseOutProg;
				curPMV = BasePMV;
			}
			
			if((curRowNo >= StartRow) && (curRowNo <= EndRow))
			{
				// If the row number is present in the current channel, we update it.
				UpdateBaseTableRow(i, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, curInProg, 
					curOutProg, curPMV, DataEnabled, DataRate, SwitchRate);

				curIP = GetNextIP(curIP, RowIncrIP);
				curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
				curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
				curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
				curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);						
			}
		
			// Check if we are at the last row of the channel and still there are some rows that need to be updated
			// In this case we will be adding new rows
			if(((curRowNo < EndRow) && // Still rows to be updated
				((i + 1) < len) && // boundary check for the next condition
				(getChannelNo(i + 1) > curChan)) // we are at the last row of current channel
				||
				((curRowNo < EndRow) && // Still rows to be updated
				 (i == len - 1))) // and we are at the last row of the entire table
				
			{
				var insert_count = 0;
				// Add the required number of rows
				if(curRowNo < StartRow)
				{
					insert_count = EndRow - StartRow + 1;
				}
				else
				{
					insert_count = EndRow - curRowNo;
				}
				for(var j = (curRowNo + 1); j <= (curRowNo + insert_count); j++)
				{
					if(AddRowToMasterTable((i + 1), j, curChan, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, 
						curInProg, curOutProg, curPMV, DataEnabled, DataRate, SwitchRate, "0.0.0.0", "0") == true)
					{
						i++;
						len++;
					}
	
					curIP = GetNextIP(curIP, RowIncrIP);
					curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
					curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
					curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
					curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);							
				}
			}
		}//if((curChan >= StartChan) && (curChan <= EndChan))
		
		// Case to detect missing channels in the middle
		if(((i + 1) < len) &&		// still there are some rows in the table
			((getChannelNo(i + 1) - curChan) > 1)) // Next channel is not (curChan+1)
			
		{
			// There are some missing channels in the given channel range
			var start = 0;
			var end = 0;
			var MissingChannels = 0;
			if(curChan >= StartChan)
			{
				start = curChan;
			}
			else
			{
				start = StartChan - 1;
			}
			if(getChannelNo(i + 1) <= EndChan)
			{
				end = getChannelNo(i + 1) - 1;
			}
			else
			{
				end = EndChan;
			}
			if(end > start)
			{
				MissingChannels = end - start;
			}
			else
			{
				continue;
			}
			for(var newChan = (start + 1); newChan <= (start + MissingChannels); newChan++)
			{
				curIP = GetNextIP(BaseIP, ChanIncrIP * (newChan - StartChan));
				curUDP = parseInt(BaseUDP, 10) + parseInt(ChanIncrUDP * (newChan - StartChan), 10);
				curInProg = BaseInProg;
				curOutProg = BaseOutProg;
				curPMV = BasePMV;
				
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable((i + 1), row, newChan, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, 
					curInProg, curOutProg, curPMV, DataEnabled, DataRate, SwitchRate, "0.0.0.0", "0") == true)
					{
						i++;
						len++;
					}

					curIP = GetNextIP(curIP, RowIncrIP);
					curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
					curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
					curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
					curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);
				}
			}
		}
		
		// Case to detect missing channels in the end of the entire table
		if((i == (len - 1)) &&    // If we are at the last row of the table and
			(curChan < EndChan)) // Still there are channels to add
		{
			var start;
			if(StartChan <= curChan)
			{
				start = curChan;
			}
			else
			{
				start = StartChan - 1;
			}
			while(start < EndChan)
			{
				start++; // curChan is already processed; need to start from curChan + 1 or StartChan
				
				// Since this is the beginning of a new channel, we offset the values by channel offsets
				curIP = GetNextIP(BaseIP, ChanIncrIP * (start - StartChan));
				curUDP = parseInt(BaseUDP, 10) + parseInt(ChanIncrUDP * (start - StartChan), 10);
				curInProg = BaseInProg;
				curOutProg = BaseOutProg;
				curPMV = BasePMV;					
				
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable((i + 1), row, start, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, 
					curInProg, curOutProg, curPMV, DataEnabled, DataRate, SwitchRate, "0.0.0.0", "0") == true)
					{
						i++;
						len++;
					}
					
					curIP = GetNextIP(curIP, RowIncrIP);
					curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
					curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
					curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
					curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);
				}
			}
		}
	} // for (var i = 0; i < len; i++)
	
	// Handling the case - If the entire table is parsed and still the StartChan is not found
	if(len == 0)
	{
		i = 0;
		var curChan = StartChan;
		while(curChan <= EndChan)
		{
			// Since this is the beginning of a new channel, we offset the values by channel offsets
			curIP = GetNextIP(BaseIP, ChanIncrIP * (curChan - StartChan));
			curUDP = parseInt(BaseUDP, 10) + parseInt(ChanIncrUDP * (curChan - StartChan), 10);
			curInProg = BaseInProg;
			curOutProg = BaseOutProg;
			curPMV = BasePMV;					
			
			for(var j = 0; j <= (EndRow - StartRow); j++)
			{
				if(AddRowToMasterTable(i, j, curChan, curIP, curUDP, Enabled, IngressPort, GbePort, StreamType, UdpBackup, BackRow, 
				curInProg, curOutProg, curPMV, DataEnabled, DataRate, SwitchRate, "0.0.0.0", "0") == true)
				{
					i++;
					len++;
				}
				
				curIP = GetNextIP(curIP, RowIncrIP);
				curUDP = parseInt(curUDP, 10) + parseInt(RowIncrUDP, 10);
				curInProg = parseInt(curInProg, 10) + parseInt(RowIncrInProg, 10);
				curOutProg = parseInt(curOutProg, 10) + parseInt(RowIncrOutProg, 10);
				curPMV = parseInt(curPMV, 10) + parseInt(RowIncrPMV, 10);
			}
			curChan++;
		}
	}
	
	RenderBaseTable();
	RenderAdvTable();	
	DisableApply(false);
}


function ImplementAdvRules()
{
	if(ValidateAdvImplementRules() == false)
	{
		return;
	}
	
	var SrcIP;
	var StartRow, EndRow, StartChan, EndChan;

	SrcIP = document.getElementById("SrcIp").value;
	
	StartChan = parseInt(document.getElementById("QamAdvStart").value, 10);
	EndChan = parseInt(document.getElementById("QamAdvEnd").value, 10);
	
	if(document.getElementById("QamAdvStart").value == "")
	{
		if(language == 0)
		{
			alert("No Channels! Please add Channels in Card Setting page.")
		}
		else
		{
			alert("没有频点！请在卡设置页面添加频点。")
		}
		return;
	}
	
	StartRow = parseInt(document.getElementById("AdvStartRow").value, 10);
	EndRow = parseInt(document.getElementById("AdvEndRow").value, 10);


	var len = g_StreamMapRows.length;

	// Start and End row numbers are given
	for(var i = 0; i < len; i++)
	{
		var curChan = getChannelNo(i);
		var curRowNo = parseInt(g_StreamMapRows[i].split(",")[1], 10);
		
		// Handle Case when channels missing in top. 
		if((i == 0) && (curChan > StartChan))
		{
			// There are some missing channels in the given channel range
			var MissingChannels;
			if(EndChan >= curChan)
			{
				MissingChannels = curChan - StartChan;
			}
			else
			{
				MissingChannels = EndChan - StartChan + 1;
			}
			for(var newChan = StartChan; newChan < (StartChan + MissingChannels); newChan++)
			{
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable((i + row), row, newChan, "0.0.0.0", "00000", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", SrcIP,  "0") == true)
					{
						i++;
						len++;
					}
				}
			}
		}
		
		if((curChan >= StartChan) && (curChan <= EndChan))
		{
			// On the beginning of a new channel, offset the IP and UDP by channel offsets
			if(g_StreamMapRows[i].split(",")[1] == "0")
			{
				// Nothing to offset / increment on the start of a channel
			}
				
			if((curRowNo >= StartRow) && (curRowNo <= EndRow))
			{
				// If the row number is present in the current channel, we update it.
				UpdateAdvTableRow(i, SrcIP);
			}
		
			// Check if we are at the last row of the channel and still there are some rows that need to be updated
			// In this case we will be adding new rows
			if(((curRowNo < EndRow) && // Still rows to be updated
				((i + 1) < len) && // boundary check for the next condition
				(getChannelNo(i + 1) > curChan)) // we are at the last row of current channel
				||
				((curRowNo < EndRow) && // Still rows to be updated
				 (i == len - 1))) // and we are at the last row of the entire table
			{
			
				var insert_count = 0;
				// Add the required number of rows
				if(curRowNo < StartRow)
				{
					insert_count = EndRow - StartRow + 1;
				}
				else
				{
					insert_count = EndRow - curRowNo;
				}
				// Add the required number of rows
				for(var j = (curRowNo + 1); j <= (curRowNo + insert_count); j++)
				{
					if(AddRowToMasterTable((i + j - curRowNo), j, curChan, "0.0.0.0", "00000", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", SrcIP, "0") == true)
					{
						i++;
						len++;
					}
				}
			}
		}
			
		// Case to detect missing channels in the middle or between the curChan and the EndChan
		if(((i + 1) < len) &&		// still there are some rows in the table
			((getChannelNo(i + 1) - curChan) > 1)) // Next channel is not (curChan+1)
			
		{
			// There are some missing channels in the given channel range
			var start = 0;
			var end = 0;
			var MissingChannels = 0;
			if(curChan >= StartChan)
			{
				start = curChan;
			}
			else
			{
				start = StartChan - 1;
			}
			if(getChannelNo(i + 1) <= EndChan)
			{
				end = getChannelNo(i + 1) - 1;
			}
			else
			{
				end = EndChan;
			}
			if(end > start)
			{
				MissingChannels = end - start;
			}
			else
			{
				continue;
			}
			for(var newChan = (start + 1); newChan <= (start + MissingChannels); newChan++)
			{
				
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable((i + row + 1), row, newChan, "0.0.0.0", "00000", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", SrcIP, "0") == true)
					{
						i++;
						len++;
					}
				}
			}
		}
		
		// Case to detect missing channels in the end of the entire table
		if((i == (len - 1)) &&    // If we are at the last row of the table and
			(curChan < EndChan)) // Still there are channels to add
		{
			var start;
			if(StartChan <= curChan)
			{
				start = curChan;
			}
			else
			{
				start = StartChan - 1;
			}
			while(start < EndChan)
			{
				start++; // curChan is already processed; need to start from curChan + 1
				
				for(var row = 0; row <= (EndRow - StartRow); row++)
				{
					if(AddRowToMasterTable((i + row + 1), row, start, "0.0.0.0", "00000", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", SrcIP,  "0") == true)
					{
						i++;
						len++;
					}
				}
			}
		}
	}// for (var i = 0; i < len; i++)
	
	// Handling the case - If the entire table is parsed and still the StartChan is not found
	if(len == 0)
	{
		i = 0;
		var curChan = StartChan;
		while(curChan <= EndChan)
		{
			for(var j = 0; j <= (EndRow - StartRow); j++)
			{
				if(AddRowToMasterTable((i + j), j, curChan, "0.0.0.0", "00000", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", SrcIP, "0") == true)
				{
					i++;
					len++;
				}
			}
			curChan++;
		}				
	}
	
	RenderAdvTable();	
	RenderBaseTable();
	DisableApply(false);
}

function ResetBaseRules()

{
	document.getElementById("DestIpBase").value					= "0.0.0.0";
	document.getElementById("UdpBase").value					= "49156";
	document.getElementById("RowActiveRule").value				= 0;
	document.getElementById("ingressPortRule").value			= 0;
	document.getElementById("gbePortRule").value				= 0;
	document.getElementById("StreamTypeRule").value				= 0;
	document.getElementById("UdpBackupRule").value				= 0;
	document.getElementById("BacRowRule").value					= "0";
	document.getElementById("InProgBase").value					= "0";
	document.getElementById("OutProgBase").value				= "2";
	document.getElementById("PmvBase").value					= "2";
	document.getElementById("RateAdjustRule").value				= 0;
	document.getElementById("DataRateRule").value				= "0";
	document.getElementById("SwitchRateRule").value				= "0";

	document.getElementById("DestIpIncr").value					= "0";
	document.getElementById("UdpPortIncr").value				= "2";
	document.getElementById("InProgIncr").value					= "0";
	document.getElementById("OutProgIncr").value				= "1";
	document.getElementById("PmvIncr").value					= "1";

	document.getElementById("DestIpChOffset").value				= "0";
	document.getElementById("UdpPortChOffset").value			= "256";

	document.getElementById("BaseStartRow").value				= "0";
	document.getElementById("BaseEndRow").value					= "9";
	document.getElementById("QamBaseStart").value				= 0;
	document.getElementById("QamBaseEnd").value					= 0;
	document.getElementById("BacRowRule").disabled = true;
	document.getElementById("DataRateRule").disabled = true;
	
	/*if(bacMode == 1)
	{
		document.getElementById("gbePortRule").disabled = false;
		document.getElementById("UdpBackupRule").disabled = false;
		document.getElementById("SwitchRateRule").disabled = false;
	}
	else
	{
		document.getElementById("gbePortRule").disabled = true;
		document.getElementById("UdpBackupRule").disabled = true;
		document.getElementById("SwitchRateRule").disabled = true;
	}*/
	document.getElementById("InProgBase").disabled = false;
	document.getElementById("OutProgBase").disabled = false;
	document.getElementById("PmvBase").disabled = false;
	document.getElementById("InProgIncr").disabled = false;
	document.getElementById("OutProgIncr").disabled = false;
	document.getElementById("PmvIncr").disabled = false;
	disabledButton(document.getElementById("BaseRuleApply"), true);
	return;
}

function ResetAdvRules()
{
	document.getElementById("SrcIp").value						= "0.0.0.0";
	document.getElementById("AdvStartRow").value				= "0";
	document.getElementById("AdvEndRow").value					= "9";
	document.getElementById("QamAdvStart").value				= 0;
	document.getElementById("QamAdvEnd").value					= 0;
	disabledButton(document.getElementById("AdvRuleApply"), true);
	return;
}


function EnableBaseRuleApply()
{
	disabledButton(document.getElementById("BaseRuleApply"), false);
}

function EnableAdvancedRuleApply()
{
	disabledButton(document.getElementById("AdvRuleApply"), false);
}
