/* Theme Pack 3.1.1+ DO NOT modify */

/*** Settings ***/

CS.v3.Forms = {
	DefaultOptions: {
		cancelHintOnDone : true,
		disableFormButtonUntilTrue: true
	}
}

/*** Events ***/
CS.v3.Components.validateForms = function(el,options) {new CS.v3.Config.validateForms(el,options)};
CS.v3.Config.validateForms = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options) {
	
		this.forms = $(el).select("form[class*='csForm']",
		"form[class*='csValidate-submit']",
		"form[class*='csValidate-realtime']");
		if (options.bind == 'true') {this.bind()}
	},
	bind: function() {
		var i = this.forms.length;
		while(i--){
			var obj = this.forms[i];
			var controls = obj.getElements();
			// Real-time validatiion
			if (obj.match('.csValidate-realtime')) {
				obj;// was: this.forms[i];
				//Form.getElements(obj).each(function(el) {
				var ar = Form.getElements(obj);
				var ii = ar.length;
				var el;
				while(ii--){
					el = ar[ii];
					new Form.Element.EventObserver(el, function(el,value) {
						if (el.type == 'text'|| el.tagName == 'TEXTAREA') {
							var comparison = this.getCustomAttribute(el,'csFireEvent-');
							if (comparison != null) {
								var comparison = comparison.toString();
								var el = $(comparison);
								new CS.v3.getTextFieldError(el,'realtime');
							} else {
								new CS.v3.getTextFieldError(el,'realtime');
							}
						}
					}.bind(this));
				//}.bind(this));
				}
				
				// Blockers
				Event.observe(obj, 'keyup', function(event) {
					var el = $(Event.element(event));
					if ((event.keyCode != Event.KEY_TAB) && (el.tagName == 'INPUT' || el.tagName == 'TEXTAREA')) { 
						new CS.v3.getBlockers(el,'block',event);
					}
				});
			}
			
			//controls.each(function(control) { 
			var ii = controls.length;
			var control;
			while(ii--){
				control = controls[ii];
				Event.observe(control, 'focus', function(event) {
					var el = $(Event.element(event));
					if (Prototype.Browser.IE){
						var tag=el.tagName;
						var type=el.type;
						var binput = (tag=='INPUT') && (type=='text' || type=='password');
						if(binput || (tag=='TEXTAREA' || tag=='SELECT')){
							el.addClassName('csIeFocus');
						}
						
						if (el.match('input.csToggle')) {
							var attr = new CS.v3.ComponentAttributes(el);
							new CS.v3.ToggleDisplay(el,attr);
						}
					}
					var tr = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
					if (tr) {
						if (tr.match('.csError')) {
							CS.v3.errorFocus.focus(el,event);
						}
					}
				});
				Event.observe(control, 'blur', function(event) {
					var el = $(Event.element(event));
					if (Prototype.Browser.IE){
						var tag=el.tagName;
						var type=el.type;
						var binput = (tag=='INPUT') && (type=='text' || type=='password');
						if(binput || (tag=='TEXTAREA' || tag=='SELECT')){
							el.removeClassName('csIeFocus');
						}
					}
					var tr = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
					if (tr) {
						if (tr.match('.csError')) {
							CS.v3.errorFocus.blur(el,event);
						}
 					}
				});
				Event.observe(control, 'change', function(event) {
					var el = $(Event.element(event));
					if (el.hasClassName('csToggle')) {
						var tag = el.tagName;
						if (tag == 'INPUT') {
							var attr = new CS.v3.ComponentAttributes(el);
							new CS.v3.ToggleDisplay(el,attr);
						} else {
							if (tag == 'SELECT') {
								var idx = el.selectedIndex;
								var ar = el.options;
								var elOption = $(ar[idx]);
								var attr = new CS.v3.ComponentAttributes(elOption);
								new CS.v3.ToggleDisplay(elOption,attr);
							}
						}
					}

				});
				// WebKit only (fixed checkbox focus issue)
				if (Prototype.Browser.WebKit) {
					Event.observe(control, 'click', function(event) {
						var el = $(Event.element(event)); el.focus();
					});
				}
			//});
			}
			// Form Validation (On Submit)
			if (obj.match('.csValidate-submit')) {
			
				// Submit
				Event.observe(obj, 'submit', function(event) {
				
					//event.preventDefault();
					//return;
				
					var form = $(Event.element(event));
					if (form.match('.csExcept')) {return}
					//var fieldset = form.down('fieldset');
					var controls = form.getElements();
					var falseResults = [];
					//controls.each(function(name) {
					var j = controls.length;
					var name;
					var el;
					var value;
					while(j--){
						name = controls[j];
						el = $(name);
						value = $F(el);
						if ((el.type == 'text' || el.tagName == 'TEXTAREA') && !el.match('.csExcept')) {
							var errors0 = new CS.v3.getTextFieldError(el,'submit');
							falseResults.push(errors0.results);
						}
						
						if ((el.type == 'radio' || el.type == 'checkbox') && el.match('.csVal-required')) {
							var errors2 = new CS.v3.getCheckError(el,form);
							falseResults.push(errors2.results);
						}
						
						if (el.tagName == 'SELECT' && el.match('.csVal-required')) {
							var errors3 = new CS.v3.getSelectError(el);
							falseResults.push(errors3.results);
						}
					}
					//}.bind(this));
					
					new CS.v3.ErrorCountBox(form,falseResults);
					
					if (form.match('.csDisabled')) {event.preventDefault();}
				});
				
				
				// click
				Event.observe(obj, 'click', function(event) { 
					var el = $(Event.element(event));
					if (el.match('.csSave')) {
						var form = CS.v3.getParentElementWithClass(el,'.csForm');//el.up('.csForm');
						form.addClassName('csExcept');
					}
				});
				
				Event.observe(obj, 'keydown', function(event) { 
					var el = $(Event.element(event));
					if (el.match('.csSave') && Event.KEY_RETURN) {
						var form = CS.v3.getParentElementWithClass(el,'.csForm');//el.up('.csForm');
						form.addClassName('csExcept');
					}
				});
			}
		}
	},
	log: function(s){
		CS.v3.Logger.log("validateForms:" + s);
	}
});

// Focus
CS.v3.errorFocus = {
	focus : function(el) {
		
		this.row = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
		this.field = CS.v3.down(this.row,'DIV.csFields') || CS.v3.down(this.row,'DIV.csLabel');
		
		if (this.field) {
			
			this.field.addClassName('csFocus');
		}
	},
	blur : function(el) {
		
		this.row = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
		this.field = CS.v3.down(this.row,'DIV.csFields') || CS.v3.down(this.row,'DIV.csLabel');
		
		if (this.field) {
		
			this.field.removeClassName('csFocus');
		}
	}
}


/*** Controls ***/

CS.v3.Control = Class.create(CS.v3.Base.prototype, {
	initialize: function(el) {

		this.value0 = $F(el);
		this.classNames = $w(el.className);
		this.results = [];
		this.msgs = [];
		this.checked = [];
		this.row = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
		this.field = CS.v3.getParentElementWithClass(el,'.csFields');//el.up('.csFields');
	},
	msgDisplay: function(el,c,validation,empty) {
	
		if (empty && validation == 'realtime') {
			
			c.row.removeClassName('csError');
			c.row.removeClassName('csDone');
			return;
		}
	
		if (c.results.all()) { // all true
		
			c.row.removeClassName('csError');
			if (c.results != '') {c.row.addClassName('csDone');}
		} else {
			c.row.addClassName('csError');
			c.row.removeClassName('csDone');
			
			new CS.v3.msgBox(el,c,'error');
		}
	}
});


/*** Get Errors ***/

// Textfield
CS.v3.getTextFieldError = Class.create(CS.v3.Forms, {
	initialize: function(el,validation) {
		//this.log('initialize:enter');
		//var start = new Date().getTime();
		var c = new CS.v3.Control(el);
		c.value1 = null;
		var compareTo = CS.v3.Base.prototype.getCustomAttribute(el,'csCompareTo-');
		var value0Empty = c.value0.empty();
		var value1Empty = null;
		var empty = null;
		
		if (compareTo != null) {
		
			var target = compareTo[0].toString();
			c.value1 = $F(target);
			value1Empty = c.value1.empty();
		}
		
		if (value0Empty || value1Empty) { empty = true; }
	
		//c.classNames.each(function(name) {
		var ar = c.classNames;
		var i = ar.length;
		var name;
		var result;
		var msg;
		var valobj;
		while(i--){
			name = ar[i];
			valobj = CS.v3.Validators[name];
			if (valobj){
				result = valobj.rule(el,c);
				if (result) {
					c.results.push(result);
				} else {
					c.results.push(result);
					msg = valobj.error(el,c);
					c.msgs.push(msg);
				}
			} else {
			// legacy
				valobj = CS.Validators[name];
				if (valobj){
					result = valobj.rule(el,c);
					if (result) {
						c.results.push(result);
				} else {
						c.results.push(result);
						msg = valobj.error(el,c);
					c.msgs.push(msg);
				}
			}
			}
		}
		//}.bind(this));
		c.msgDisplay(el,c,validation,empty);
		//var tm = new Date().getTime() - start;
		//this.log('initialize=' + tm);
		//this.log('initialize:exit');
		return this.results = c.results;
	},
	log: function (s){
		CS.v3.Logger.log("getTextFieldError:" + s);
	}
});



// Checkbox & radio
CS.v3.getCheckError = Class.create(CS.v3.Forms, {
	initialize: function(el,form) {
	
		var c = new CS.v3.Control(el);
		var getAtt = el.readAttribute('name');
		var name = $A(form[getAtt]);
		this.check = false;
		
		name.each(function(control) {
			if (control.checked) {
				this.check = true;
			}
		}.bind(this));
		
		if (this.check) {c.results = [true];
		} else {
			c.results = [false];
			c.msgs[0] = CS.v3.Validators['csVal-required'].error(el,c);
		}
		c.msgDisplay(el,c);
		return this.results = c.results;
	}
});


// Select
CS.v3.getSelectError = Class.create(CS.v3.Forms, {
	initialize: function(el) {
	
		var c = new CS.v3.Control(el);
		var obj = CS.v3.Validators['csVal-required'];
		this.result = obj.rule(el,c);
		
		if (this.result) {
			c.results = [true];
		} else {
			c.results = [false];
			c.msgs[0] = obj.error(el,c);
		}
		c.msgDisplay(el,c);
		return this.results = c.results;
	}
});



/*** Get Blockers ***/

CS.v3.getBlockers = Class.create(CS.v3.Forms, {
	initialize: function(el,type,event) {
		//this.log('initialize:enter');
		//var start = new Date().getTime();
		//var c = new CS.v3.Control(el);
		//c.classNames.each(function(name) {
		var ar = $w(el.className);//c.classNames;
		var i = ar.length;
		var name;
		var obj;
		var c;
		while(i--){
			name = ar[i];
			//this.log('initialize:i=' + i + '|name=' + name);
			if (name.startsWith('csMaxlength-')) {
				if(!c){
					c = new CS.v3.Control(el);
				}
				c.max = CS.v3.Base.prototype.getCustomAttribute(el,'csMaxlength-');
				obj = CS.v3.Blockers['csMaxlength'];
				obj.rule(el,c);
			}
			obj = CS.v3.Blockers[name];
			if (obj){
				if(!c){
					c = new CS.v3.Control(el);
				}
				obj.rule(el,c,event);
			}
		//}.bind(this))
		}
		//var tm = new Date().getTime() - start;
		//this.log('initialize:tm=' + tm + '|c=' + c);
	},
	log: function (s){
		CS.v3.Logger.log("getBlockers:" + s);
	}
});




/*** Boxes ***/

CS.v3.ErrorCountBox = Class.create(CS.v3.Base.prototype, {
	initialize: function(form,results) {
	
		var results = results.compact();
		var results = results.flatten();
		var errorTest = results.any(function(s) {return s == false;});
		
		var errorsBoxTest = CS.v3.down(form,'DIV.csPanelErrors');
		
		if (errorsBoxTest == null) {
			var bx = CS.v3.HTML.errorBoxCount;
			//var bc = CS.v3.down(form,'FIELDSET');
			//bc.insert({before: bx});
			
			form.insert({top: bx});
		}
		
		var errorsBox = CS.v3.down(form,'DIV.csPanelErrors');
		
		if (errorTest == true) {
			
			var errorCount = form.select("tr[class*='csError']","div[class*='csError.csRow']");
			var errorCount = errorCount.length;
			errorsBox.removeClassName('csBoxHide');
			var errorsCount2 = CS.v3.down(form,'SPAN.csCount');
			
			errorsCount2.update(errorCount);
			form.addClassName('csDisabled');
		} else {
		
			form.removeClassName('csDisabled');
			errorsBox.addClassName('csBoxHide');
		}
		
	}
});


CS.v3.msgBox = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,c,type) {
	
		var row = CS.v3.getParentElement(el,'TR') || CS.v3.getParentElementWithClass(el,'.csRow');//el.up('tr') || el.up('.csRow');
		var fields = CS.v3.down(row,'DIV.csFields');
		
		var boxtest = CS.v3.down(fields,'.csPanelError');
		if (c.msgs instanceof Array) {
			this.msgs = c.msgs.join('');
		} else {
			this.msgs = c.msgs;
		}
		
		if (boxtest == null) {
			this.box = CS.v3.HTML.errorBox();
			fields.insert({bottom: this.box});
		}
		var boxError = CS.v3.down(fields,'.csPanelError');
		var eMsg = CS.v3.down(boxError,'.csErrorMsg');
		var hMsg = CS.v3.down(boxError,'.csHintMsg');
		
		var hLocal = CS.v3.down(fields,'.csHintLocal');
		var eLocal = CS.v3.down(fields,'.csErrorLocal');
		
		if (type == 'error') {eMsg.update(this.msgs);}
		if (type == 'hint') {hMsg.update(this.msgs);}
		
		
		// Local Messages - Update 
		c.classNames.each(function(name) {
		
			var class1 = 'P.' + name;
			var localMsgP = null;
			if (type == 'error' && eLocal) { localMsgP = CS.v3.down(eLocal,class1);}
			if (type == 'hint' && hLocal) { localMsgP = CS.v3.down(hLocal,class1);}
			if (localMsgP) {
				var localMsg = localMsgP.cloneNode(true);
				var storedMsgP = CS.v3.down(boxError,class1);
				if (storedMsgP) {storedMsgP.update(localMsg);}
			}
		});

		// Update with Dynamic values
		var value0 = CS.v3.down(eMsg,'.value0');
		var value1 = CS.v3.down(eMsg,'.value1');
		
		if (value0) {value0.update(c.value0);}
		if (value1) {value1.update(c.value1);}
	}
});


/*** Validators ***/
CS.v3.Validators = {
	'tester': {
		rule: function(el,c) {return true;},
		error: function(el,c) {return ''},
		hint: function(el,c) {return 'tester'}
	},
	'csVal-required': {
		rule: function(el,c) {
			if ((c.value0 == null) || (c.value0.length == 0)) {return false} 
			else {return true;}
		},
		error: function(el,c) {return '<p class="csVal-required">Required fields(s).</p>'},
		hint: function(el,c) {return '<p class="csVal-required">Required fields(s).</p>'}
	},
	'csVal-isNumber': {
		rule: function(el,c) {return (!isNaN(c.value0) && !/^\s+$/.test(c.value0));},
		error: function(el,c) {return '<p class="csVal-isNumber">Enter a valid number in this field.</p>'},
		hint: function(el,c) {return '<p class="csVal-isNumber">Enter a valid number in this field.</p>'}
	},
	'csVal-isDigit': {
		rule: function(el,c) {return (!isNaN(c.value0) && !/[^\d]/.test(c.value0));},
		error: function(el,c) {return '<p class="csVal-isDigit">Enter a valid number in this field.</p>'},
		hint: function(el,c) {return '<p class="csVal-isDigit">Enter a valid number in this field.</p>'}
	},
	'csVal-isAlpha': {
		rule: function(el,c) {return /^[a-zA-Z]+$/.test(c.value0);},
		error: function(el,c) {return '<p class="csVal-isAlpha">Enter letters only (a-z) in this field.</p>'},
		hint: function(el,c) {return '<p class="csVal-isAlpha">Enter letters only (a-z) in this field.</p>'}
	},
	'csVal-isAlphaNum': {
		rule: function(el,c) {return !/\W/.test(c.value0);},
		error: function(el,c) {return '<p class="csVal-isAlphaNum">Enter only letters (a-z) or numbers (0-9) in this field. Spaces and other characters are not allowed.</p>'},
		hint: function(el,c) {return '<p class="csVal-isAlphaNum">Enter only letters (a-z) or numbers (0-9) in this field. Spaces and other characters are not allowed.</p>'}
	},
	'csVal-isLessThan': {
		rule: function(el,c) {
			if ((c.value0 == null) || (c.value0.length == 0)) {return null;} 
			if ((c.value1 == null) || (c.value1.length == 0)) {return null;} 
			if (c.value0 < c.value1) {return true;} else {return false}
		},
		error: function(el) {
			var msg = '<p class="csVal-isLessThan">The left field value <span class="value0"></span> must be less than the right field value <span class="value1"></span>.</p>';
			return msg;
		},
		hint: function(el,c) {return '<p class="csVal-isLessThan">The left field value <span class="value0"></span> must be less than the right field value <span class="value1"></span>.</p>'}
	},
	'csVal-isGreaterThan': {
		rule: function(el,c) {
			if ((c.value0 == null) || (c.value0.length == 0)) {return null;} 
			if ((c.value1 == null) || (c.value1.length == 0)) {return null;} 
			if (c.value0 > c.value1) {return true;} else {return false;}
		},
		error: function(el,c) {
			var msg = '<p class="csVal-isGreaterThan">This left field  value <span class="value0"></span>  must be greater than the right field value <span class="value1"></span>.</p>';
			return msg;
		},
		hint: function(el,c) {return '<p class="csVal-isGreaterThan">This left field  value <span class="value0"></span>  must be greater than the right field value <span class="value1"></span>.</p>'}
	}
};

CS.v3.Blockers = {
	'csVal-maxlength': {
		rule: function(el,c) {
		 if (c.value0.length > c.max) {el.value=el.value.substring(0,c.max)}
		}
	}
}


/*** Get Help 1.3 ***/

CS.v3.helpFocus = {
	focus : function(target) {
		this.icon = CS.v3.up(target,'DIV.csIconHint');
		this.panel = CS.v3.down(this.icon,'.csPanelHint');
		
		CS.v3.styleZIndex.active(target,this.icon);
		
		// IE 6 Only
		if (CS.v3.Base.prototype.coverIE) {
			this.ieCover = target.readAttribute('data-ie6Cover');
			if (this.ieCover == 'true') {
				CS.v3.Base.prototype.coverIE(this.panel);
			}
		}
		
		this.icon.addClassName('csHintShow');
	},
	blur : function(target) {
		this.icon =  CS.v3.up(target,'DIV.csIconHint');
		
		CS.v3.styleZIndex.inactive(target,this.icon);
		
		this.icon.removeClassName('csHintShow');
	}
}

CS.v3.getHints = Class.create(CS.v3.Forms, {
	initialize: function(el) {
		this.hint(el)
	},
	hint: function(el) {
		if (el.match('.csHide2')) {
			CS.v3.helpFocus.blur(el);
			el.removeClassName('csHide2');
		} else {
			el.addClassName('csHide2');
			CS.v3.helpFocus.focus(el);
		}
	}
});

/* IE List Boxes */

// For IE 6
CS.csIeListBoxMouseDown = function(key) {
	if (Prototype.Browser.IE) {key.style.width = 'auto'}
};

if (Prototype.Browser.IE) {CS.v3.Components.ieListBox = function(el,options) {new CS.v3.Config.ieListBox(el,options)};}
CS.v3.Config.ieListBox = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options) {
		this.ieListBox = $(el).select("select[class*='csIeListBox']");
		this.ieDisabled = $(el).select("select");
		this.bind();
	},
	bind: function() {
		var i=this.ieListBox.length;
		while(i--) {
			/* Note: Reguires another keydown observe method elsewhere up the DOM  */
			Event.observe(this.ieListBox[i], 'keydown', function(event) {
				var target = $(Event.element(event));
				if ((event.keyCode == Event.KEY_DOWN) && event.altKey) {
					this._showOptions(target);
				}
			}.bind(this));
			
			// Is required also
			Event.observe(this.ieListBox[i], 'mousedown', function(event) {
				//var target = $(Event.element(event));
				//this._showOptions(target);
			}.bind(this));
			
			Event.observe(this.ieListBox[i], 'focus', function(event) {
				var target = $(Event.element(event));
				var keyMsg = target.next('.csKeyMsg-widen');
				keyMsg.addClassName('csShowKeyMsg');
			}.bind(this));
			
			Event.observe(this.ieListBox[i], 'blur', function(event) {
				var target = $(Event.element(event));
				this._hideOptions(target);
				
				var keyMsg = target.next('.csKeyMsg-widen');
				keyMsg.removeClassName('csShowKeyMsg');
			}.bind(this));
			
			Event.observe(this.ieListBox[i], 'change', function(event) {
				var target = $(Event.element(event));
				this._hideOptions(target);
			}.bind(this));
			
		}
		var i=this.ieDisabled.length;
		while(i--){
			Event.observe(this.ieDisabled[i], 'focus', function(event) {
				var target = $(Event.element(event));
				this._disabledFocus(target);
			}.bind(this));
			
			Event.observe(this.ieDisabled[i], 'change', function(event) {
				var target = $(Event.element(event));
				this._disabledChange(target);
			}.bind(this));
		}
	},
	_showOptions: function(target) {
		target.style.width = "auto";
	},
	_hideOptions: function(target) {
		target.style.width = "";
	},
	_disabledFocus: function(target) {
		this.index = target.selectedIndex;
		CS.v3.SelectedState = this.index;
	},
	_disabledChange: function(target) {
		try {
			this.index = target.selectedIndex;
			this.option = target.options[this.index];
			this.optionExt = $(this.option);
			if (this.optionExt.match('.csDisabled')) {target.selectedIndex = target.selectedIndex[CS.v3.SelectedState];}
		} catch(e) {} //ie 6 error catch
	}
});



CS.v3.Components.Telephony = function(el,options) {new CS.v3.Config.Telephony(el,options)};
CS.v3.Config.Telephony = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options) {
		this.csSelectTelephony = $(el).select("select[class*='csSelectTelephony']");
		//this.bind();
		if (options.bind == 'true') {this.bind()}
	},
	bind: function() {
		var ar = this.csSelectTelephony;
		var i = ar.length;
		var selEl;
		while(i--){
			selEl = this.csSelectTelephony[i];
			//selEl.removeAttribute('name'); // remove these as they no purpose here!
			CS.v3.I18N.updateAttribute(selEl,'size','1'); // force to be single (not MULTIPLE!) dropdowns
			Event.observe(selEl, 'change', function(event) {
				var el = $(Event.element(event));
				this._Options(el);
				event.stop();
			}.bind(this));
		}
	},
	_Options: function(selEl) {
		var optValu = CS.v3.I18N.getDropdownSelectedValue(selEl);
		var b = CS.v3.I18N.isEmpty(optValu);
		if(!b){
			var frmEl = CS.v3.getParentElement(selEl,'FORM');//selEl.up('form');
				var inputs = frmEl.select("input[class*='csTelephonyButton']");
				if (inputs.length>0) {
					var submitInput=inputs[0];
					frmEl.insert({bottom:'<input type=\"hidden\" name=\"'+ submitInput.readAttribute('name') +'\" value=\"\" />'});
				}
				frmEl.submit();
			
		}
	}
});

/* Textarea */
CS.v3.Components.Textarea = function(el,options) {new CS.v3.Config.Textarea(el,options); };
CS.v3.Config.Textarea = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options){
		this.el = el;
		this.allTextareas = $(el).select("textarea[class*='csTextArea']");
		//this.bind();
		if (options.bind == 'true') {this.bind(); }
	},
	bind: function(){
		var el = this.el;
		var tag = CS.v3.I18N.getTagName(el);
		if(tag=='BODY'){
			this.allTextareas = $(el).select("textarea[class*='csTextArea']");
			var ar = this.allTextareas;
			var i = ar.length;
			var obj;
			while(i--){
				//try{
					obj = ar[i];
					CS.v3.Textarea.setup(obj);
				//}
				//catch(e){
				//}
			}
		}
	}
});
CS.v3.Textarea = {
	setup: function(el){
		if(el){
			try{
				var tag = CS.v3.I18N.getTagName(el);
				if(tag=='TEXTAREA'){
					var maxsize = this.getCustomAttributeMaxsize(el);
					if(maxsize>0){
						this.addDecoration(el);
						Event.observe(el,'keyup', function(event){ CS.v3.Textarea.keyupEv(event); });
						CS.v3.I18N.updateAttribute(el,'onkeyup','return CS.v3.Textarea.keyupEv(event);');
					}
				}
			}
			catch(e){
				this.log('addDecoration:e=' + e);
			}
		}
	},
	keyupEv: function(event){
		var el = $(Event.element(event));
		if(el){
			this.checkLength(el,true);
		}
	},
	checkLength: function(el,isTrim){
		var maxsize = this.getCustomAttributeMaxsize(el);
		if(maxsize>0){
			var size = this.getCurrentSize(el);
			if(size > maxsize){
				if(isTrim==true){
					var str = CS.v3.I18N.getValue(el);
					var myval = CS.v3.I18N.truncateString(str,maxsize);
					CS.v3.I18N.setValue(el,myval);
				} else {
					var tr = CS.v3.getParentElement(el,'TR');//el.up('TR');
					if(tr){
						CS.v3.I18N.addError(tr);
					}
				}
			}
			this.updateMessage(el);
		}
	},
	updateMessage: function(el){
		try{
			var maxsize = this.getCustomAttributeMaxsize(el);
			var cursize = this.getCurrentSize(el);
			var remainsize = maxsize - cursize;
			var msgmax = this.getMessageMaxsize(el, maxsize);
			var msgremain = this.getMessageRemaining(el, remainsize);
			var msg = '<div class=\"csRow csCols-2\"><div class=\"csCol-1\">' + msgmax + '</div><div class=\"csCol-2\">' + msgremain + '</div>';
			var wrap = CS.v3.up(el,'DIV.csTextarea-wrapper');
			var span = CS.v3.down(wrap,'DIV.csTextarea-display');
			this.updateFix(span,msg);
		}
		catch(e){
			this.log('updateMessage:e=' + e);
		}
	},
	addDecoration: function(el){
		var b=el.hasClassName('csTextarea-icon');
		if(!b){
			CS.v3.I18N.initialize(el);
			el.addClassName('csTextarea-icon');
			//el.wrap('DIV',{'class':'csTextarea-wrapper'});
			var div = CS.v3.getParentElement(el,'DIV');//el.up('DIV');
			div.addClassName('csTextarea-wrapper');
			var node = CS.v3.up(el,'DIV.csTextarea-wrapper');
			node.insert({bottom:'<div class=\"csTextarea-display\"></div>'});
		}
		this.updateMessage(el);
	},
	getCurrentSize: function(el){
		var val = CS.v3.I18N.getValue(el);
		var str = CS.v3.I18N.getLength(val);
		var rc = parseInt(str);
		return rc;
	},
	getCustomAttributeMaxsize: function(el){
		var rc = 0;
		if(el){
			try{
				var def = '0';
				var str = CS.v3.I18N.getDataAttribute(el,'data-csMaxsize',def);// HTML5
				rc = parseInt(str);
			}
			catch(e){
				this.log('getCustomAttributeMaxsize:e=' + e);
			}
		}
		return rc;
	},
	getMessageRemaining: function(el,val){
		var def = CS.v3.I18N.findProperty(el,'textarea-messageRemain');
		var str = CS.v3.I18N.getDataAttribute(el,'data-csMessageRemain',def);// HTML5
		var rc = str.replace('###',val);
		return rc;
	},
	getMessageMaxsize: function(el,val){
		var def = CS.v3.I18N.findProperty(el,'textarea-messageMaxsize');
		var str = CS.v3.I18N.getDataAttribute(el,'data-csMessageMaxsize',def);// HTML5
		var rc = str.replace('###',val);
		return rc;
	},
	updateFix: function(el,str){
		//el.update(str);
		el.innerHTML = str
	},
	log: function (s) {
		CS.v3.Logger.log("Textarea:" + s);
	}
};
CS.v3.I18N.addProperty('textarea-messageMaxsize','','Maximum ### Characters.');
CS.v3.I18N.addProperty('textarea-messageRemain','','### characters left');




/* format */
CS.v3.Components.Format = function(el,options) { new CS.v3.Config.Format(el,options); };
CS.v3.Config.Format = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options){
		var ar1 = $(el).select("fieldset[class*='csFormatCurrency']");
		this.allFormatCurr = ar1;
		var ar2 = $(el).select("input[class*='csFormat']");
		this.allFormatInput = ar2;
		//this.bind();
		if (options.bind == 'true') {this.bind(); }
	},
	bind: function(){
		var ar = this.allFormatCurr;
		var i = ar.length;
		var el;
		while(i--){
			el = ar[i];
			CS.v3.Format.setupCurrency(el);
		}
		// now for text fields
		ar = this.allFormatInput;
		i = ar.length;
		while(i--){
			el = ar[i];
			CS.v3.Format.setupFormat(el);
		}
	}
});
CS.v3.Format = {
	setupCurrency: function(el){
	/*
		var sel = $(el).select('select');
		//this.log('setupCurrency:sel=' + sel);
		if(sel){
			this.log('setupCurrency:sel=' + sel);
		}
		*/
		CS.v3.I18N.initialize(el);
		var input = $(el).select('input[type=text]');
		//this.log('setupCurrency:inp=' + input);
		if(input){
			CS.v3.I18N.initialize(input);
			//this.log('setupCurrency:input1=' + input);
			//input.wrap('DIV',{'class':'csFormat-wrapper'} );
			//this.log('setupCurrency:input2=' + input);
			var pattern = this.createPattern(input);
			//this.log('setupCurrency:pattern=' + pattern);
			try{
				CS.v3.I18N.setCustomAttributePattern(input,pattern);
			}
			catch(e){
				this.log('setupCurrency:test:e=' + e);
			}
			//this.log('setupCurrency:exit');
		}
	},
	setupFormat: function(input){
		//var input = $(el).select('input[type=text]');
		//this.log('setupFormat:init');
		if(input){
			CS.v3.I18N.initialize(input);
			var pattern = CS.v3.I18N.getCustomAttributePattern(input,'');
			//this.log('setupFormat:pattern=' + pattern);
			var b = CS.v3.I18N.isEmpty(pattern);
			if(!b){
				CS.v3.I18N.updateAttribute(input,'title',pattern);
				this.reformat(input);
				Event.observe(input,'blur', function(event){ CS.v3.Format.blurEv(event); });
				Event.observe(input,'focus', function(event){ CS.v3.Format.focusEv(event); });
			}
		}
		//this.log('setupFormat:exit');
	},
	reformat: function(el){
		try{
			var filler = ' ';
			var sourceRaw = this.parseInputAmount(el);
			var patternRaw = CS.v3.I18N.getCustomAttributePattern(el,'');
			//this.log('reformat:val=' + val + '|pattern=' + pattern);
			
			var sourceTrim = CS.v3.I18N.trimString(sourceRaw);
			var sourceSB = CS.v3.I18N.reverseString(sourceTrim);
			var patternTrim = CS.v3.I18N.trimString(patternRaw);
			var patternSB = CS.v3.I18N.reverseString(patternTrim);
			//this.log('reformat:val2=' + sourceSB + '|pattern2=' + patternSB);
			var sourceSize = CS.v3.I18N.getLength(sourceSB);
			var patternSize = CS.v3.I18N.getLength(patternSB);
			var j = 0;
			var i = 0;
			while(i<patternSize){
				var cSource = filler;
				var cPattern = CS.v3.I18N.getCharAt(patternSB,i);
				if(cPattern == '#')
				{
					if(j<sourceSize)
					{
						cSource = CS.v3.I18N.getCharAt(sourceSB,j);
					} else {
						cSource = filler;
					}
					j++;
					patternSB = CS.v3.I18N.setCharAt(patternSB,i,cSource);
				} else {
					if(j>sourceSize){
						cPattern = filler;
						patternSB = CS.v3.I18N.setCharAt(patternSB,i,cSource);
					}
				}
				i++;
			}
			/* EXTRA?...
			while(j<sourceSize){
				patternSB += CS.v3.I18N.getCharAt(sourceSB,j);
				j++;
			}
			*/
			var raw = CS.v3.I18N.reverseString(patternSB);
			var rc = CS.v3.I18N.trimString(raw);
			//this.log('reformat:rc=' + rc);
			CS.v3.I18N.setValue(el,rc);
		}
		catch(e){
			this.log('reformat:e=' + e);
		}
	},
	focusEv: function(event){
		var el = $(Event.element(event));
		//this.log('focusEv:el=' + el);
		try{
			var val = this.parseInputAmount(el);
			//this.log('focusEv:val=' + val);
			CS.v3.I18N.setValue(el,val);
		}
		catch(e){
			this.log('focusEv:e=' + e);
		}
		//this.log('focusEv:exit');
	},
	blurEv: function(event){
		var el = $(Event.element(event));
		//this.log('blurEv:el=' + el);
		this.reformat(el);
		//this.log('blurEv:exit');
	},
	getCustomAttributeThousandSeparator: function(el){
		var def = CS.v3.I18N.findProperty(el,'format_thousand_separator');//',';
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csThousandSeparator',def);// HTML5 
		return rc;
	},
	getCustomAttributeDecimalSeparator: function(el){
		var def = CS.v3.I18N.findProperty(el,'format_decimal_separator');//'.';
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDecimalSeparator',def);// HTML5 
		return rc;
	},
	getCustomAttributeNumberOfDecimals: function(el){
		var def = CS.v3.I18N.findProperty(el,'format_number_of_decimals');//'2';
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csNumberOfDecimals',def);// HTML5 
		return rc;
	},
	getCustomAttributeGrouping: function(el){
		var def = CS.v3.I18N.findProperty(el,'format_grouping');//'3';
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csGrouping',def);// HTML5 
		return rc;
	},
	getCustomAttributeZero: function(el){
		var def = CS.v3.I18N.findProperty(el,'format_zero');//'0';
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csZero',def);// HTML5 
		return rc;
	},
	createPattern: function(el){
		//this.log('createPattern:init');
		var rc = '';
		try{
			var nodStr = this.getCustomAttributeNumberOfDecimals(el);
			var deciStr = this.getCustomAttributeDecimalSeparator(el);
			var thouStr = this.getCustomAttributeThousandSeparator(el);
			var groupStr = this.getCustomAttributeGrouping(el);
			var zeroStr = this.getCustomAttributeZero(el);
	
			var maxgroups = 4;
			var group = parseInt(groupStr);
			var nod = parseInt(nodStr);
			for(var i=0;i<maxgroups;++i){
				if(i>0){
					rc+=thouStr;
				}
				for(var g=0;g<group;++g){
					rc+="#";
				}
			}
			if(nod>0){
				rc+=deciStr;
			}
			for(var d=0;d<nod;++d){
				rc+="#";
			}
		}
		catch(e){
			this.log('createPattern:e=' + e);
		}
		//this.log('createPattern-rc=' + rc);
		return rc;
	},
	parseInputAmount: function(el){
		var rc = '';
		var raw = CS.v3.I18N.getValue(el);
		var x = CS.v3.I18N.trimString(raw);
		var b = CS.v3.I18N.isEmpty(x);
		if(!b){
			var ar = CS.v3.I18N.findProperty(el,'format_remove');
			var i = ar.length;
			if(i>0){
				var c;
				while(i--){
					c = ar[i];
					x = CS.v3.I18N.replaceString(x,c,'');
				}
			}
			rc = x;
		}
		return rc;
	},
	formatNumber: function(val, decimal, delim_thou, delim_frac) {
		//decimal  - the number of decimals after the digit from 0 to 3
		//-- Returns the passed number as a string in the xxx,xxx.xx format.
		var divider =10;
		switch(decimal){
			case 0: divider=1; break;
			case 1: divider=10; break;
			case 2: divider=100; break;
			case 3: divider=1000; break;
			case 4: divider=10000; break;
			case 5: divider=100000; break;
			case 6: divider=1000000; break;
			default:  	 //for 3 decimal places
				divider=1000;
		}
		var workNum=Math.abs((Math.round(val*divider)/divider));
		var workStr=EMPTY+workNum;
		if (workStr.indexOf(delim_frac)==-1){workStr+=delim_frac;};
		var dStr=workStr.substr(0,workStr.indexOf(delim_frac));
		dNum=dStr-0;
		var pStr=workStr.substr(workStr.indexOf(delim_frac));
		while (pStr.length-1< decimal){ pStr+=ZERO; }
		if(pStr == delim_frac){ pStr = EMPTY; }
		var dLen = 0;
		//--- Adds a comma in the thousands place.
		if (dNum>=1000) {
			dLen=dStr.length;
			dStr=parseInt(''+(dNum/1000))+delim_thou+dStr.substring(dLen-3,dLen);
		}
		//-- Adds a comma in the millions place.
		if (dNum>=1000000) {
			dLen=dStr.length;
			dStr=parseInt(''+(dNum/1000000))+delim_thou+dStr.substring(dLen-7,dLen);
		}
		var rc = dStr + pStr;
		//-- Put numbers in parentheses if negative.
		//if (val<0) { rc='('+rc+')'; }
		//You could include a dollar sign in the return value.
		//rc =  "$"+rc;
		return rc;
	},
	removeCents:function(obj,decimals,delim_thou,delim_frac){
		var val = obj.value;
		var pos = val.indexOf(delim_frac);
		var str = EMPTY;
		if(pos>-1){
			str= val.substr(0,val.indexOf(delim_frac));
		} else {
			str =val;
		}
		obj.value = ohb_formatNumber(str,decimal,delim_thou,delim_frac);
	},
validateAmount:function(el, min, mineq, max, maxeq, msgOperator, msgString){
	var isModifiable = true;
	if(min != null && !obj.value > min){
		isModifiable = false;
	} else if(max != null && !obj.value < max){
		isModifiable = false;
	}else if(mineq != null && !obj.value >= mineq){
		isModifiable = false;
	}else if(maxeq != null && !obj.value <= maxeq){
		isModifiable = false;
	}
	var conf=true;
	if(!isModifiable){
		conf = confirmSubmit("You are only authorised to enter value " + msgOperator + " " + msgString + " in the amount field. Do you still want to continue?");
	}
	return conf;
},
	log: function (s) {
		CS.v3.Logger.log("Format:" + s);
	}

};
CS.v3.I18N.addProperty('format_thousand_separator','',',');
CS.v3.I18N.addProperty('format_decimal_separator','','.');
CS.v3.I18N.addProperty('format_zero','','0');
CS.v3.I18N.addProperty('format_number_of_decimals','','3');
CS.v3.I18N.addProperty('format_grouping','','3');
CS.v3.I18N.addProperty('format_remove','',new Array(',','.',' ','(',')','-','$'));

/* future consideration is to read/derive these based on a CSS classname
CS.v3.I18N.addProperty('format_amount','','###,###,###,###,###.##');
CS.v3.I18N.addProperty('format_phone','','### (###)###-####');
CS.v3.I18N.addProperty('format_postcode','','### ###');
CS.v3.I18N.addProperty('format_zipcode','','#####-####');
*/


CS.v3.Components.DependentDropdowns = function(el,options) {new CS.v3.Config.DependentDropdowns(el,options); };
CS.v3.Config.DependentDropdowns = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options){
		this.allDependentDropdowns = CS.v3.DependentDropdowns.findAllDependentDropdowns(el);
		//this.bind();
		if (options.bind == 'true') {this.bind(); }
	},
	bind: function(){
		var ar = this.allDependentDropdowns;
		var ar2 = this.bindSelects(ar);
		this.bindParents(ar2);
	},
	bindSelects: function(ar){
		var i = ar.length;
		var divEl;
		var b;
		var par;
		var rc = new Array();
		while(i--){
			divEl = ar[i];
			CS.v3.DependentDropdowns.setup(divEl /*,'dddiv' + i */);
			par = CS.v3.DependentDropdowns.getCustomAttributeParent(divEl);
			b = CS.v3.I18N.isEmpty(par);
			if(b){
				rc.push(divEl);
			}
		}
		return rc;
	},
	bindParents: function(ar){
		var i = ar.length;
		var divEl;
		var nam;
		var namlast = null;
		if(i>1){
			ar.sort(); // only sort if more than 1, we need this to dedupe
		}
		while(i--){
			divEl = ar[i];
			nam = CS.v3.DependentDropdowns.getCustomAttributeName(divEl);
			if(nam!=namlast){
				CS.v3.DependentDropdowns.showChildDivsRecurseTop(divEl);
				namlast = nam;
			}
		}
		// do last one too!
		if(nam!=namlast){
			CS.v3.DependentDropdowns.showChildDivsRecurseTop(divEl);
		}
		CS.v3.DependentDropdowns.changeObservation(divEl);
	}
});
CS.v3.DependentDropdowns = {
	changeObservation: function(el){
		var ar = this.findTopDependentDropdown(el);
		var i = ar.length;
		if(i>1){
			this.log('changeObservation:i=' + i + ' should be ,ax 1 in FORM');
		}
		var x = ar[0];
		if(x){
			var frmEl = this.findFormUpEl(x);
			var ar = this.findObservers(frmEl);
			if(ar){
				var i = ar.length;
				var val = this.observeChildDivsRecurse(x);
				var obj;
				while(i--){
					obj = ar[i];
					CS.v3.I18N.setValue(obj,val);
					CS.v3.fireOnchange(obj);
				}
			}
		}
	},
	setup: function(divEl/*,suffix*/){
		var divId = Element.identify(divEl);//CS.v3.I18N.assertId(divEl,suffix);
		var ar = divEl.select('select');
		var i = ar.length;
		var selEl;
		while(i--){
			selEl = ar[i];
			this.decorateSelect(divEl,selEl);//,'ddsel' + i);
			Event.observe(selEl,'change', function(event){ CS.v3.DependentDropdowns.changeEv(event); });
		}
	},
	hideChildDivsRecurse: function(divEl){
		var childNam = this.getCustomAttributeChild(divEl);
		try{
			var b = CS.v3.I18N.isEmpty(childNam);
			if(b){
				//this.log('hideChildDivsRecurse: is EMPTY');
			} else {
				var ar = this.findFormDropdownDivs(divEl);
				var i = ar.length;
				var objdiv;
				var objchild;
				var objname;
				while(i--){
					objdiv = ar[i];
					objname = this.getCustomAttributeName(objdiv);
					if(objname == childNam){
						this.hideChildSelects(objdiv);
						this.hideChildDivsRecurse(objdiv);
					}
				}
			}
		}
		catch(e){
			this.log('hideChildDivsRecurse:e=' + e);
		}
	},
	hideChildSelects: function(divEl){
		var ar = this.findDivSelects(divEl);
		var i = ar.length;
		var selobj;
		while(i--){
			selobj = ar[i];
			this.hideSelect(selobj);
		}
	},
	decorateSelect: function(divEl,selEl,suffix){
		try{
			selEl.addClassName('csDependentSelect');
			CS.v3.I18N.updateAttribute(selEl,'size','1'); // force to be single (not MULTIPLE!) dropdowns
			var id = Element.identify(selEl);//CS.v3.I18N.assertId(selEl,suffix);
			var selVal = CS.v3.I18N.getDropdownSelectedValue(selEl);
			// (begin) clone DIV attributes to the select
			var parentKey = this.getCustomAttributeParent(divEl);
			this.setCustomAttributeParent(selEl,parentKey);
			var childKey = this.getCustomAttributeChild(divEl);
			this.setCustomAttributeChild(selEl,childKey);
			var nameKey = this.getCustomAttributeName(divEl);
			this.setCustomAttributeName(selEl,nameKey);
			//var valueKey = this.getCustomAttributeValue(divEl);
			//this.setCustomAttributeValue(selEl,valueKey);
			// (end) clone DIV attributes to the select
			//this.log('decorateSelect:selVal=' + selVal);
			//var b = CS.v3.I18N.isEmpty(selVal);
			//if(b){
				//var selected = selEl.selectedIndex;
				//selEl.selectedIndex = selected +1;
				//this.log('decorateSelect:changedSelected');
			//}
			this.hideChildDivsRecurse(divEl);
		}
		catch(e){
			this.log('decorateSelect:e=' + e);
		}
	},
	showSelect: function(selEl){
		selEl.removeAttribute('disabled');
		var divEl = this.findDivElUp(selEl);
		var nam = this.getCustomAttributeName(divEl);
		divEl.removeClassName('csHide');
		CS.v3.I18N.updateAttribute(selEl,'name',nam);
		selEl.removeClassName('csHide');
	},
	hideSelect: function(selEl){
		var par = this.getCustomAttributeParent(selEl)
		var b = CS.v3.I18N.isEmpty(par);
		if(!b){
			CS.v3.I18N.updateAttribute(selEl,'disabled','disabled');
			var nam = selEl.readAttribute('name');
			var bn = CS.v3.I18N.isEmpty(nam);
			if(!bn){
				// these should NOT be defined, but we will save it here (but not use it)
				this.setCustomAttributeNameOriginal(selEl,nam);
				selEl.removeAttribute('name');
			}
			if(selEl.hasClassName('csHide')){
				selEl.removeClassName('csHide');//dedupe
			}
			selEl.addClassName('csHide');
		}
	},
	changeEv: function(event){
		var selEl = $(Event.element(event));
		this.updateDD(selEl);
		this.changeObservation(selEl);
	},
	updateDD: function(selEl){
		try{
			var divEl = this.findDivElUp(selEl);
			this.hideChildDivsRecurse(divEl);
			var frmEl = this.findFormUpEl(selEl);
			var selChildKey = this.getCustomAttributeChild(selEl);
			var val = CS.v3.I18N.getDropdownSelectedValue(selEl);
			var divar = this.findAllDependentDropdownsName(frmEl,selChildKey);
			var i = divar.length;
			var divobj;
			var selar;
			var j;
			var selobj;
			var selval;
			while(i--){
				divobj = divar[i];
				divid = divobj.getAttribute('id');
				selar = this.findDivSelects(divobj);
				j = selar.length;
				while(j--){
					selobj = selar[j];
					selval = this.getCustomAttributeValue(selobj);
					if(selval == val){
						this.showSelect(selobj)
					} else {
						this.hideSelect(selobj);
					}
				}
			}
		}
		catch(e){
			this.log('updateDD:e=' + e);
		}
		//this.log('updateDD:exit');
	},
	setCustomAttributeChild: function(el,val){
		CS.v3.I18N.setDataAttribute(el,'data-csDropdownChild',val);// HTML5
	},
	getCustomAttributeChild: function(el){
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDropdownChild','');// HTML5 
		return rc;
	},
	setCustomAttributeParent: function(el,val){
		CS.v3.I18N.setDataAttribute(el,'data-csDropdownParent',val);// HTML5
	},
	getCustomAttributeParent: function(el){
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDropdownParent','');// HTML5 
		return rc;
	},
	setCustomAttributeName: function(el,val){
		CS.v3.I18N.setDataAttribute(el,'data-csDropdownName',val);// HTML5
	},
	getCustomAttributeName: function(el){
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDropdownName','');// HTML5 
		return rc;
	},
	setCustomAttributeNameOriginal: function(el,val){
		CS.v3.I18N.setDataAttribute(el,'data-csDropdownNameOriginal',val);// HTML5
	},
	getCustomAttributeNameOriginal: function(el){
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDropdownNameOriginal','');// HTML5 
		return rc;
	},
	setCustomAttributeValue: function(el,val){
		CS.v3.I18N.setDataAttribute(el,'data-csDropdownValue',val);// HTML5
	},
	getCustomAttributeValue: function(el){
		var rc = CS.v3.I18N.getDataAttribute(el,'data-csDropdownValue','');// HTML5 
		return rc;
	},
	findAllDependentDropdowns: function(el){
		var rc;
		if(el){
			rc = $(el).select("div[class*='csDependentDropdowns']");
		}
		return rc;
	},
	findTopDependentDropdown: function(el){
		var rc = new Array();
		var frmEl = this.findFormUpEl(el);
		var ar = this.findAllDependentDropdowns(frmEl);
		if(ar){
			var obj;
			var par;
			var i = ar.length;
			while(i--){
				obj = ar[i];
				par = this.getCustomAttributeParent(obj);
				if(par == ''){
					rc.push(obj);
				}
			}
		}
		return rc;
	},
	findAllDependentDropdownsName: function(fieldsEl,namVal){
		var rc = new Array();
		var ar = this.findAllDependentDropdowns(fieldsEl);
		var obj;
		var nam;
		var i = ar.length;
		while(i--){
			obj = ar[i];
			nam = this.getCustomAttributeName(obj);
			if(nam == namVal){
				rc.push(obj);
			}
		}
		return rc;
	},
	findFormUpEl: function(el){
		var rc;
		try{
			if(el){
				rc = CS.v3.getParentElement(el,'FORM');//el.up('FORM');//el.up('DIV.csFields');
			}
		}
		catch(e){
			this.log('findDivFieldsUpEl:e=' + e + ':el=' + el);
		}
		return rc;
	},
	findDivElUp: function(el){
		var rc;
		if(el){
			rc = CS.v3.up(el,'DIV.csDependentDropdowns');
		}
		return rc;
	},
	findObservers: function(el){
		var rc;
		if(el){
			rc = el.select('INPUT.csDependentSelectObserver');//can remove the INPUT to make more flexible!
		}
		return rc;
	},
	findFormDropdownDivs: function(divEl){
		var rc;
		var frmEl = this.findFormUpEl(divEl);
		if(frmEl){
			rc = frmEl.select('DIV.csDependentDropdowns');
		}
		return rc;
	},
	findDivSelects: function(divEl){
		var rc;
		if(divEl){
			rc = divEl.select('SELECT.csDependentSelect');
		}
		return rc;
	},
	showChildDivsRecurseTop: function(divEl){
		var ar = this.findDivSelects(divEl);
		var i = ar.length;
		if(i!=1){
			this.log('showChildDivsRecurseTop:i=' + i + ' should be 1');
		}
		var selEl = ar[0];
		var selVal = CS.v3.I18N.getDropdownSelectedValue(selEl);
		this.showChildDivsRecurse(divEl,selVal);
	},
	showChildDivsRecurse: function(divEl,selVal){
		var childNam = this.getCustomAttributeChild(divEl);
		try{
			var b = CS.v3.I18N.isEmpty(childNam);
			if(!b){
				var ar = this.findFormDropdownDivs(divEl);
				var i = ar.length;
				var objdiv;
				var objchild;
				var objname;
				while(i--){
					objdiv = ar[i];
					objname = this.getCustomAttributeName(objdiv);
					if(objname == childNam){
						var dummyVal = this.showChildSelect(objdiv,selVal);
						this.showChildDivsRecurse(objdiv,dummyVal);
					}
				}
			}
		}
		catch(e){
			this.log('showChildDivsRecurse:e=' + e);
		}
	},
	showChildSelect: function(divEl,selNam){
		var rc;
		var ar = this.findDivSelects(divEl);
		var i = ar.length;
		var selobj;
		var selval;
		while(i--){
			selobj = ar[i];
			selval = this.getCustomAttributeValue(selobj);
			if(selval == selNam){
				this.showSelect(selobj);
				rc = CS.v3.I18N.getDropdownSelectedValue(selobj);
			}
		}
		return rc;
	},
	observeChildDivsRecurse: function(divEl){
		var rc='';
		var childNam = this.getCustomAttributeChild(divEl);
		try{
			var b = CS.v3.I18N.isEmpty(childNam);
			if(b){
				//this.log('observeChildDivsRecurse: is EMPTY');
			} else {
				var ar = this.findFormDropdownDivs(divEl);
				var i = ar.length;
				var objdiv;
				var objchild;
				var objname;
				var str='';
				var x='';
				while(i--){
					objdiv = ar[i];
					objname = this.getCustomAttributeName(objdiv);
					if(objname == childNam){
						str = this.observeChildSelects(objdiv);
						if(!CS.v3.I18N.isEmpty(str)){
							x = this.observeChildDivsRecurse(objdiv);
							if(!CS.v3.I18N.isEmpty(x)){
								str = x;
							}
						}
					}
					if(!CS.v3.I18N.isEmpty(str)){
						rc = str;
					}
				}
			}
		}
		catch(e){
			this.log('observeChildDivsRecurse:e=' + e);
		}
		return rc;
	},
	observeChildSelects: function(divEl){
		var rc='';
		var ar = this.findDivSelects(divEl);
		var i = ar.length;
		var selobj;
		var str='';
		var b;
		while(i--){
			selobj = ar[i];
			str = this.observeSelect(selobj);
			b = CS.v3.I18N.isEmpty(str);
			if(!b){
				rc = str;
			}
		}
		return rc;
	},
	observeSelect: function(selEl){
		var rc='';
		var nam = selEl.readAttribute('name');
		var bn = CS.v3.I18N.isEmpty(nam);
		if(!bn){
			if(!selEl.hasClassName('csHide')){
				rc = CS.v3.I18N.getDropdownSelectedValue(selEl);
			}
		}
		return rc;
	},
	log: function (s) {
		CS.v3.Logger.log("Dropdowns:" + s);
	}
};
