/*
 * The Apache Software License, Version 1.3
 *
 * Copyright (c) 2003 Institute of Information Science, 
 * Academia Sinica, Taiwan. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by Jenghan Hsieh,
 *        Bike Hsu. (http://axeframework.sourceforge.net/) during
 *        2002-04/12 and by Jenghan Hsieh at Academia Sinica, Taiwan
 *        during 2003-01/07."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "AXEFramework", and "Academia Sinica, Taiwan" must not 
 *    be used to endorse or promote products derived from this software
 *    without prior written permission. For written  permission, please
 *    contact jenghan@iis.sinica.edu.tw.
 *
 * 5. Products derived from this software may not be called "AXEFramework"
 *    nor may "AXEFramework" appear in their names without prior written
 *    permission of the author.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For more information on the Architectural XML Editing
 * Framework, please see
 * <http://axeframework.sourceforge.net/>.
 *
 * ====================================================================
 *
 *  We use a javascript module called "InnerHTML for Mozilla - innerHTML.js" 
 *  by Erik Arvidsson for cross-browser compatibility issues and debugging. 
 *  More information about this module can be found at 
 *  http://webfx.nu/dhtml/mozInnerHTML/mozInnerHtml.html
 *
 
  [2003-10-16 bike] 增加 _interop_GetLocalName, 解決 IE, Mozilla, XML, HTML 對 DOMLevel2 localName 的支援.
							 
  [2003-10-20 bear] 修改 __ExtractXML, 修補 Mozilla1.4 XML Attribute 的 NS Declaration 不會出現的怪問題.
  
  [2003-10-20 bear] Added _interop_removeChildren( oTarget ) , which remove all the childNodes of the oTarget.
 
  [2003-10-20 bear] Fixed the improper dependency in Core.js( __doExpandTemplate() ) with references to the assumed global 'PROTOTYPES' object

  [2003-10-27 bear] Regular Expression validation is temprorarily removed. patch for the problem found on PHP server side include.
  
  [2003-10-28 bike] code rearrange in _core_ExpandTemplate()

  -----	V1.2 -------------------
	
  [2005-03-24 max] fixed __doExpandTemplate(), error occured when defaul value is used.

  [2005-04-05 max] fixed _ProcessNodeValue() item which doesn't have _NAME attribute will not be extract.
	
  [2005-04-12 max] add _ProcessNodeValue() can support empty tags, use value=" " to output a empty tags
  
  [2005-12-27 max] add _EMPTY flag when the input text is empty value.
  
 *************************************************
 *                    READ ME FIRST !!!
 *************************************************
 *
 *  This core.js is separate into two parts, the 
 *  first is the [interop] section for the cross-browser
 *  compatibility, the second is the [core] section.
 *
 *  The [core] section consists of two rather large
 *  functions each performing a distinct unit operation.
 *  These two operations are the foundation of the
 *  framework. Enhancements and improvements 
 *  are welcome.
 *  
 */
 
 
/* ======================================
    part I.  [interop] Internet Explorer / Mozilla Interoperability
   ---------------------------------------------------------------------

     Properties
    ----------------
		is_ie : bool  , determine the user agent type

     Public Methods
    ----------------
		_interop_GetDocument()
		_interop_GetLocalName()
		_interop_CreateElementNS()
		_interop_CreateAttributeNS()
		_interop_SerializeXMLElement()
		_interop_getTextValue()
		_interop_setTextValue()
		_interop_removeChildren()

   ======================================
 */

var __agt=navigator.userAgent.toLowerCase();
var is_ie = ((__agt.indexOf("msie") != -1) && (__agt.indexOf("opera") == -1));

//
// create XML Object
function _interop_GetDocument()
{

	if (is_ie)
	{
		var odXML = new ActiveXObject("Msxml2.DOMDocument.3.0") ;
		odXML.async = false;
   		odXML.setProperty("SelectionLanguage", "XPath");
		odXML.setProperty("SelectionNamespaces", "xmlns:j='urn::JPGSystem' xmlns:a='urn::DXAF-architecture'" );

	}
	else if (document.implementation && document.implementation.createDocument)
	{
		var odXML = document.implementation.createDocument("", null, null );
	}
	
	return( odXML );
}

function _interop_GetLocalName(odXML)

{
	if(odXML.nodeType != 1)
	{
		return "";
	}
	
	if (is_ie)
	{
		if(odXML.baseName)
		{	return odXML.baseName;
		}
		else
		{	return odXML.tagName;
		}
	} 
	else
	{	return odXML.localName;
	}
}

function _interop_CreateElementNS( odXML, cTagName, cNS )
{
	var oResult;

	if (is_ie)
	{
		if(__WithNameSpace)
		{ //bike 2004/09/23
			oResult = odXML.createNode( 1, "o:" + cTagName, cNS );
		}
		else
		{	oResult = odXML.createNode( 1, cTagName, "");
		}
		
		return( oResult );
		
	}
	else if (document.implementation && document.implementation.createDocument) 
	{
		if(__WithNameSpace)
		{
			oResult = odXML.createElementNS( cNS, "o:" + cTagName ); //bike 2004/09/23
		}
		else
		{
			oResult = odXML.createElementNS( cNS, cTagName );
		}
		return( oResult );
	}
}

function _interop_CreateAttributeNS( odXML, cAttrName, cNS ){

	var oResult;
	if (is_ie)
	{
		if(__WithNameSpace){ //bike 2004/09/23
		oResult = odXML.createNode( 2, "a:" + cAttrName, cNS );
		}
		else{
			oResult = odXML.createNode( 2, cAttrName, "");
		}
		return( oResult );
	} else if (document.implementation && document.implementation.createDocument) {
		if(__WithNameSpace){ //bike 2004/09/23
		oResult = odXML.createAttributeNS( cNS, "a:" + cAttrName );
		}
		else{
			oResult = odXML.createAttributeNS( cNS, cAttrName );
		}
		return( oResult );
	}
}

function _interop_SerializeXMLElement( oXML ){

	if ( ! is_ie ){
		return( (new XMLSerializer()).serializeToString( oXML )) ;
	} else {
		return( oXML.xml );
	}
}


function _interop_getTextValue( oNode ){

	var oChildList = oNode.childNodes;
	var retVal = "";
	
	for( var i = 0; i < oChildList.length; i++ ){
		var oCurrentChild = oChildList[i];
		retVal += _interop_getTextValue( oCurrentChild );		
	}
	
	if( oNode.nodeType == 3 ){
		return( trim( oNode.nodeValue ) );
	} else {
		return( retVal );
	}
}

function _interop_setTextValue( oNode, cValue ){

	if( oNode.nodeType == 3 ){
		oNode.value = cValue;
		return( true );
	} else if (oNode.nodeType == 1) {
		var oChildList = oNode.childNodes;
		
		for( var i = 0; i < oChildList.length ; i++ ){
			oNode.removeChild(oChildList[i]);
			//debug( oNode.innerHTML );
		}
		oNode.appendChild( document.createTextNode( cValue ) ) ;
	}
}

function _interop_removeChildren( oTarget ){

	var oChildList = oTarget.childNodes;
	for( var i = oChildList.length; i > 0 ;){
		oTarget.removeChild(oChildList[--i]);
	}
}

/* ======================================
    part II.  [core]  XML Extraction and Template Expansion
   ---------------------------------------------------------------------

     Properties
    ----------------
	     __regexCheckVerbose : bool

     Public Methods
    ----------------
		_core_ExtractXML( )
		_core_ExpandTemplate( )

     Private Method
    ----------------
		_regexCheck

   =======================================
*/

//var __regexCheckVerbose = true;
var __regexCheckVerbose = false;
var __WithNameSpace = false;

/*
	DOM -> XML
*/
function _core_ExtractXML( oRecord )
{
	var oResult = __ExtractXML( oRecord, _interop_GetDocument() );	
	
	return( oResult );
}

	//
	//  There's a strange bug in Mozilla 1.4, that the namespace of XML Attributes 
	//	will not present in serialized XML document. I apply a patch here in __ExtractXML
	//  in order to solve the problem temporarily.  jenghan
	// -----------------------------------------------------------------------------------------------
	function __ExtractXML( oRecord, odResult )
	{
	    oRecord = __d( oRecord, "_CONTAINER" );
	   	var cDOCTYPE = oRecord.getAttribute("_CONTAINER");

	   	var cNS = oRecord.getAttribute("_NS");
	   	
		if( cDOCTYPE != null )
		{	
			if( __WithNameSpace && (cNS == null))
			{
				alert( "no namespace declaration for XML instance." );
				cNS = "namespace";
			}
			
			var oRoot = _interop_CreateElementNS( odResult, cDOCTYPE, cNS );

			odResult.appendChild( oRoot );
			
			var result = _traverseContainer( oRecord, oRoot, cNS );

			if(result == "" || String( result ) == "undefined")
			{
				return( oRoot );
			}
			else
			{
				return(result);
			}
		}
		else 
		{

			// should raise an error here...
			alert( "_core_ExtractXML, Target HTML Node is not a valid container." );
			return( null );
		}
	}

		function _traverseContainer( oTarget, oXMLContext, cNamespace ){			
			
			var oDocument = oXMLContext.ownerDocument;
			var oChildNodes = oTarget.childNodes ;
			
			if( oChildNodes.length > 0 ) {
			
				for( var  i = 0 ; i < oChildNodes.length ; i++ ) {

					var oCurrentNode = oChildNodes[i];
					
					if ( oCurrentNode.nodeType == 1) 
					{
						
						var result = _ProcessNodeValue( oCurrentNode, oXMLContext, cNamespace );
						
						if ( result != "")
						{
							return(result);
						}
					}
				}
			}
		
			return("");
		}


		function _ProcessNodeValue( oCurrentNode, oXMLContext, cNamespace )
		{			
			var oDocument = oXMLContext.ownerDocument;

// debug
//oCurrentNode.style.border='1px red solid';

			//if( oCurrentNode.getAttribute("_NS") != null ) cNamespace = oCurrentNode.getAttribute("_NS"); //bike 2004/09/23
			
			switch( oCurrentNode.tagName )
			{
				case "INPUT" :		
					switch( oCurrentNode.type ) 
					{
						case "button" : break;
						case "checkbox" :
						case "radio" :
	
							if( oCurrentNode.checked )
							{
								try
								{
									var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.getAttribute("_NAME"), cNamespace );
																		
									//max 2005/04/12, support empty tags									
									if( oCurrentNode.value != " " )
										tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );									
								}
								catch (e)
								{
									try
									{
										var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.id, cNamespace );
										tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
									}
									catch (e)
									{
										var tmpElm = null;
									}
								}
			
								if ( tmpElm != null ) oXMLContext.appendChild( tmpElm );
	
							}
							else 
							{
								var tmpElm = null;
							}
	
							break;

						default :
					
//  [2003-10-27 bear] Regular Expression validation is temprorarily removed.
//  ------------------------------------------------------------------------
//						var RegExFlag = __regexCheck(oCurrentNode);
//						if(RegExFlag != "") return(RegExFlag);							
							
							try 
							{
								var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.getAttribute("_NAME"), cNamespace );
								//alert(oCurrentNode.value);						
								var ret = tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
							}
							catch (e)
							{
								//alert("catch");
								try
								{
									var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.id, cNamespace );
									tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
								}
								catch (e)
								{	// max 2005/04/05
									// strange ? no _NAME attribute will be extract
									break;
									var tmpElm = oDocument.createTextNode( oCurrentNode.value );
								}
							}
							
							oXMLContext.appendChild( tmpElm );
					}

					break;
				
				case "SELECT" :
					try
					{
						var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.getAttribute("_NAME"), cNamespace );
						
						if( oCurrentNode.value != '' )
						{
							tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
						}
						else
						{
							tmpElm.appendChild( oDocument.createTextNode( _SelectedText(oCurrentNode) ) );
						}

					}
					catch (e)
					{	

						try
						{
							var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.id, cNamespace );
							tmpElm.appendChild( oDocument.createTextNode( _SelectedText(oCurrentNode) ) );
						}
						catch (e)
						{	// max 2005/04/05
							// strange ? no _NAME attribute will be extract
							break;
							var tmpElm = oDocument.createTextNode( _SelectedText(oCurrentNode) );
						}

					}
					oXMLContext.appendChild( tmpElm );
		
					break;
							
				case "TEXTAREA" :

						// Performs regular expression check ...
						// --------------------------------------------
						// var RegExFlag = __regexCheck(oCurrentNode);
						// if(RegExFlag != "") return(RegExFlag);

					try
					{
						var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.getAttribute("_NAME"), cNamespace );
						tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
					}
					catch (e)
					{
						try
						{
							var tmpElm = _interop_CreateElementNS( oDocument, oCurrentNode.id, cNamespace );
							tmpElm.appendChild( oDocument.createTextNode( oCurrentNode.value ) );
						}
						catch (e)
						{
							var tmpElm = oDocument.createTextNode( oCurrentNode.value );
						}
					}
					oXMLContext.appendChild( tmpElm );
		
					break;
					
				default :
					var cContainerName = oCurrentNode.getAttribute("_CONTAINER");
	
					if( cContainerName != null )
					{
						var oChild = _interop_CreateElementNS( oDocument, cContainerName, cNamespace );
						oXMLContext.appendChild( oChild );
						return( _traverseContainer( oCurrentNode, oChild, cNamespace ) );
					}
					else
					{ 
						return( _traverseContainer( oCurrentNode, oXMLContext, cNamespace ) );
					}
			} 

			if( oCurrentNode.getAttribute("_IDX") != null && tmpElm != null )
			{
				var oAttr = _interop_CreateAttributeNS( oDocument, "idx", "urn::DXAF-architecture");
				oAttr.value = oCurrentNode.getAttribute("_IDX");
				tmpElm.setAttributeNode( oAttr );
			}
			
			return(""); //正確執行
		}


// Check Box will be reset after append Child in IE, we need to restore it.
var checkboxArray;

function restoreCheckbox()
{
	for(var i = 0; i < checkboxArray.length; i ++){
		checkboxArray[i].checked = true;
	}
}

/*
	XML -> DOM
*/

var emptyArray = new Array();
var deleteArray = new Array();
var	oPROTOTYPE;
var oXML;
	
function _core_ExpandTemplate( tXML, oPROTO)
{
	oPROTOTYPE = oPROTO;
	oXML = tXML;
    /* ==========================================================
     *
     *	This function find template from oPROTOTYPE and fill data into it with oXML.
     *	
     *   Critiria 1 : no containers of the same name in the same level.
     *   Critiria 2 : no two nodes would has the same name with different type.
     *
     *  return when 
     *
     *    1. XML container vs a leaf node, 
     *    2. there are more XML leaf nodes vs less leaf HTML nodes with the same name.
     *
     *    Search the DIVs with _REF attribute and substitute them with the container 
     *  in PROTOTYPE. PROTOTYPE Container will be added in sequence of XML , not the
     *  HTML. All PROTOTYPE containers will append to the end of parent.
     *
     *  If there are other elements(beside PROTOTYPE Container) with PROTOTYPE 
     *  containers under the same parent, they will appear in front of PROTOTYPE 
     *  containers.
     *
     */
     
	// Get the first container.
	cDocumentType = _interop_GetLocalName(oXML);
     	
	// reset checkbox array.
	checkboxArray = new Array();

	oTable = __d( oPROTOTYPE, "_CONTAINER", cDocumentType ).cloneNode(true);

	// redundant element to be delete at least.
	//var deleteArray = new Array();
	
	var result = __doExpandTemplate(oXML, oTable);

	for(var i = 0; i < deleteArray.length; i++)
	{
		deleteArray[i].parentNode.removeChild(deleteArray[i]);
	}

	// clear _EMPTY node value that we marked before.
	for(var i = 0; i < emptyArray.length; i++)
	{
		emptyArray[i].value="";
	}
	
	return( oTable );
}

    /*	===== private functions ===== */

   	// Get Node by _CONTAINER of _NAME or ID or _REF
    // -----------------------------------------------------------

	function GetNodeByRCNI(oNodes, cRCNI)
	{
		for(var i = 0; i < oNodes.length; i++)
		{
			if(oNodes[i].getAttribute("_REF"))
			{
				if(oNodes[i].getAttribute("_REF") == cRCNI) return(i);
			}
			else if(oNodes[i].getAttribute("_CONTAINER"))
			{
				if(oNodes[i].getAttribute("_CONTAINER") == cRCNI) return(i);
			}
			else if(oNodes[i].getAttribute("_NAME"))
			{
				if(oNodes[i].getAttribute("_NAME") == cRCNI) return(i);
			}
			else if(oNodes[i].getAttribute("id"))
			{
				if(oNodes[i].getAttribute("id") == cRCNI) return(i);
			}
		}
		return false;
	}

   	// Get next Node with the same _NAME or id.
    // ------------------------------
	function GetNextSilbingByNI(aTableChilds, tablePosition)
	{
		var cNI;
		var oCurrrentNode = aTableChilds[tablePosition];
		var i = tablePosition;
		
		if(oCurrrentNode.getAttribute("_NAME")){
			cNI = oCurrrentNode.getAttribute("_NAME")
		}
		else if(oCurrrentNode.getAttribute("id")){
			cNI = oCurrrentNode.getAttribute("id")
		}
		else{
			return false;
		}
			
		while((i + 1) < aTableChilds.length){
			i ++;
			if(aTableChilds[i].getAttribute("_NAME")){
				if(aTableChilds[i].getAttribute("_NAME") == cNI){
					return(i);
				}
			}
			if(aTableChilds[i].getAttribute("id") == cNI){
				return(i);
			}
		}
		return false;
	}

	// Scan the table and fine out elements which can be map to XML in the table in first layer.
	//---------------------------------------------
	function GetValidChilds(oTable, level)
	{
		var childs = new Array();
		var cTableChilds = oTable.childNodes;
		var i;
		
		for(i = 0; i < cTableChilds.length; i++)
		{
			if(cTableChilds[i].nodeType == 1)
			{
				if(cTableChilds[i].getAttribute("_CONTAINER") != null)
				{	
					childs.push(cTableChilds.item(i));
					cTableChilds.item(i)._DELETED = false;
				}
				else if(cTableChilds.item(i).getAttribute("_REF"))
				{
					childs.push(cTableChilds.item(i));
					deleteArray.push(cTableChilds.item(i));
				}
				else
				{
					var str = _interop_GetLocalName(cTableChilds.item(i));
										
					switch( str )
					{
						case "TEXTAREA":
						case "INPUT" :
						case "SELECT" :												
							childs.push(cTableChilds.item(i));
							break;
						default:
							childs = childs.concat(GetValidChilds(cTableChilds.item(i), level + 1));
							
					}
				}
			}	
		}		
		return childs;
	}

	function disableCheckbox(oTable)
	{
		oSet = fetchArraybyAttribute( oTable, "type", "checkbox" );
		for(var i = 0; i < oSet.length; i++){
			oSet[i].checked = false;
		}
	}
	
	// fixed checked value allow unchecked with N
	function IsChecked( _checkValue )
	{			
		if( _checkValue == "N" )
			return false;		
		else
			return true;		
	}

// Really expand function
//-----------------------------------------
function __doExpandTemplate(oXML, oTable)
{
	//alert(oTable.id);
	var aTableChilds = GetValidChilds(oTable, 0);
	disableCheckbox(oTable);
	
	var retrunFlag = true;
	var oTemp, oInsertPoint;

	/* ==== find out Childs of XML and the Table ==== */		
	if(_hasChildElement(oXML))
	{
		var XMLChilds = oXML.childNodes;
	}
	else
	{
		var XMLChilds = new Array(oXML);
	}

	for(var i = 0; i < XMLChilds.length; i++)
	{
		var currentXMLTarget = XMLChilds[i];
		
		var tablePosition = GetNodeByRCNI(aTableChilds, _interop_GetLocalName(currentXMLTarget));
					
		if( typeof(tablePosition) != "boolean")
		{
			if(aTableChilds[tablePosition].getAttribute("_REF"))
			{ // reference

				oTemp = __d( oPROTOTYPE, "_TEMPLATE", aTableChilds[tablePosition].getAttribute("_REF") ).cloneNode(true);
				aTableChilds[tablePosition].parentNode.appendChild(oTemp);
				retrunFlag = retrunFlag && __doExpandTemplate(currentXMLTarget ,oTemp); //recursion
			}
			else if(aTableChilds[tablePosition].getAttribute("_CONTAINER"))
			{ // Container
				
				// push into Delete Array if it's not there
				if(aTableChilds[tablePosition]._DELETED == false)
				{
					deleteArray.push(aTableChilds[tablePosition]); 
					aTableChilds[tablePosition]._DELETED == true;
				}
				
				oTemp = aTableChilds[tablePosition].cloneNode(true);

				// if this the container inside the table, append it as sibling
				oInsertPoint = aTableChilds[tablePosition]; // Find the last position.
				if(oInsertPoint.nextSibling)
				{
					if(oInsertPoint.nextSibling.nodeType == 1)
					{
						while (oInsertPoint.nextSibling.getAttribute("_CONTAINER") == oInsertPoint.getAttribute("_CONTAINER"))
						{
							oInsertPoint = oInsertPoint.nextSibling;
							if(oInsertPoint.nextSibling == null )
							{//no sibling
								break;
							}
						}
					}
				}
				
				InsertAfter(oInsertPoint, oTemp)
				retrunFlag = retrunFlag && __doExpandTemplate(currentXMLTarget ,oTemp); //recursion
			}				
			else
			{ // an leaf node in HTML
				
				//Check for leaf in HTML match a leaf in XML
				if(GetChildElements(currentXMLTarget).length != 0)
				{
					debug("structure error, XML is:" + _interop_GetLocalName(currentXMLTarget));						
					debug("_core_ExpandTemplate, structure Error: Leaf in HTML but Container in XML");
					return false;
				}
				
				oTemp = aTableChilds[tablePosition];					
				
				switch(_interop_GetLocalName(oTemp))
				{
					case "TEXTAREA":
					case "INPUT" :							
						if(oTemp.type == "checkbox")
						{
							while(oTemp.checked)
							{ 
								// find an unchecked box
								tablePosition = GetNextSilbingByNI(aTableChilds, tablePosition);
								if( typeof(tablePosition) == "boolean"){
									// not found.
									// there must be one XML leaf node with the same name is filled, but this one can't be filled.
									// we can break if we want to just ignore this.
									//return false;
									break;// 2005/03/24 max
								}
								oTemp = aTableChilds[ tablePosition ];
								if(oTemp.type != "checkbox"){ 
									// two type with the same name
									//return false;
									break;
								}
							}//end While
															
							// 2005/03/25 max
							//oTemp.checked = IsChecked( _interop_getTextValue(currentXMLTarget) ); // if this is a check box, check it.
							oTemp.checked = true;
							checkboxArray.push(oTemp); // checkbox will be reset after appendChild. we need to mark it and restore its value.
						}
						else if(oTemp.type == "radio")
						{
							while(oTemp.value != _interop_getTextValue(currentXMLTarget))
							{
								//Fine Next
								oTemp.checked = false; // uncheck wrong one
								tablePosition = GetNextSilbingByNI(aTableChilds, tablePosition);
								if(typeof(tablePosition) == "boolean"){
									// not found.
									// there must be one XML leaf node with the same name is filled, but this one can't be filled.
									// we can break if we wan to just ignore this.
									//return false;
									break;
								}
								oTemp = aTableChilds[tablePosition];
								if(oTemp.type != "radio"){ 
									// two type with the same name
									debug("Radio Type Error");
									//return false;
									break;
								}
							}
							
							if(oTemp.value != _interop_getTextValue(currentXMLTarget)){
								return false; // can't find a radio with the value the same as the xml element
							}
							
							oTemp.checked = true;
						}
						else
						{ // other input

							var tmpValue = trim( oTemp.value );
							
							while( tmpValue )
							{
								tablePosition = GetNextSilbingByNI(aTableChilds, tablePosition);								
								if(typeof(tablePosition) == "boolean")
								{
									// not found.
									// there must be one XML leaf node with the same name is filled, but this one can't be filled.
									// we can break if we wan to just ignore this.
									//return false;
									break;
								}

								oTemp = aTableChilds[tablePosition]; 
								tmpValue = trim(oTemp.value);
								
							}//end While
							
							if ( typeof(tablePosition) == "boolean")
								break;
							
							if(_interop_getTextValue(currentXMLTarget) != "")
							{
								oTemp.value = _interop_getTextValue(currentXMLTarget);
								
								// [2003-09-01 bear] [experimental]Dynamically adjust the size of "TEXTAREA"
								if( _interop_GetLocalName(oTemp) == "TEXTAREA" )
								{	
									oTemp.wrap = "off";
									if( oTemp.value.length > 300 ){
										oTemp.rows += 2 ;
									} 
									if( oTemp.value.length > 500 ){	
										oTemp.rows += 2 ;
									}
									if( oTemp.value.length < 700 ){
										oTemp.rows += 2 ;
									}
								}
							}
							else if(aTableChilds[tablePosition].getAttribute("_EMPTY")==1)	// for empty input text, marked with "[[[empty]]]".
							{	
								oTemp.value = "[[[empty]]]";
								emptyArray.push(oTemp);	// add this node to emptyArray, and clear it later.
							}
							

						}// end INPUT
						
					break;
					case "SELECT":							
						while(oTemp._SETED){ // Find a new select tag
							tablePosition = GetNextSilbingByNI(aTableChilds, tablePosition);
							if(typeof(tablePosition) == "boolean"){
									// not found.
									// there must be one XML leaf node with the same name is filled, but this one can't be filled.
									// we can break if we wan to just ignore this.
									//return false;
									break;
							}
																
							oTemp = aTableChilds[tablePosition];
							if(!oTemp){ 
								// not found.
								// there must be one XML leaf node with the same name is filled, but this one can't be filled.
								// we can break if we wan to just ignore this.
								//return false;
								break;
							}
						}																			
						
						if(_interop_GetLocalName(oTemp) != "SELECT"){
						 	return false; //Structure Error
						}
					
						AssignValue( oTemp, _interop_getTextValue(currentXMLTarget) );							
						oTemp.setAttribute("_SETED", true);
						
					break;
				} // end of switch(_interop_GetLocalName(oTemp))
				
			} // end of an leaf node in HTML
		}
		else
		{
		}
	}
	
	return(retrunFlag);
} // end of __doExpandTemplate
	
function _SelectedText( inSelection )
{

	if( inSelection.options.length > 0 ) {
		return( inSelection.options[ inSelection.selectedIndex ].text );
	} else {
		return( "" );
	}
}

function __regexCheck(oCurrentNode){
}


/*
	function __regexCheck(oCurrentNode){
	// __regexCheck : 日期檢查，格式為(YYYY-MM-DD,YYYY-MM-DD)，日期應介於其中。
	// 資料格式檢查用 : 每個 Field 增加兩個 optional 的 attribute (_REGEX, _REGEXDISCRIPTION)
	// _REGEX --> 指定格式的 Regular Expression
	// _REGEXDISCRIPTION --> 若發生錯誤時的訊息
	// __regexCheckVerbose --> 全域變數, ture: 錯誤時自動 Show 出訊息, false: 不會自動 alert.
	
		var ErrorMessage;


		if ( oCurrentNode.getAttribute("_NAME") != null){
			var field = oCurrentNode.getAttribute("_NAME")
		}
		else if(oCurrentNode.id != ""){
			var field = oCurrentNode.id;
		}
			
		if ( oCurrentNode.getAttribute("_REGEX") != null){
			var cValue = oCurrentNode.value;
			var cRegEx = oCurrentNode.getAttribute("_REGEX");
			var re = new RegExp(cRegEx);
			var arr = re.exec(cValue);
			
			// 輸入正確
			if(arr != null)
				if(arr[0] == cValue) return("");

			//輸入錯誤			
			//var ErrorMessage = "資料輸入錯誤\n欄位: '" + field + "'\n\n 說明:\n";
							
			if ( oCurrentNode.getAttribute("_REGEXDISCRIPTION") != null){
				ErrorMessage = ErrorMessage + oCurrentNode.getAttribute("_REGEXDISCRIPTION");
			}
			if(__regexCheckVerbose) alert(ErrorMessage);
			return("field: " + field);
		}
		else if(oCurrentNode.getAttribute("_regexCheck") != null){
			var cValue = oCurrentNode.value;
			var cRegEx = oCurrentNode.getAttribute("_regexCheck");
			var cStartDate = cRegEx.split(",")[0];
			var oStartDate = Str2YMD(cStartDate);
			var oEndDate = Str2YMD(cRegEx.split(",")[1]);
			var oValueDate = Str2YMD(cValue);
			
			// 輸入格式錯誤
			if ( YMD2Str(oValueDate) != cValue){
				if(__regexCheckVerbose) {
					//var ErrorMessage = "資料輸入錯誤(格式為 YYYY-MM-DD)\n欄位: '" + field + "'\n\n 說明:\n";
					ErrorMessage += oCurrentNode.getAttribute("_REGEXDISCRIPTION");
					alert(ErrorMessage);
				}
				return("field: " + field);
			}
			
			// 輸入範圍錯誤
			if ( oStartDate.getTime() > oValueDate.getTime() || oEndDate.getTime < oValueDate.getTime() ){
				if(__regexCheckVerbose) {
					//var ErrorMessage = "資料輸入錯誤(範圍為" + YMD2Str(oStartDate) + "到" + YMD2Str(oEndDate) + ")\n欄位: '" + field + "'\n\n 說明:\n";
					ErrorMessage += oCurrentNode.getAttribute("_REGEXDISCRIPTION");
					alert(ErrorMessage);
				}
				return("field: " + field);
			}
		}
		return("");
	}
	*/
	
	function Str2YMD(cDate){ // from YYYY-MM-DD to date object
		var ss = cDate.split("-");
		return(new Date(ss[0], ss[1] - 1, ss[2]));
	}
	
	function YMD2Str(oDate){
		var cMonth = oDate.getMonth() + 1;
		var cDate = oDate.getDate();
		
		if ( cMonth < 10 ) cMonth = "0" + cMonth;
		if ( cDate < 10) cDate = "0" + cDate;
		
		return(oDate.getFullYear() + "-" + cMonth + "-" + cDate);
	}

function debug( cMessage ){
	//  alert( cMessage );
}
