/* Copyright 2005, Ektron, Inc. */

//nodeType 
var ELEMENT_NODE = 1;

var g_design_ektPlatformInfo = null;
function design_isSafari()
{
	if (null == g_design_ektPlatformInfo && "function" == typeof PlatformInfo)
	{
		g_design_ektPlatformInfo = new PlatformInfo;
	}

	if (g_design_ektPlatformInfo)
	{
		return (g_design_ektPlatformInfo.isSafari);
	}
	else
	{
		return (false);
	}
}

function design_validateHtmlForm(form)
// form is name or index of, or reference to, the form element to validate.
// Returns first invalid element, or null.
{
	//  validation is supported for browser NS 6.2+ and IE 5+
	if (null == g_design_ektPlatformInfo && "function" == typeof PlatformInfo)
	{
		g_design_ektPlatformInfo = new PlatformInfo;
	}
	if (g_design_ektPlatformInfo)
	{
		if (g_design_ektPlatformInfo.isNetscape && g_design_ektPlatformInfo.browserVersion < 6.2) return null;
		if (g_design_ektPlatformInfo.isIE && g_design_ektPlatformInfo.browserVersion < 5) return null;
	}
	
	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 && oElem.currentStyle != null) 
	{
		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
		{	 // or "object" - again, for mac (safari), see notes below.
			var sFn = oElem.getAttribute("onblur");
			if (sFn)
			{
				try
				{
					oElem.fnonblur = new Function(sFn);

					oElem.fnonblur();
				}
				catch (e)
				{
					// ********************************************************
					//    ATTENTION
					//      
					//		  Safari appears to inovoke the new function we 
					//		create here (to handle the on-blur event (and 
					//		perform the validation) in the wrong context; 
					//      it runs in the calling windows context - which
					//      is a problem when we use things like the date
					//      picker popup, functions/etc that exist in the 
					//      main window are not available in the popup window
					//      contentext - so the code fails...
					//      
					//        If, instead, we evaluate the function then it
					//      runs in the context of this main window and behaves
					//      properly. We catch that failure and attempt to 
					//      handle it for Safari (or any other similarly 
					//      mis-behaving browser).
					//      
					//      Note that we cannot use the 'this' pointer
					//      in this case, we must replace it with the variable
					//      name that points to the element object - in this 
					//      case 'oElem' Also note that we asume that the 
					//      this pointer will only be passed once in the parameter
					//      list, that it will come before the comments, etc.,
					//      otherwise the following regular expression will need
					//      to be updated.
					//      
					// ********************************************************
					sFn = sFn.replace(/([\(\,]\s*)this(\s*[\,\)])/, '$1oElem$2');
					var fn = new Function(sFn);
					eval(sFn);
				}
			}
		}
		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 + ""; // Note: This string conversion is needed for Safari, 
									 // as the regular expression fails to handle the value 
									 // properly without it until some value has been placed
									 // into the input field (value may then be removed and it
									 // still works!). This way it always works properly.
									 // (Thanks Doug D! -BCB)
		}
	}
	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 (!result)
	{
		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;	
			}
		}
	}

	// Check for the presence of a customer defined validation-styling function:
	if ("function" == typeof customValidationStyle)
	{
		// call the users custom validation-styling function:
		customValidationStyle(oElem, result);
	}
	else
	{
		// use our built-in validation-styling function:
		design_validationStyle(oElem, result);
	}
}

function design_validationStyle(oElem, isValid)
{
	var parent = null;
	var elTypeName = oElem.tagName;

	// If browser is Safari, or control type is Select, but not both
	// Safari And Select-control (because Safari Select controls do not
	// generate an onBlur event) then add wrapper for border/style control:
	var specialCaseBorder = (design_isSafari() && ("INPUT" == elTypeName)) 
			|| ((!design_isSafari()) && ("SELECT" == elTypeName));
	
	if ("object" == typeof oElem)
	{
		parent = oElem.parentNode;
		
		if (("object" == typeof oElem.style) && ("object" == typeof parent))
		{
			if (isValid)
			{
				if (specialCaseBorder)
				{
					if (("SPAN" == parent.tagName) 
						&& ("design_validation_failed" == parent.className))
					{
						parent.className = "design_validation_passed";
					}
				}
				else
				{
					if (design_isSafari())
					{
						oElem.style.borderStyle = "solid";
						oElem.style.borderColor = "white";
						oElem.style.borderWidth = "0";
					}
					else
					{
						oElem.style.borderStyle = "";
						oElem.style.borderColor = "";
						oElem.style.borderWidth = "";
						// Do not simply remove style: it doesn't 
						// re-render in IE 5.5, may destabilize it...
					}
				}
			}
			else
			{
				if (("undefined" == typeof g_design_designMode) || (g_design_designMode != true))
				{
					if (specialCaseBorder)
					{
						// Ensure that the element is wrapped in our own 
						// span tag, so we can control the border style:
						if ((parent.tagName != "SPAN") 
							|| ((parent.className != "design_validation_failed")
								&& (parent.className != "design_validation_passed")))
						{
							var wrapper = document.createElement("span");
							wrapper = parent.insertBefore(wrapper, oElem);
							oElem = parent.removeChild(oElem);
							oElem = wrapper.appendChild(oElem);
							parent = wrapper;
						}

						parent.className = "design_validation_failed";
					}
					else
					{
						oElem.style.borderStyle = "";
						oElem.style.borderColor = "";
						oElem.style.borderWidth = "";
					}
				}
			}
		}
	}
}

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;
}



