/* Copyright 2005, Ektron, Inc. */

//nodeType 
var ELEMENT_NODE = 1;

var g_draw_border = true;

function design_validateHtmlForm(form)
// form is name or index of, or reference to, the form element to validate.
// Returns first invalid element, or null.
{
	var ektPlatformInfo = new PlatformInfo;
	//  validation is supported for browser NS 6.2+ and IE 5+
	if (ektPlatformInfo.isNetscape && ektPlatformInfo.browserVersion < 6.2) return null;
	if (ektPlatformInfo.isIE && ektPlatformInfo.browserVersion < 5) return null;
	if (ektPlatformInfo.isSafari) 
	{
		// in Safari, it only partly works.  It will draw the choices and checklists red border 
		// but it does not remove it. It does not draw border for all other form field. 
		g_draw_border = false;
	}
	
	var oForm;
	switch (typeof form)
	{
	case "string":
	case "number":
		oForm = document.forms[form];
		break;
	case "object":
		oForm = form;
		break;
	default:
		oForm = document.forms[0];
		break;
	}
	if (!oForm) return null;
	return design_prevalidateElement(oForm, null);
}

function design_prevalidateElement(oElem, oFirstInvalidElem)
{
	if (!oElem) return oFirstInvalidElem;
	if ("undefined" == typeof oElem.getAttribute) return oFirstInvalidElem;
	if ("design_prototype" == oElem.className) return oFirstInvalidElem;
	if ("object" == typeof oElem.currentStyle) 
	{
		if ("none" == oElem.currentStyle.display) return oFirstInvalidElem;
		if ("hidden" == oElem.currentStyle.visibility) return oFirstInvalidElem;
	}
	var validation = oElem.getAttribute("ektdesignns_validation");
	if (validation && validation != "none")
	{
		oElem.removeAttribute("ektdesignns_isvalid");
		design_validate_result = true; // just in case onblur handler fails to set the result
		if ("function" == typeof oElem.onblur)
		{
			oElem.onblur(); // return value in global design_validate_result
		}
		else //if ("string" == typeof oElem.onblur) //for mac browsers
		{
			var sFn = oElem.getAttribute("onblur");
			if (sFn)
			{
				oElem.fnonblur = new Function(sFn);
				oElem.fnonblur();
			}
		}
		if (null == oFirstInvalidElem && false == design_validate_result) 
		{
			oFirstInvalidElem = oElem;
		}
	}

	if (typeof oElem.childNodes != "undefined") 
	{
		for (var i = 0; i < oElem.childNodes.length; i++)
		{
			if (ELEMENT_NODE == oElem.nodeType)
			{
				oFirstInvalidElem = design_prevalidateElement(oElem.childNodes.item(i), oFirstInvalidElem);
			}
		}
	}
	return oFirstInvalidElem;
}

var g_oElemContainerForAttributes = null;

function design_getProtectedAttribute(oElem, name)
{
	// Processes attributes that may have be protected by eWebEditPro+XML.
	var retValue; // initially undefined
	if (oElem)
	{
		var ektAttr = oElem.getAttribute("ctagattrs");
		// eg, " ektdesignns_minoccurs=@zzquote;0@zzquote;" or @zzsquo;
		if ("string" == typeof ektAttr)
		{
			if (null == g_oElemContainerForAttributes)
			{
				g_oElemContainerForAttributes = document.createElement("span");
			}
			var strAttrs = ektAttr.replace(/\@zzquote\;/g,'"');
			strAttrs = strAttrs.replace(/\@zzsquo\;/g,"'");
			strAttrs = strAttrs.replace(/\@zzamp\;/g,"&");
			strAttrs = strAttrs.replace(/\@zzlt\;/g,"<");
			strAttrs = strAttrs.replace(/\@zzgt\;/g,">");
			g_oElemContainerForAttributes.innerHTML = "<span " + strAttrs + "> </span>";
			retValue = g_oElemContainerForAttributes.firstChild.getAttribute(name);	
		}
	}
	return retValue;
}

function design_getAttribute(oElem, name)
{
	// Processes attributes that may have be protected by eWebEditPro+XML.
	var retValue; // initially undefined
	if (oElem)
	{
		retValue = oElem.getAttribute(name);
		if ("undefined" == typeof retValue || null == retValue)
		{
			retValue = design_getProtectedAttribute(oElem, name);
		}
	}
	return retValue;
}

function design_getValue(oElem)
{
	if (!oElem) return;
	var bSupportInnerHTML = (typeof oElem.innerHTML != "undefined");
	if (typeof oElem.value != "undefined")
	{
		if ("INPUT" == oElem.tagName && ("checkbox" == oElem.type || "radio" == oElem.type))
		{
			var strValue = oElem.value + "";
			if (strValue.length > 0 && strValue != "true")
			{
				if (oElem.checked)
				{
					return strValue;
				}
				else
				{
					return "";
				}
			}
			else // boolean
			{
				if (oElem.checked)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		}
		else
		{
			return oElem.value;
		}
	}
	else if (typeof oElem.getAttribute != "undefined" && oElem.getAttribute("value") != null)
	{
		// In FireFox/Mozilla/Netscape7, the .value attribute is undefined if not standard (e.g., span)
		// and .getAttribute("value") is null when .value is standard (e.g., input).
		return oElem.getAttribute("value");
	}
	else if (bSupportInnerHTML && "content-req" == design_getAttribute(oElem, "ektdesignns_validation"))
	{
		return oElem.innerHTML; // CAUTION: .innerHTML is not well-formed and cannot be processed as XML
	}
	else if (bSupportInnerHTML && "mixed" == design_getAttribute(oElem, "ektdesignns_datatype"))
	{
		return oElem.innerText; // .innerHTML needs to be converted to XHTML, that is, well-formed
	}
	else if (typeof oElem.innerText != "undefined")
	{
		return oElem.innerText;
	}
	else if (bSupportInnerHTML)
	{
		return oElem.innerHTML.replace(/\<[^>]*\>/g, "");
	}
	else
	{
		return; // no data to test
	}
}

function design_setValue(oElem, value)
{
	if (!oElem) return;
	if (typeof oElem.value != "undefined")
	{
		if ("undefined" == typeof oElem.getExpression || "undefined" == typeof oElem.getExpression("value"))//ie5(win)
		{
			if ("INPUT" == oElem.tagName && ("checkbox" == oElem.type))
			{
				// boolean
				if ("true" == value || true == value)
				{
					oElem.checked = true;
				}
				else if ("false" == value || false == value)
				{
					oElem.checked = false;
				}
				else
				{
					oElem.value = value;
				}
			}
			else
			{
				oElem.value = value;
			}
		}
	}
	else if (typeof oElem.getAttribute != "undefined" && oElem.getAttribute("value") != null)
	{
		// In FireFox/Mozilla/Netscape7, the .value attribute is undefined if not standard (e.g., span)
		// and .getAttribute("value") is null when .value is standard (e.g., input).
		oElem.value = value;
	}
	else if (typeof oElem.innerHTML != "undefined" && "mixed" == design_getAttribute(oElem, "ektdesignns_datatype"))
	{
		if ("undefined" == typeof oElem.getExpression || "undefined" == typeof oElem.getExpression("innerHTML"))
		{
			oElem.innerHTML = value;
		}
	}
	else if (typeof oElem.innerText != "undefined")
	{
		if ("undefined" == typeof oElem.getExpression || "undefined" == typeof oElem.getExpression("innerText"))
		{
			oElem.innerText = value;
		}
	}
}

function design_evaluate(expression, value)
{
	var obj = new Object();
	obj.text = value + "";
	obj.fnDesignEvaluateExpression = new Function("return " + expression); 
	return obj.fnDesignEvaluateExpression();
}

function design_normalize_re(re, oElem)
{
	// only normalize for actual onblur event
	if (typeof g_design_prevalidateFormReentry == "undefined" || g_design_prevalidateFormReentry != true) 
	{
		var value = design_getValue(oElem);
		if ("undefined" == typeof value) return; // no data to test
		if ("undefined" != typeof RegExp.lastIndex) 
		{
			RegExp.lastIndex = 0;
		}
		
		var ary = re.exec(value);
		
		value = (null == ary ? "" : ary[0]);
		design_normalize_complete(oElem, value);
	}
}

function design_validate_re(re, oElem, invalidmsg)
{
	var value = design_getValue(oElem);
	if ("undefined" == typeof value) return; // no data to test

	var result = re.test(value);
	
	design_validate_complete(oElem, result, invalidmsg);

	return result;
}

function design_normalize_js(expression, oElem)
{
	// only normalize for actual onblur event
	if (typeof g_design_prevalidateFormReentry == "undefined" || g_design_prevalidateFormReentry != true) 
	{
		var value = design_getValue(oElem);
		if ("undefined" == typeof value) return; // no data to test
		
		var value = design_evaluate(expression, value);
		
		design_normalize_complete(oElem, value);
	}
}

function design_validate_js(expression, oElem, invalidmsg)
// value is optional
// returns true if valid or indeterminate, false if value fails reg exp.
{
	var value = design_getValue(oElem);
	if ("undefined" == typeof value) return; // no data to test
	
	var result = design_evaluate(expression, value);
	
	design_validate_complete(oElem, result, invalidmsg);
	return result;
}

function design_normalize_complete(oElem, value)
{
	design_setValue(oElem, value);
}

var design_validate_result = true;
function design_validate_complete(oElem, result, invalidmsg)
{
	design_validate_result = result;
	if (!oElem) return result;
	// Netscape 4.7 does not support oElem.title and oElem.style.
	
	if (invalidmsg && "string" == typeof oElem.title)
	{
		// Remove message from title attribute if it was appended.
		var p = oElem.title.indexOf(invalidmsg);
		if (p >= 0)
		{
			if (p > 0 && "\n" == oElem.title.charAt(p-1))
			{
				p -= 1;
			}
			oElem.title = oElem.title.substring(0, p);
		}
		// remove trailing line breaks
		p = oElem.title.length - 1;
		if (p >= 0 && "\n" == oElem.title.charAt(p))
		{
			while (p >= 0 && "\n" == oElem.title.charAt(p))
			{
				p--;
			}
			oElem.title = oElem.title.substring(0, p);
		}
	}
	if ("object" == typeof oElem.style)
	{
		if (result)
		{
			oElem.style.borderStyle = "";
			oElem.style.borderColor = "";
			oElem.style.borderWidth = "";
			//oElem.removeAttribute("style"); // doesn't re-render in IE 5.5, my destabilize it
		}
		else
		{
			if (typeof g_design_designMode == "undefined" || g_design_designMode != true)
			{
				if (g_draw_border)
				{
					oElem.style.borderStyle = "dashed";
					oElem.style.borderColor = "red";
					oElem.style.borderWidth = "2px";
				}
				if (invalidmsg && "string" == typeof oElem.title)
				{
					// Append message to title attribute unless it is already present.
					if (-1 == oElem.title.indexOf(invalidmsg))
					{
						if (oElem.title.length > 0)
						{
							oElem.title += " \n";
						}
						oElem.title += invalidmsg;	
					}
				}
			}
		}
	}
}

function design_validate_select(minIndex, oElem, invalidmsg) 
// minIndex = -1, 0, 1 etc.. (-1 = not selected; 0 = 1st on list etc)
// returns true if valid or indeterminate, false if index is 0 or -1.
{
	if (!oElem) return;
	if ("undefined" == typeof oElem.selectedIndex)
	{
		return; // not a select element
	}

	var result = (oElem.selectedIndex >= minIndex);
	// this has no visual effect on select tag, but it is needed to set the design_validate_result (global var).
	design_validate_complete(oElem, result, invalidmsg);
	return result;
}

function design_validate_choice(minSelected, maxSelected, oElem, invalidmsg) 
// returns true if valid or indeterminate, false otherwise.
// maxSelected = -1 if it has no limits.
{
	if (!oElem) return;
	if ("undefined" == typeof oElem.getElementsByTagName) return;
	var num_checked = 0;
	var oCurrElem;
	var bUseChecked;
	var aryElements = null;
	var validation = oElem.getAttribute("ektdesignns_validation");
	if ("choice-req" == validation)
	{
		aryElements = oElem.getElementsByTagName("input");
		bUseChecked = true;
	}
	else if ("select-req" == validation) //list box
	{
		aryElements = oElem.getElementsByTagName("option");
		bUseChecked = false;
	}
	if (aryElements)
	{
		for (var i = 0; i < aryElements.length; i++)
		{
			oCurrElem = aryElements[i];
			if (bUseChecked)
			{
				if (oCurrElem.checked)
				{
					num_checked++;
				}
			}
			else //list box
			{
				if (oCurrElem.selected)
				{
					num_checked++;
				}
			}
		}
	}
	var result = (minSelected <= num_checked && (maxSelected <= 0 || num_checked <= maxSelected));	
	design_validate_complete(oElem, result, invalidmsg);
	return result;
}

// private
function design_canElementReceiveFocus(oElem)
// Returns true if form element can receive the focus, false if not.
{
	if (!oElem) return false;
	var strType = oElem.type + "";
	if ("hidden" == strType) return false;
	if ("object" == typeof oElem.currentStyle) 
	{
		if ("none" == oElem.currentStyle.display) return false;
		// Unfortunately, currentStyle.visibility may return "inherit" (even for all parents), which is not helpful.
		if ("hidden" == oElem.currentStyle.visibility) return false;
	}
	var strDisabled = oElem.disabled + "";
	if ("true" == strDisabled) return false;
	if (oElem.isDisabled) return false;
	var strIsTextEdit =  oElem.isTextEdit + "";
	if ("false" == strIsTextEdit) return false;
	var strFocusMethod = typeof oElem.focus;
	if ("function" != strFocusMethod && "object" != strFocusMethod) return false;
	return true;
}




