// wForms - a javascript extension to web forms.
// v0.99.1 - May 26 2005
// Copyright (c) 2005 Cédric Savarese <pro@4213miles.com>
// This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
// Other Contributors: Michael Duff (fullmoondesigns.net)

// Change Log: see http://formassembly.com/blog/wforms-a-javascript-extension-to-web-forms/

// Known Problems:
// 		Safari 1.x:  	Validation Disabled. No way of knowing if a field is visible or not (cf. checkVisibility())
// 		IE 5.2 Mac: 	Validation Disabled. currentStyle.display returns an empty string in checkVisibility() causing non-visible fields to get validated. 
//						Buggy Rendering of the Repeat behavior 
//						Counter Field of Repeat Behavior not submitted (probably setting the name attribute didn't work)
// 		IE 5.0 PC:		Repeat behavior doesn't work. All field are created as TEXT input ? To be checked again.


function wFORMS() { // wFORMS Class Constructor

	var wu = new wUTILITY();
	var self = this;

	// CSS class name definitions. 
	this.classNamePrefix_switch			= "switch";
	this.className_switchIsOn 			= "swtchIsOn"; // used to keep track of the switch state on buttons and links (where the checked attribute is not available) (added in v0.97)
	this.classNamePrefix_offState		= "offstate";
	this.classNamePrefix_onState		= "onstate";
	this.className_repeat 			= "repeat";
	this.className_delete 			= "removeable";
	this.className_required 		= "required";
	this.className_validationError_msg 	= "errMsg";		 
	this.className_validationError_fld	= "errFld";  
	this.classNamePrefix_validation 	= "validate";
	this.className_duplicateLink 		= "duplicateLink";
	this.className_removeLink 		= "removeLink";
	this.className_activeFieldHint 		= "field-hint";
	this.className_inactiveFieldHint 	= "field-hint-inactive";
	// id attribute suffixes
	this.idSuffix_fieldHint 			= "-H";
	this.idSuffix_fieldLabel			= "-L";
	this.idSuffix_fieldError			= "-E";
	this.idSuffix_repeatCounter			= "-RC";
	this.idSuffix_duplicateLink			= "-wfDL";		// not fully implemented yet

	// Behavior configuration options
	this.preserveRadioName				= true; 		// if true, Repeat behavior will preserve name attributes for radio input. 
	this.switchScopeRootTag				= "FORM";		// limit the scope of the switch behavior. You may use 'BODY'.
	
	// Form validation function name. May be overidden if you need to run your own validation routine (but make sure to run formValidation() in it).
	this.functionName_formValidation = "this.formValidation";
	this.showAlertOnError = true; // set to false to not show the alert when a validation error occurs.
	this.preventSubmissionOnEnter = false; // prevent submission when pressing the 'enter' key. Set to true if pagination behavior is used.
	
	
	// Other Messages
	this.arrMsg = new Array();
	this.arrMsg[0] = "Add a row"; 	// repeat link
	this.arrMsg[1] = "Repeats the preceding field or field group." // title attribute on the repeat link 
	this.arrMsg[2] = "Remove"; 		// remove link
	this.arrMsg[3] = "Removes the preceding field or field group." // title attribute on the remove link
	this.arrMsg[4] = "Next Page";
	this.arrMsg[5] = "Previous Page";	
	this.utilities = wu;	
	

	// =======================================================================================
	// Switch Behavior Methods
	// =======================================================================================

	// Privileged Instance Methods
	//----------------------------
	this.refreshAllStates = function(fId) {
		var f=document.getElementById(fId);
		if(!f) return;
		// loop through the fields
		var x = wu.getElements(f);
        
        wu.debug('refreshAllState(fId): ' + x.length + ' items to refresh\n');
        //var skipped = 0;
        
		for (var i=0;i<x.length;i++) {
            // don't check Country_Code and children
            if( x[i].name == 'Country_Code' || (
                x[i].tagName.toUpperCase()=='OPTION' && x[i].parentNode.name == 'Country_Code')) {
                //wu.debug('skipping item '+i);
                //skipped++;
                continue;
            }
			// add switch/state behavior
			if (x[i].tagName.toUpperCase() == "SELECT" && wu.isEventHandled(x[i],'change') ) {				
				this.refreshState(null,x[i]);
			}
			if (x[i].className && x[i].className.indexOf(this.classNamePrefix_switch) != -1) {			
				switch(x[i].tagName.toUpperCase()) {
					case "OPTION":
						break;
					default:
						this.refreshState(null,x[i]);
						break;
				}
			}
		}
        //wu.debug('' + skipped + ' items skipped');
	}
	
    //var nbswitch;
    
	this.refreshState = function(e) {
		if(!e && arguments.length==2)
			var srcE = arguments[1];
		else
			var srcE = wu.getSrcElement(e);
	
        //nbswitch = 0;
        //wu.debug(' > refreshState(' + srcE.id + ')');
		switch(srcE.tagName.toUpperCase()) {
			case "SELECT":
				
				var selectedStateClass="";
				var localScope = switchScope(srcE);
				for(var i=0;i<srcE.options.length;i++) {
					if(srcE.options[i].className.indexOf(self.classNamePrefix_switch) != -1 ) {
						var s = srcE.options[i].className;
						s = s.substr(s.indexOf(self.classNamePrefix_switch)).split(" ")[0].substr(self.classNamePrefix_switch.length);
						var offStateClass = self.classNamePrefix_offState + s;
						var onStateClass = self.classNamePrefix_onState + s;				
						if(i==srcE.selectedIndex) {					
							switchState(localScope, offStateClass, onStateClass);
							selectedStateClass = onStateClass; // prevents further switching off 
						}
						else if(onStateClass != selectedStateClass) {
							switchState(localScope, onStateClass, offStateClass);
						}
					}			
				}
				break;
			case "INPUT":	
				if(srcE.type.toLowerCase() == 'radio') {
					// Go through the radio group.
					for(var i=0;i <srcE.form[srcE.name].length;i++) { 
						var r = srcE.form[srcE.name][i];
						if(r.className && r.className.indexOf(self.classNamePrefix_switch)!=-1) {
							var s = r.className;
							s = s.substr(s.indexOf(self.classNamePrefix_switch)).split(" ")[0].substr(self.classNamePrefix_switch.length);
							var offStateClass = self.classNamePrefix_offState + s;
							var onStateClass = self.classNamePrefix_onState + s;	

							if(r.checked) 
								switchState(switchScope(r), offStateClass, onStateClass);
							else {								
								switchState(switchScope(r), onStateClass, offStateClass); 
							}						
						}
					}
				} else {
					var s = srcE.className;
					s = s.substr(s.indexOf(self.classNamePrefix_switch)).split(" ")[0].substr(self.classNamePrefix_switch.length);
					var offStateClass = self.classNamePrefix_offState + s;
					var onStateClass = self.classNamePrefix_onState + s;	

					if(srcE.checked || 
					  (srcE.type.toLowerCase() == 'button' && srcE != arguments[1] && srcE.className.indexOf(self.className_switchIsOn) == -1 )) { // && !srcE.defaultChecked
						switchState(switchScope(srcE), offStateClass, onStateClass);
						if(srcE.type.toLowerCase() == 'button') {
							srcE.className += " " + self.className_switchIsOn;
						}
					}
					else {							
						switchState(switchScope(srcE), onStateClass, offStateClass); 
						if(srcE.type.toLowerCase() == 'button' && srcE != arguments[1]) {
							srcE.className = srcE.className.replace(self.className_switchIsOn,"");
						}
					}
				}
				break;
			default: 
				var s = srcE.className;
				s = s.substr(s.indexOf(self.classNamePrefix_switch)).split(" ")[0].substr(self.classNamePrefix_switch.length);
				var offStateClass = self.classNamePrefix_offState + s;
				var onStateClass = self.classNamePrefix_onState + s;	
				if(srcE != arguments[1] && srcE.className.indexOf(self.className_switchIsOn) == -1) { 
					switchState(switchScope(srcE), offStateClass, onStateClass);
					srcE.className += " " + self.className_switchIsOn;
				}
				else if(srcE != arguments[1]) {
					switchState(switchScope(srcE), onStateClass, offStateClass); 
					srcE.className = srcE.className.replace(self.className_switchIsOn,"");
				}
				break;
		}	
        //wu.debug(' < switchState calls: ' + nbswitch);
	}	
	
	// Switch Behavior Private Methods
	// -------------------------------

	// The switch scope limits the element tree on which the switch can operate.
	// Because of interference issue, a SWITCH contained in a REPEATed block
	// should not be allowed to operate outside of it.
	function switchScope(n) {
		while(n) {
            
			 if (n.className && ( (' '+n.className+' ').indexOf(' pane ') != -1 )) 
                return n;
        
			 if (n.className && ( (' '+n.className+' ').indexOf(' '+self.className_repeat+' ') != -1 || (' '+n.className+' ').indexOf(' '+self.className_delete+' ') != -1)) 
				return n;
			 if (n.tagName.toUpperCase() == self.switchScopeRootTag)
				return n;
			 n = n.parentNode;
		}
		return null; // should not happen. A form should exists.
	}
	
	// Recursive loop within the scope to switch classes
	function switchState(n, oldStateClass, newStateClass) {		
        //nbswitch++;
		if(n.nodeType != 1) return;
        // don't check Country_Code and children
        if( n.name == 'Country_Code' || (
            n.tagName.toUpperCase()=='OPTION' && n.parentNode.name == 'Country_Code')) {
            return;
        }
        //wu.debug('switchState(' + n.id?n.id:n.name + ')');
		if(n.className && n.className.indexOf(oldStateClass) != -1) {  		
			n.className = n.className.replace(oldStateClass, newStateClass);
			// FAT support
			// n.id not set.
			// if(Fat && n.id) Fat.fade_element(n.id, 10, 600, "#FFFFCC", "#FFFFFF");	
		}
		for (var i=0;i<n.childNodes.length;i++){ 
            if(n.childNodes[i].nodeType != 1) continue;
			switchState(n.childNodes[i], oldStateClass, newStateClass);
        }
	}

	// =======================================================================================
	// Repeat/Remove Behavior Methods
	// =======================================================================================

	// removed (dib)
	// -------------------
	// Priviledged Methods
	// -------------------
	this.duplicateFieldGroup = function(e) {
		var srcE = wu.getSrcElement(e);
		// Get Element to duplicate.
		var sourceNode = srcE.parentNode;
		while (sourceNode && (!sourceNode.className || (' '+sourceNode.className+' ').indexOf(' '+self.className_repeat+' ') == -1)) {
			sourceNode = sourceNode.parentNode;
		}	
		if (sourceNode && sourceNode.className.indexOf(self.className_repeat) != -1) {
			//alert('repeat behavior...');
			// Extract row counter information
			counterField = document.getElementById(sourceNode.id + self.idSuffix_repeatCounter);
			if(!counterField) {
				alert('no counter field!');
				return; // should not happen.
			}
			var rowCount = parseInt(counterField.value) + 1;
			// Prepare id suffix
			var suffix = "-" + rowCount.toString()
			// duplicate node tree 
			var dupTree = replicateTree(sourceNode, null, suffix);  //  sourceNode.cloneNode(true); 
			// find insert point in DOM tree (after existing repeated element)
			var insertNode = sourceNode.nextSibling;
			while(insertNode && insertNode.className && insertNode.className.indexOf(self.className_delete) != -1) {
				insertNode = insertNode.nextSibling;
			}
					
			sourceNode.parentNode.insertBefore(dupTree,insertNode);	 // Buggy rendering in IE5/Mac
			// if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1)			
			//
			
			// the copy is not duplicable, it's removeable
			dupTree.className = sourceNode.className.replace(self.className_repeat,self.className_delete);
			// Save new row count 			
			document.getElementById(sourceNode.id + self.idSuffix_repeatCounter).value = rowCount;
			// re-add behaviors
			if(!dupTree.id) dupTree.id = wu.randomId() + suffix;  //  createAttribute()
			wu.debug('Duplicated tree id : '+dupTree.id);
			self.addBehaviors(dupTree.id);
			
			// FAT support
			if(typeof Fat != 'undefined' && Fat && dupTree.id) Fat.fade_element(dupTree.id, 10, 600, "#FFFFCC", "#FFFFFF");	

		}
		return wu.XBrowserPreventEventDefault(e);
	}
	this.removeFieldGroup = function(e) {
		var srcE = wu.getSrcElement(e);	// Get Element to remove.
		var delNode = srcE.parentNode;

		while (delNode && (' '+delNode.className+' ').indexOf(' '+self.className_delete+' ') == -1) {
			delNode = delNode.parentNode;
		}
		delNode.parentNode.removeChild(delNode);
		return wu.XBrowserPreventEventDefault(e);
	}

	// Repeat Behavior Private Methods
	// -------------------------------
	function removeRepeatCountSuffix(str) {
		return str.replace(/-\d$/,'');
	}
	
	function replicateTree(srcNode,dupParentNode, idSuffix) {
		switch(srcNode.nodeType) {
			case 1:	// ELEMENT-NODE
				if(srcNode.className.indexOf(self.className_duplicateLink) != -1 ||
					srcNode.className.indexOf(self.className_removeLink) != -1  ) 							
					return null; // Exclude the 'duplicate/remove' links
				if(srcNode.className.indexOf(self.className_delete) != -1) { 							
					return null; // Exclude duplicated elements of a nested repeat group
				}				 
				if(srcNode.className.indexOf(self.className_repeat) != -1 && dupParentNode!=null) { 
					// Match nested repeat group only
					idSuffix = idSuffix.replace('-','__');
				}
				   
				if(document.all && !window.opera) { 
					// IE Specific : see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
					var tagHtml = srcNode.tagName;
					
					if(srcNode.name) 					
						if (srcNode.tagName.toUpperCase()=="INPUT" && srcNode.type.toLowerCase()=="radio" && self.preserveRadioName)
							tagHtml += " NAME='" + srcNode.name + "' ";
						else
							tagHtml += " NAME='" + removeRepeatCountSuffix(srcNode.name) + idSuffix + "' ";
					if(srcNode.type) {
						tagHtml += " TYPE='" + srcNode.type + "' ";
					}
					if(srcNode.selected) 
						tagHtml += " SELECTED='SELECTED' ";
					if(srcNode.checked)
						tagHtml += " CHECKED='CHECKED' ";

					if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1) // IE5 Mac
						var newNode = document.createElement(tagHtml);
					else
						var newNode = document.createElement("<" + tagHtml + "></"+ srcNode.tagName + ">"); 
					try { newNode.type = srcNode.type; } catch(e) {}; // nail it down for IE5 ?, breaks in IE6
 					
				}
				else
					var newNode = document.createElement(srcNode.tagName); 
	
				// get attributes										
				for(var i=0; i< srcNode.attributes.length; i++) {
	
					if(	srcNode.attributes[i].specified || // in IE, the attributes array contains all attributes in the DTD
						srcNode.attributes[i].nodeName.toLowerCase() == 'value' ) { // attr.specified buggy in IE?  
	
						if(	srcNode.attributes[i].nodeName.toLowerCase() == "id" || 
							srcNode.attributes[i].nodeName.toLowerCase() == "name" ||
							srcNode.attributes[i].nodeName.toLowerCase() == "for") {
														
							if(srcNode.attributes[i].nodeValue.indexOf(self.idSuffix_fieldHint) != -1)  {
								//leave the field hint suffix at the end of the id.
								var value = srcNode.attributes[i].nodeValue;
								value= removeRepeatCountSuffix(value.substr(0,value.indexOf(self.idSuffix_fieldHint))) + idSuffix + self.idSuffix_fieldHint;
							}
							else {
								if (srcNode.tagName.toUpperCase()=="INPUT" && srcNode.getAttribute('type',false).toLowerCase()=="radio" &&
									srcNode.attributes[i].nodeName.toLowerCase() == "name" && self.preserveRadioName) {
									var value = srcNode.attributes[i].nodeValue;						
								}
								else {
									// var value = removeRepeatCountSuffix(srcNode.attributes[i].nodeValue) + idSuffix;
									var value = srcNode.attributes[i].nodeValue + idSuffix;
								}
							}
						} else {
							// Do not copy the value attribute for text/password/file input
							if(srcNode.attributes[i].nodeName.toLowerCase() == "value" &&
							 	srcNode.tagName.toUpperCase()=='INPUT' &&  
								  (srcNode.type.toLowerCase() == 'text' || srcNode.type.toLowerCase() == 'password' || srcNode.type.toLowerCase() == 'file')) 
								var value='';   
							else
								var value = srcNode.attributes[i].nodeValue;
						}
						switch(srcNode.attributes[i].nodeName.toLowerCase()) {
							case "class":
								newNode.className = value; 
								break;
							case "style": // inline style attribute (fix for IE)
								if(srcNode.style && srcNode.style.cssText) newNode.style.cssText = srcNode.style.cssText; 
								break;								
							default:
								newNode.setAttribute(srcNode.attributes[i].name, value, 0);//setAttribute(newNode, srcNode.attributes[i].name, value);
						}
					}
				}				
				break;
			case 3: // TEXT-NODE (do not copy value of textareas)
				if(srcNode.parentNode.tagName.toUpperCase() != 'TEXTAREA')
					var newNode = document.createTextNode(srcNode.data); 
				break;
		}
		if(dupParentNode && newNode) dupParentNode.appendChild(newNode);
		for(var i=0; i<srcNode.childNodes.length;i++) {
			replicateTree(srcNode.childNodes[i],newNode,idSuffix);
		}
		return newNode;
	}
    
	// =======================================================================================
	// Field Hint Behavior Methods
	// =======================================================================================

	this.activateFieldHint = function(e) {
		var srcE = wu.getSrcElement(e);
		var fh = document.getElementById(srcE.id +  self.idSuffix_fieldHint);
		if(!fh && srcE.tagName.toUpperCase()=='INPUT' && 
			(srcE.type.toLowerCase() == 'radio' || srcE.type.toLowerCase() == 'checkbox' )) {
			s = srcE.name;			
			if (s.charAt(s.length-2)=='[' && s.charAt(s.length-1)==']') {
				s = s.substr(0,s.length -2);
			}
			fh = document.getElementById(s + self.idSuffix_fieldHint);
		}
		/*
		if(!fh && srcE.tagName.toUpperCase()=='INPUT' && srcE.type.toLowerCase() == 'checkbox') {
			name = srcE.name.substr(0,srcE.name.length-2);
			fh = document.getElementById(name + self.idSuffix_fieldHint);
		}*/	
		if(fh) fh.className = fh.className.replace(self.className_inactiveFieldHint, self.className_activeFieldHint);
	}
	this.desactivateFieldHint = function(e) {
		var srcE = wu.getSrcElement(e);
		var fh = document.getElementById(srcE.id +  self.idSuffix_fieldHint);
		if(!fh && srcE.tagName.toUpperCase()=='INPUT' && 
			(srcE.type.toLowerCase() == 'radio' || srcE.type.toLowerCase() == 'checkbox' )) {
			s = srcE.name;			
			if (s.charAt(s.length-2)=='[' && s.charAt(s.length-1)==']') {
				s = s.substr(0,s.length -2);
			}
			fh = document.getElementById(s + self.idSuffix_fieldHint);
		}
		if(fh) fh.className = fh.className.replace(self.className_activeFieldHint,self.className_inactiveFieldHint);
	}
	
	
	// =======================================================================================
	// Multi-page Forms Management
	// =======================================================================================

	// removed (dib)
    
	// =======================================================================================
	// FORM VALIDATION 
	// =======================================================================================
	
	// removed (dib)

}

//------------------------------------------------------------------------------------------------------------------------
// WFORMS Public Methods
//------------------------------------------------------------------------------------------------------------------------
wFORMS.prototype.onLoadHandler = function() {		
	for (var i=0;i<document.forms.length;i++) {
		if(!document.forms[i].id) document.forms[i].id = this.utilities.randomId();
		this.addBehaviors(document.forms[i].id);
		//alert('behaviors added to form ' + document.forms[i].id);
	}
}
wFORMS.prototype.addBehaviors = function (fId) {
	var f=document.getElementById(fId);
	if(!f) return;

	var thisForm; 				// Pointer to keep track of the current form being processed.
	var wu = this.utilities;	// Utiltiy class instance
	wu.resetEventList();
	
	// loop through the fields
	var x = wu.getElements(f);

    //wu.debug('browsing the form elements: ' + x.length);

    //var skipped = 0;
    
	for (var i=0;i<x.length;i++) {

		// add form validation behavior
        
		if(x[i].tagName.toUpperCase()=="FORM") {			
			//wu.XBrowserAddHandler(x[i],'submit',eval(this.functionName_formValidation));
			thisForm = x[i];	// Pointer to keep track of the current form being processed.
		}
        
		// add fieldhint behavior
		var fh = document.getElementById(x[i].id + this.idSuffix_fieldHint);			
		if(!fh && x[i].tagName.toUpperCase()=='INPUT' && 
			(x[i].type.toLowerCase() == 'radio' || x[i].type.toLowerCase() == 'checkbox')) {
			var s = x[i].name;
			if (s.charAt(s.length-2)=='[' && s.charAt(s.length-1)==']'){
				s = s.substr(0,s.length -2);
			}
			fh = document.getElementById(s + this.idSuffix_fieldHint);
		}		
		/*
		if(!fh && x[i].tagName.toUpperCase()=='INPUT' && x[i].type.toLowerCase() == 'checkbox') {
			s = x[i].name;
			name = s.substr(0,s.length -2);
			fh = document.getElementById(name + this.idSuffix_fieldHint);
		}*/		
		if(fh) {		
			wu.XBrowserAddHandler(x[i],'focus',this.activateFieldHint);
			wu.XBrowserAddHandler(x[i],'blur',this.desactivateFieldHint);			
		}
		// add switch/state behavior
		if (x[i].className && x[i].className.indexOf(this.classNamePrefix_switch) != -1) {
			
			switch(x[i].tagName.toUpperCase()) {
				case "OPTION":
					var sel = x[i].parentNode;	// Get to the SELECT
					if(sel.tagName.toUpperCase() == "OPTGROUP") sel = sel.parentNode; // try again.
					if(!wu.isEventHandled(sel,'change')) {
						wu.XBrowserAddHandler(sel,'change',this.refreshState);						
				   	}
					break;
				case "INPUT":
					if(x[i].type && x[i].type.toLowerCase() == 'radio') {
						// Add the onclick event on radio inputs of the same group
						if(!thisForm) thisForm = x[i].form;	
						for (var j=0;j<thisForm[x[i].name].length;j++) {
							if(thisForm[x[i].name][j].type == 'radio') // prevents conflicts with elements with an id = name of radio group
								wu.XBrowserAddHandler(thisForm[x[i].name][j],'click',this.refreshState);
						}
					} else {
						wu.XBrowserAddHandler(x[i],'click',this.refreshState);
					}
					break;
				default:					
					wu.XBrowserAddHandler(x[i],'click',this.refreshState);
					break;
			}
		}
    //}
		// add repeat behavior
		//if (x[i].className && (' '+x[i].className+' ').indexOf(' '+this.className_repeat+' ') != -1) {
		if (x[i].className && x[i].className.indexOf(this.className_repeat) != -1) {
			// this element to be duplicated.
			//wu.debug('adding repeat on ' + x[i].id);
			//alert('adding repeat on ' + x[i].id);
			var actionNode = null;
			if(x[i].id) actionNode = document.getElementById(x[i].id + this.idSuffix_duplicateLink);
			if (!actionNode) {				
				// add duplicate action
				actionNode = document.createElement("a"); 
				var textNode = document.createTextNode(this.arrMsg[0]);
				actionNode.setAttribute('href',"#");	
				actionNode.className = this.className_duplicateLink;			
				actionNode.setAttribute('title', this.arrMsg[1]);	
				if(x[i].tagName.toUpperCase()=="TR") {
					// find the last TD
					var n = x[i].lastChild;	
					while(n && n.nodeType != 1)  
						n = n.previousSibling;
					if(n && n.nodeType == 1) 
						n.appendChild(actionNode);
					// Else Couldn't find the TD. Table row malformed ?
				} else
					x[i].appendChild(actionNode);
				actionNode.appendChild(textNode); 
			}
			// Add hidden counter field if necessary
			var counterField = document.getElementById(x[i].id + this.idSuffix_repeatCounter);
			if (!counterField) {
				if(document.all && !window.opera) { // IE Specific :-(
					// see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
					var counterFieldId = x[i].id + this.idSuffix_repeatCounter;
					if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1) // IE5 Mac
						counterField = document.createElement("INPUT NAME=\"" + counterFieldId + "\"");
					else
						counterField = document.createElement("<INPUT NAME=\"" + counterFieldId + "\"></INPUT>"); 					
					counterField.type='hidden';
					counterField.id = counterFieldId; 
					counterField.value = "1";
				}
				else {
					counterField = document.createElement("INPUT"); 
					counterField.setAttribute('type','hidden'); // hidden
					counterField.setAttribute('value','1');
					counterField.setAttribute('name', x[i].id + this.idSuffix_repeatCounter);
					counterField.setAttribute('id', x[i].id + this.idSuffix_repeatCounter); 
				}
				if(!thisForm) {
					thisForm = x[i].parentNode;
					while(thisForm && thisForm.tagName.toUpperCase() != "FORM")
						thisForm = thisForm.parentNode;
				}
				thisForm.appendChild(counterField);
			}
			// Add event handler			
			wu.XBrowserAddHandler(actionNode,'click',this.duplicateFieldGroup);			
		}/* else {
			alert('no repeat for ' + x[i].id);
		}*/
		
		// add remove behavior
		if (x[i].className && (' '+x[i].className+' ').indexOf(' '+this.className_delete+' ') != -1) {
			wu.debug('adding remove on ' + x[i].id);
			// this element can be removed
			// add remove action
			var actionNode = document.createElement("a"); 
			var textNode = document.createTextNode(this.arrMsg[2]);
			actionNode.setAttribute('href',"#");	
			actionNode.className = this.className_removeLink;
			actionNode.setAttribute('title',this.arrMsg[3]);	
			if(x[i].tagName.toUpperCase()=="TR") {
				// find the last TD
				var n = x[i].lastChild;	
				while(n && n.nodeType != 1)  
					n = n.previousSibling;
				if(n && n.nodeType == 1) 
					n.appendChild(actionNode);
				// Else Couldn't find the TD. Table row malformed ?
			} else
				x[i].appendChild(actionNode);
			actionNode.appendChild(textNode); 			
			wu.XBrowserAddHandler(actionNode,'click',this.removeFieldGroup);			
		}	
	}
     //wu.debug(skipped + ' items skipped');
	 this.refreshAllStates(fId);
}


// *************************************************************************************************************
// UTILITY CLASS
// *************************************************************************************************************
function wUTILITY() {
	// Event Handler utility list
	this.handlerList = new Array(); 
}

// Cross-Browser event handler management.
// adapted from Andy Smith's (http://weblogs.asp.net/asmith/archive/2003/10/06/30744.aspx)
wUTILITY.prototype.XBrowserAddHandler = function (target,eventName,handlerName) {
	if(!target) return;
	if (target.addEventListener) { 
		target.addEventListener(eventName, function(e){eval(handlerName)(e);}, false);
	} else if (target.attachEvent) { 
		target.attachEvent("on" + eventName, function(e){eval(handlerName)(e);});
		} else { 
		// THIS CODE NOT TESTED 
		var originalHandler = target["on" + eventName]; 
		if (originalHandler) { 
		  target["on" + eventName] = function(e){originalHandler(e);eval(handlerName)(e);}; 
		} else { 
		  target["on" + eventName] = eval(handlerName); 
		} 
	} 
	// Keep track of added handlers.
	var l = this.handlerList.length;
	this.handlerList[l] = new Array(2);
	this.handlerList[l][0] = target.id;  
	this.handlerList[l][1] = eventName;  	
	this.debug("Handler added :" + target.id + ' ' + eventName);
}
// 
wUTILITY.prototype.isEventHandled = function(n, type) {	
	for(var i=0; i < this.handlerList.length; i++) {
		if(this.handlerList[i][0]==n.id && this.handlerList[i][1]==type)
			return true;
	}
	return false;
}
wUTILITY.prototype.resetEventList = function() {
	this.handlerList = new Array(); 
}

// Activating an Alternate Stylesheet (thx to: http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=27)
// Use this to activate a CSS Stylesheet that shouldn't be used if javascript is turned off.
// The stylesheet rel attribute should be 'alternate stylesheet'. The title attribute should be set.
wUTILITY.prototype.activateStylesheet = function(sheetref) {
	if(document.getElementsByTagName) {
		var ss=document.getElementsByTagName('link');
	} else if (document.styleSheets) {
		var ss = document.styleSheets;
	}
	for(var i=0;ss[i];i++ ) {
		if(ss[i].href.indexOf(sheetref) != -1) {
			ss[i].disabled = true;
			ss[i].disabled = false;			
		}
	}
}
// Generates a random ID
wUTILITY.prototype.randomId = function () {
	var rId = "";
	for (var i=0; i<6;i++)
		rId += String.fromCharCode(97 + Math.floor((Math.random()*24)))
	return rId;
}
// returns all child elements of a node.
wUTILITY.prototype.getElements = function(n, list) {
	if(!list) list = new Array();
	if(n.nodeType==1) {
		list[list.length]= n;
		for(var i=0; i<n.childNodes.length;i++) 
			this.getElements(n.childNodes[i], list);
		return list;
	}
}
// Returns the event's source element 
wUTILITY.prototype.getSrcElement = function(e) {	
	if(!e) 
		e = window.event;	
	if(e.target)
		var srcE = e.target;
	else
		var srcE = e.srcElement;
	if(srcE.nodeType == 3) srcE = srcE.parentNode; // safari weirdness		
	if(srcE.tagName.toUpperCase()=='LABEL') { 
		// when clicking a label, firefox fires the input onclick event
		// but the label remains the source of the event. In Opera and IE 
		// the source of the event is the input element. Which is the 
		// expected behavior, I suppose.		
		if(srcE.getAttribute('for')) {
			srcE = document.getElementById(srcE.getAttribute('for'));
		}
	}
	return srcE;
}
// Cancel the default execution of an event.
wUTILITY.prototype.XBrowserPreventEventDefault = function(e) {
	if(!e) e = window.event;
	if (e.preventDefault) e.preventDefault();
	else e.returnValue = false;
	return false;
}
wUTILITY.prototype.checkVisibility = function(n) {
	// check if any of the element's ancestors is not visible.
	if(window.getComputedStyle) {
		var isVisible = window.getComputedStyle(n,"").getPropertyValue("display").toLowerCase()!="none";
		isVisible = isVisible && window.getComputedStyle(n,"").getPropertyValue("visibility").toLowerCase()!="hidden";
		// add visiblity!=collapse ?
	}
	else if(n.currentStyle) {		
		if(n.currentStyle.display=='') return false; // effectively disable validation on IE5/Mac.
		var isVisible = n.currentStyle.display.toLowerCase() != "none";
		isVisible = isVisible && n.currentStyle.visibility.toLowerCase() !="hidden";
	}
	else {
		return false; // effectively disable validation for Safari
		// try to focus or select...
		// This code not finalized (doesn't work for Safari).
		try {			
				if(n.focus) alert(n.focus());
				if(n.select) alert(n.select());
			}  
		catch (e) {
				// focus failed. Either not a field, or not visible.
				alert("not a visible field. " + e);
				return false;
			}		
			return true; // focus ok. The field is definitively visible.
	}
	if(!n.parentNode) { return false; } ; // should not happen, unless we checking some removed elements.
	if (n.parentNode.tagName.toUpperCase()=="BODY" || !isVisible)
		return isVisible;
	return this.checkVisibility(n.parentNode);
}
	
wUTILITY.prototype.debug = function(text) { 
//	var debugOutput = document.getElementById('debugOutput');  
//	if(debugOutput) debugOutput.innerHTML = debugOutput.innerHTML+"<br />"+text; 
}

// =============================================================================
// LET's GO
var wf = new wFORMS();
// Attach JS only stylesheet.
wf.utilities.activateStylesheet('style-jsonly.css'); 
// onLoad event handler
//wf.utilities.XBrowserAddHandler(window,'load',function() { wf.onLoadHandler();}  );
// =============================================================================

// setup tabbed panel interface, add behavior to link
var W3CDOM = document.getElementById && document.createElement;
// add onmouseover behavior to required elements
// use /js/rollover2.js

var editors = editors ? editors : new Array;

function onHidePane(paneId,paneObj) {
	if(!W3CDOM || document.all) return;

	for(x=0; x < editors.length;x++) {
		pane = editors[x].pane;
		name = editors[x].name;
		etype = editors[x].type;
	    if(paneId != pane) continue;
		switch(etype){
				
			case 'xinha':
				if(!xinha_editors) continue;
				editor = xinha_editors[name];
				if(editor) {
					editor.deactivateEditor();//geckoUnhide();
				}
				break;

    	}
	}
}

function onShowPane(paneId,paneObj) {
	if(!W3CDOM || document.all) return;

	for(x=0; x < editors.length;x++) {
		pane = editors[x].pane;
		name = editors[x].name;
		etype = editors[x].type;
	    if(paneId != pane) continue;
		switch(etype){
			case 'fck':
				if (!window.FCKeditorAPI) continue;
				var obj = FCKeditorAPI.GetInstance( name );
				if (  obj.EditMode == FCK_EDITMODE_WYSIWYG && obj.SwitchEditMode ){
						// && obj.version <= 2.0fc !!!
					obj.SwitchEditMode() ;
					obj.SwitchEditMode() ;
				}
				break;
				
			case 'xinha':
				if(!xinha_editors) continue;
				editor = xinha_editors[name];
				if(editor) {
					//editor.geckoUnhide();
					editor.activateEditor();
					//editor.focus();
				}else {
					//alert('name found, but no editor:' + name);
				}
				break;

			case 'tiny':
				if (!window.tinyMCE) continue;
				tinyMCE.updateContent(name);
				break;
    	}
	}
}

/*
function onShowPane(paneId) {
    if(!W3CDOM || document.all || !editorName) return;
	
    if(paneId == 'pane0') {
	var obj = FCKeditorAPI.GetInstance( editorName );
	if (  obj.EditMode == FCK_EDITMODE_WYSIWYG && obj.SwitchEditMode ){
		obj.SwitchEditMode() ;
		obj.SwitchEditMode() ;
	//	alert('switched');
	}
    }
}
*/

function pageInit() {
//	setRollOver('intlshow');

	
	 wf.onLoadHandler();

	// init xinha editors
	if (window.xinha_init) {
		xinha_init();
	}
	
    // init tabbed panel
    if (window.setupPanes) {
        if(typeof openTab == 'undefined') openTab = 'tab0';
        else openTab = 'tab'+openTab;
        setupPanes('container1',openTab);
    }
	if(document.loginForm){// && window.loginFormInit) {
		//loginFormInit();
        f=document.loginForm;
        wf.utilities.XBrowserAddHandler(f,'submit', function() { window.checkForm();} );
        
	}
}

addLoadEvent(pageInit);
// vim: set ts=4:


