dojo.require('dijit._Widget');
dojo.require('dijit._Templated');
dojo.require('dijit.form.DateTextBox');
dojo.require('dojo.number');

dojo.provide("zen.zen");
dojo.provide("zen.form");
dojo.provide("zen.common");
dojo.provide('zen.extras');
dojo.provide("zen.data");
dojo.provide("zen.math");

zen = {};

/**** Basic HTML Enhancements ****/

zen.byName = function(name)
{
	if ((typeof name) != "string") {return name};
	
	var node = dojo.byId(name);
	if (node != null) {return node;}
	
	var node = dojo.query("[name=" + name + "]");
	
	if (node.length) {return node[0];}
	return null;
};

zen.getElementArrayByName = function(name)
{
	var a = new Array();
	for (var i = 0 ; i < document.forms.length ; i++)
	{
		for (var j = 0 ; j < document.forms[i].elements.length ; j++)
		{
			if (document.forms[i].elements[j].name == name)
			{
				a[a.length] = document.forms[i].elements[j];
			}
		}
		if (a.length > 0 ) {return a;}
	}
	return a;
};

zen.get = function(name)
{
	var node = zen.byName(name);

	if (node == null) {return "";}

	var format = dojo.attr(node, 'format');
	var result = "";

	// console.group("zen.get('%s')", node.name);
	
	switch (node.type)
	{
		case 'text':
		case 'textarea':
		case 'hidden':
		case 'password':
		case 'file':
			// console.log("get: %s", node.value);
			result = node.value;
			break;

		case 'select':
		case 'select-one':
			if (node.options.length > 0)
			{
				result = node.options[node.selectedIndex].value;
			}
			break;

		case 'select-multiple':
			for (var i = 0 ; i < node.options.length ; i++)
			{
				if (node.options[i].selected)
				{
					if (result.length) {result += ",";}
					result += node.options[i].value;
				}
			}
			break;
		
		case 'radio':
			var n = this.getElementArrayByName(node.name);

			for (var i = 0 ; i < n.length ; i++)
			{
				if (n[i].checked == true)
				{
					result = n[i].value;
					break;
				}
			}
			break;
		
		case 'checkbox':
			var n = this.getElementArrayByName(node.name);

			for (var i = 0 ; i < n.length ; i++)
			{
				if (n[i].checked == true)
				{
					if (result.length) {result += ",";}
					result += n[i].value;
				}
			}
			break;
		
		default:
			result = node.innerHTML; 
	}
	
	if (result != "") 
	{
		result = zen.dataType.parse(result, format);
	}

	// console.log("parsed: '%s'", result);
	// console.groupEnd();
	return result;
};

zen.set = function(name, value, skipOnChange)
{
	var node = zen.byName(name);

	// console.group("zen.set('%s', '%s', '%s')", node.name, value, skipOnChange);

	if (value == null) 
	{
		value = "";
	}
	else
	{
		value = value.toString();
	}

	if (node)
	{
		switch (node.type)
		{
			case 'text':
			case 'textarea':
			case 'password':
			case 'hidden':
				node.value = value;
				break;

			case 'select':
			case 'select-one':
				for (var i = 0 ; i < node.options.length ; i++)
				{
					if ((node.options[i].value.toUpperCase() == value.toUpperCase())
						|| (node.options[i].text.toUpperCase() == value.toUpperCase()))
					{
						node.selectedIndex = i;
						break;
					}
				}
				break;

			case 'select-multiple':
				var values = value.split(",");

				for (var j = 0 ; j < node.options.length ; j++)
				{
					node.options[j].selected = false;
				}
				for (var i = 0 ; i < values.length ; i++)
				{
					for (var j = 0 ; j < node.options.length ; j++)
					{
						if (node.options[j].value.toUpperCase() == values[i].toUpperCase())
						{
							node.options[j].selected = true;
						}
					}
				}
				break;

			case 'checkbox':
			case 'radio':
				var n = this.getElementArrayByName(node.name);
				var v = value.split(",");
				for (var i = 0 ; i < n.length ; i++)
				{
					n[i].checked = false;
					for (var j = 0 ; j < v.length ; j++)
					{
						if (n[i].value == v[j])
						{
							n[i].checked = true;
							break;
						}
					}
				}
				break;
			
			default:
				node.innerHTML = value;
				break;
		}

		if ((typeof skipOnChange == 'undefined') || (skipOnChange == false))
		{
			try
			{
				if (document.all)
			    {
					node.fireEvent("onchange", document.createEventObject());
			    }
			    else
			    {
			        var changeEvent = document.createEvent("HTMLEvents");
			        changeEvent.initEvent("change", false, true);
			        node.dispatchEvent(changeEvent);
			    }    
			}
			catch (e) {}
		}
	}
	// console.groupEnd();
};

zen.getValue = zen.get; // alias for backwards compatibility
zen.setValue = zen.set; 


zen.showDialog = function(href)
{
	dojo.require("zen.form");
	dojo.require("dijit.Dialog");
	dojo.require("dijit.layout.TabContainer");
	dojo.require("dojox.layout.ContentPane");

	var dialog = dijit.byId('idDialog');
	
	if (dialog == null)
	{
		dialog = new dijit.Dialog({id:"idDialog"}, document.createElement("DIV"));
	}

	var oldDialogContent = dijit.byId('idDialogContent');
	
	if (oldDialogContent != null)
	{
		dialog.hide();
		oldDialogContent.destroyDescendants();
		oldDialogContent.destroy();
	}

	var dialogContent = new dojox.layout.ContentPane({id:"idDialogContent", preventCache:true}, document.createElement("DIV"));

	dojo.connect(dialogContent, "onLoad", function()
	{
		dojo.query(".dialogTitle", dialogContent.containerNode).forEach(function(n){dialog.titleNode.innerHTML = n.innerHTML; n.style.display = "none";});
		dialog.containerNode.appendChild(dialogContent.domNode);

		dialog.show();
		dialog._position();

		if (dojo.byId('idQuit'))
		{
			dojo.byId('idQuit').onclick = function(){dijit.byId('idDialog').hide();};
		}
	});

	dialogContent.setHref(href);
};

zen.show = function (node, toggle, callback) 
{
	node = dojo.byId(node);
	duration = 400;

	var _show = function()
	{
		if (node.style.display == "none") 
		{
			if (node.zenDisplayCache) 
			{
				style = node.zenDisplayCache; 
				node.zenDisplayCache = undefined;
			}
			else
			{
				switch(node.tagName.toLowerCase())
				{
					case 'table':
					case 'thead':
					case 'th':
					case 'tr':
					case 'td':
					case 'tbody': {style = ''; break;}
					
					case 'button':
					case 'img':
					case 'input':
					case 'select':
					case 'textarea':
					case 'span': {style = 'inline'; break;}
					
					default: {style = 'block';}
				}
			}
			node.style.display = style;
			
			if (dojo.isFunction(callback)) {callback();}
		}
	};

	switch(toggle)
	{
		case "fade": {dojo.fadeIn({node:node, duration:duration, onEnd:_show}).play(); break;}
		case "fadeWipe": 
		{
			dojo.require("dojo.fx");
			dojo.fx.combine([
				dojo.fadeIn({node:node, duration:duration}),
				dojo.fx.wipeIn({node:node, duration:duration, onEnd:_show})
			]).play();
			break;
		}
		default: _show();
	}
};

zen.hide = function (node, toggle, callback)
{
	node = dojo.byId(node);
	duration = 400;
	
	var _hide = function()
	{
		style = node.style.display;
		
		if (style != "none")
		{
			node.zenDisplayCache = style;
			node.style.display = "none";
			
			if (dojo.isFunction(callback)) {callback();}
		}
	};

	if (node.style.display != "none")
	{
		switch(toggle)
		{
			case "fade": 
			{
				dojo.fadeOut({node:node, duration:duration, onEnd: _hide}).play(); 
				break;
			}
			case "fadeWipe": 
			{
				dojo.require("dojo.fx");
				dojo.fx.combine([
					dojo.fadeOut({node:node, duration:duration}),
					dojo.fx.wipeOut({node:node, duration:duration, onEnd: _hide})
				]).play();
				break;
			}
			default: {_hide();}
		}
	}
};

zen.showHide = function (node, toggle, callback)
{
	node = zen.byName(node);
	
	if (node.style.display == 'none')
	{
		zen.show(node, toggle, callback);
	}
	else
	{
		zen.hide(node, toggle, callback);
	}
}

zen.updateNode = function(node, url)
{
	dojo.xhrGet({url:url, load:function(response){zen.set(node, response);}});	
};

zen.toNumber = function(value, allowNull)
{
	value = value.toString().replace(/[^1234567890.+-]/g, "");
	value = parseFloat(value);

	if (isNaN(value)) 
	{
		if (allowNull == true) {return "";}
		return 0;
	}
	return value;
};


zen.checkAll = function(name, checked)
{
	boxes = zen.getElementArrayByName(name);	
	for (i = 0 ; i < boxes.length ; i++)
	{
		boxes[i].checked = checked;
	}
};

zen.setSelectOptions = function(select, array)
{
	select.options.length = 0;
	
	for(i = 0 ; i < array.length ; i++)
	{
		select.options[i] = new Option(array[i].label, array[i].value);
	}
};

zen.sync =
{
	lock:false,
	delay:300,
	lastToken:'',

	execute: function(fn, token)
	{
		if (this.lock){return;} // enforce lock
		if ((typeof token != undefined) && (this.lastToken == token)) {return;} // ignore duplicates
		
		this.lock = true;       // set the lock so that only one postponed event can occur
		_this = this;
		window.setTimeout(function()
		{
			zen.sync.lock = false;   // now that the function is executing, allow new postponed events to be scheduled.
			_this.lastToken = token; // run the necessary function
			fn();                   
		}, this.delay);
	}
};

/**** Extras *****/
dojo.require('zen.common');
dojo.provide('zen.extras');

zen.autoOrder = function(stObjectPrefix)
{
	var i = "";
	var o = "";
	
	if (zen.byName(stObjectPrefix + 1))
	{
		for (i = 1 ; o = zen.byName(stObjectPrefix + i) ; i++)
		{
			if (!o.AutoOrder)
			{
				o.AutoOrder = new Object();
				o.AutoOrder.id = i;
				o.AutoOrder.stObjectPrefix = stObjectPrefix;
				
				dojo.connect(o, "onchange", function()
				{
					var new_value = this.selectedIndex;
					var old_value = this.AutoOrder.old_selectedIndex;
					var o = "";
				
					for (i = 1 ; o = zen.byName(this.AutoOrder.stObjectPrefix + i) ; i++)
					{
						if (i != this.AutoOrder.id)
						{
							// user made a value smaller, shuffle others down
							if (new_value < old_value)
							{
								// if current select box is within range, then change its value
								if ((o.selectedIndex >= new_value) && (o.selectedIndex <= old_value))
								{
									o.selectedIndex++;
								}
							}
							// user made a value larger, shuffle others up
							else
							{
								// if current select box is within range, then change its value
								if ((o.selectedIndex <= new_value) && (o.selectedIndex >= old_value))
								{
									o.selectedIndex--;
								}
							}
						}
					}
					zen.autoOrder(this.AutoOrder.stObjectPrefix); // Reorder controls to new values
				});
			}
			o.AutoOrder.old_selectedIndex = o.selectedIndex;
		}
	}
};


zen.showAnother = function(prefix, max, link, dontScroll)
{
	var i = max;
	while(o = dojo.byId(prefix + i))
	{
		if (dojo.style(o, "display") == "none")
		{
			i--;
		}
		else
		{
			break;
		}
	}
	
	if (i < max)
	{
		zen.show(dojo.byId(prefix + (i+1)), "fade");
		
		if (dontScroll == false)
		{
			dojo.byId(link).scrollIntoView();
		}

		if (i == (max-1))
		{
			if (link)
			{
				zen.hide(dojo.byId(link));
			}
		}
	}
};
zen.inputColumn = function() {};

/***** Data Type *****/
zen.dataType = {};

zen.dataType.parse = function(value, format)
{
	var result = value;
	if (result == "") {return "";}

	// console.log("zen.dataType.parse('%s', '%s')", value, format);

	switch (format)
	{
		case "number": 
			result = zen.toNumber(result, true);
			break;
			
		case "integer":
			result = zen.toNumber(result, true);
			
			if (! isNaN(result))
			{
				result = Math.floor(result);
			}
			break;
			
		case "currency": 
			result = zen.toNumber(result, true);
			break;
	}

	// console.log("result: %s", result);
	return result;
};
	
zen.dataType.validate = function(value, format)
{
	// console.log("zen.dataType.validate('%s', '%s')", value, format);
	if (value.length == 0) {return true;}

	switch(format)
	{
		case "date":
			dojo.require("dojo.date.locale");
			var d = dojo.date.locale.parse(value, {selector:"date", datePattern:zen.dataType.getDateFormat()});

			if (d == null) {return false;}
			if (d.getFullYear() < 1753) {return false;}
			return true;

		case "email":
			// dojo.require("dojox.validate.regexp");
			// return dojox.validate.isEmailAddress(value);
			
			var re = new RegExp("^([a-z0-9]+[-._+&']?)*@([0-9a-z-]+\.)+[a-z]{2,6}$", "i");
			return re.test(value); // Boolean

		case "creditcard":
			if (value.indexOf("X") >= 0 ) {return true;}
			dojo.require("dojox.validate.creditCard");
			value = value.replace(/[^0-9]/g, "");
			return dojox.validate.isValidCreditCardNumber(value);

		case "month/year":
			rx = /^(0?[1-9]|1[012])(\/|-)(20)?[0-9]{2}$/gi;
			if (value.match(rx) == null) {return false;}
			return true;

		case "number":
		case "currency":
			value = zen.toNumber(value);
			// console.log('validating currency:  value=', value);
			// console.log('result=', (isNaN(value) == false));
			return (isNaN(value) == false);

		case "integer":
			value = zen.toNumber(value);
			if (isNaN(value)) {return false;}
			// console.log("validating integer: %s, %s, %s", value, Math.floor(value), (value == Math.floor(value)));
			
			return (value == Math.floor(value));
	}

	return true;
};

zen.dataType.format = function(value, format)
{
	var result = value;
	// console.group("zen.dataType.format('%s', '%s')", value, format);

	if (result == "") 
	{
		// console.log("empty value will be skipped");
	}
	else
	{
		switch (format)
		{
			case "number":
			case "integer":
			case "currency":
			{
				if (isNaN(result))
				{
					// console.log("isNaN(result)= true.  Setting to null value.");
					result = "";
				}
			}			
		}

		switch (format)
		{
			case "number":
				result = dojo.number._formatAbsolute(value, "#.####");
				break;
				
			case "integer":
				// console.log("begin format");
				result = dojo.number._formatAbsolute(Math.floor(value), "#,##0");
				// console.log("end format");
				break;
							
			case "currency":
				result = dojo.number._formatAbsolute(value, "#,##0.00");
				break;
		}
	}
	
	// console.log("zen.dataType.format('%s', '%s') = '%s'", value, format, result);
	// console.groupEnd();
	return result;
};

zen.dataType.getCurrency = function()
{
	// console.log("zen.dataType.getCurrency('%s')", dojo.locale);
	
	switch(dojo.locale)
	{
		case 'en-au': return 'AUD';
		case 'en-ca': return 'CAD';
		case 'en-gb': return 'GBP';
		case 'en-ie': return 'EUR';
		case 'en-nz': return 'NZD';
		case 'en-us': return 'USD';
		case 'fr-fr': return 'EUR';
		case 'de-ch': return 'CHF';
		case 'de-de': return 'EUR';
		case 'it-it': return 'EUR';
	}
	return 'USD';
};

zen.dataType.getDateFormat = function()
{
	switch (dojo.locale)
	{
		case 'en-au':
		case 'en-ca':
		case 'en-gb':
		case 'en-ie':
		case 'en-nz':
		case 'fr-fr':
		case 'de-ch':
		case 'de-de':
		case 'it-it':
			return 'dd/MM/yyyy';
	}
	return 'MM/dd/yyyy';	
}


/**** Widgets ****/

dojo.declare
(
	"zen.form", 
	[dijit._Widget, dijit._Templated], 
	{
		name:"",
		action:"",
		target:"_self",
		method:"post",
		onsubmit:"",
		enctype:"multipart/form-data",
		templateString:"<form name='${name}' action='${action}' target='${target}' method='${method}' enctype='${enctype}' dojoAttachPoint='containerNode' dojoAttachEvent='onsubmit:_onSubmit'></form>",

		message: "Please correct all highlighted fields before continuing.",
	
		_onSubmit: function(e)
		{
			if (!this.validate())
			{
				alert(this.message);
				dojo.stopEvent(e);
				return false;
			}
			if (this.onsubmit.length)
			{
				if (this.onsubmit.substring(0,6) == "return")
				{
					this.onsubmit = this.onsubmit.substring(6);
				}
				if (dojo.eval(this.onsubmit) != true)
				{
					dojo.stopEvent(e);
					return false;
				}
			}
		},

		validate: function()
		{
			var children = this.getChildren();

			for(var i = 0 ; i < children.length ; i++)
			{
				var child = children[i];
				if ((child.declaredClass == 'zen.input') || (child.declaredClass == 'zen.comboBox'))
				{
					if (!child.validate())
					{
						if (dojo.isFunction(child.domNode.focus)) {child.domNode.focus();}
						if (dojo.isFunction(child.domNode.select)) {child.domNode.select();}
						return false;
					}
				}
			}
			return true;
		},

		getChildren: function()
		{
			return dojo.query("[widgetId]", this.domNode).map(dijit.byNode); // Array
		}		
	}
);	

dojo.declare
(
	"zen.input",
	[dijit._Widget],
	{
		type:"",
		id:"",
		name:"",
		value:"",

		customValidation:"",
		fn:"",
		listen:"",
		enabled:"",
	
		format:"",
		required:"",
		minvalue:"",
		maxvalue:"",
		maxlength:50,
		minlength:0,
		
		invalidClass:"zen_InvalidInput",

		postCreate: function()
		{
			// console.group("Define Widget: %s", this.name);
			// console.log("widget type: '%s'", this.domNode.type);
			this.firstBlur = true;
	
			switch (this.format)
			{
				case 'integer':
				case 'number':
				case 'currency':
					if (this.value.length) 
					{
						this.value = zen.toNumber(this.value);
					}
					dojo.style(this.domNode, 'textAlign', 'right');
			}

			if (this.domNode.type != undefined)
			{
				dojo.attr(this.domNode, 'autocomplete', 'off');

				switch (this.domNode.type)
				{
					case 'select':
					case 'select-one':
					case 'select-multiple': 
						dojo.connect(this.domNode, "onchange", this, "onChange");
						zen.set(this.domNode, this.value, true);
						break;

					case 'text':
						// console.log('configure text options');
						zen.set(this.domNode, zen.dataType.format(this.value, this.format), true);
						// intentional fall through.  no "break" necessary.					
						
					default:

						// console.log('attach event handlers...');
						dojo.connect(this.domNode, "onchange", this, "onChange");
						dojo.connect(this.domNode, "onkeyup", this, "onKeyUp");
						this.setEnforceMaxLength();
						// console.log('done.');
						break;
				}
			}
			
			// console.log('check for "listen" attribute.');
			if ((typeof this.listen == 'string') && (this.listen != ""))
			{
				this.listen = this.listen.toString().split(",");
				for (var i = 0 ; i < this.listen.length ; i++)
				{
					dojo.connect(dojo.byId(this.listen[i]), "onkeyup" , this, "refresh");
					dojo.connect(dojo.byId(this.listen[i]), "onchange", this, "refresh");
				}
			}
			else
			{
				// console.log('no "listen" function');
			}
			
			// console.group("refresh");
			this.refresh();
			// console.log("done.");
			// console.groupEnd();
			
			// console.groupEnd();
			// console.log("really, really done.");
		},
		
		onKeyUp: function()
		{
			if (this.afterFirstBlur)
			{
				this.validate();
			}
		},
		
		onChange: function()
		{
			// console.group("widget.onChange('%s')", this.name);
			if(this.validate() && (this.domNode.type == 'text'))
			{
				var value = zen.get(this.domNode);
				value = zen.dataType.format(value, this.format);
				zen.set(this.domNode, value, true);
			}

			this.afterFirstBlur = true;
			// console.groupEnd();
		},
		
		refresh: function()
		{
			// console.group("widget.refresh('%s')", this.name)
			if (this.fn.length)
			{
				zen.set(this.domNode, zen.dataType.format(dojo.eval(this.fn), this.format), true);
			}
			
			if (this.enabled.length)
			{
				this.domNode.disabled = ! dojo.eval(this.enabled);
			}
			this.validate();
			// console.groupEnd();
		},
		
		validate: function()
		{
			// console.group("widget.validate('%s')", this.name);
			
			var valid = this.isValid();
			if (valid)
			{
				dojo.toggleClass(this.domNode, this.invalidClass, false);
			}
			else
			{
				dojo.toggleClass(this.domNode, this.invalidClass, true);
				this.afterFirstBlur = true;
			}
			
			// console.groupEnd();
			return valid;
		},
		
		isValid: function()
		{
			var value = zen.get(this.domNode);
			
			// console.log("isValid('%s')", value);

			if (this.format.length)
			{
				if (zen.dataType.validate(value, this.format) == false)
				{
					// console.log('validation fails on formatting check');
					return false;
				}
			}
			
			if (this.required.length)
			{
				try
				{
					if (dojo.eval(this.required) == true)
					{
						if (value.length == 0) 
						{
							// console.log('validation fails on required field check');
							// console.log('required="%s"', this.required);
							// console.log('value="%s"', value);
							return false;
						}
					}
				}
				catch(e) {}
			}

			if (this.minvalue.length)
			{
				if (zen.toNumber(value) < zen.toNumber(dojo.eval(this.minvalue)))
				{
					// console.log('validation fails on minvalue check');
					return false;
				}
			}
			
			if (this.maxvalue.length)
			{
				if (zen.toNumber(value) > zen.toNumber(dojo.eval(this.maxvalue)))
				{
					// console.log('validation fails on maxvalue check');
					return false;
				}
			}
			
			if (this.minlength.length)
			{
				if ((value.length > 0) && (value.length < zen.toNumber(dojo.eval(this.minlength)))) 
				{
					// console.log('validation fails on minlength check');
					return false;
				}
			}
			
			if (this.maxlength.length)
			{
				if (value.length > zen.toNumber(dojo.eval(this.maxlength))) 
				{
					// console.log('validation fails on maxvalue check');
					return false;
				}
			}
			
			if (this.customValidation.length)
			{
				if (!eval(this.customValidation))
				{
					// console.log('validation fails on custom validation check');
					return false;
				}
			}
			
			// console.log('validation succeeds');
			return true;
		},
				
		setEnforceMaxLength: function(e)
		{
			var _this = this;
			if (this.domNode.type == 'textarea')
			{
				dojo.connect(this.domNode, "onkeydown", function(e)
				{
					if (zen.get(_this.domNode).length >= _this.maxlength)
					{
						switch(e.keyCode)
						{
							// Allowable keys
							case dojo.keys.BACKSPACE:
							case dojo.keys.DELETE:
							case dojo.keys.PAGE_UP:
							case dojo.keys.PAGE_DOWN:
							case dojo.keys.END:
							case dojo.keys.HOME:
							case dojo.keys.LEFT_ARROW:
							case dojo.keys.UP_ARROW:
							case dojo.keys.RIGHT_ARROW:
							case dojo.keys.DOWN_ARROW:
							{
								break;
							}
							default:
							{
								e.preventDefault();
							}
						}
					}
				});
		
				dojo.connect(this.domNode, "onkeyup", function(e)
				{
					if (zen.get(_this.domNode).length >= _this.maxlength)
					{
						zen.set(_this.domNode, zen.get(_this.domNode).substring(0, _this.maxlength));
					}
				});
			}
			else
			{
				dojo.attr(this.domNode, "maxlength", this.maxlength);
			}
		}
	}
);

dojo.declare
(
	"zen.comboBox", 
	[zen.input],
	{
		newItemLabel  : "[Add Another Item]",
		newItemPrompt : "Please enter the value for the new item:",
		
		postCreate: function()
		{
			zen.comboBox.superclass.startup.apply(this, arguments);
			this.setDefaultValue(this.value);
			this.domNode.options[this.domNode.options.length] = new Option (this.newItemLabel, "__NEW__");
			dojo.connect(this.domNode, "onchange", this, "promptAddItem");
			
		},
		
		setDefaultValue: function(value)
		{
			if (value == "") {return;}

			for (var i = 0 ; i < this.domNode.options.length ; i++)
			{
				if (this.domNode.options[i].value == value)
				{
					this.domNode.selectedIndex = i;
					return;
				}
			}

			this.domNode.options[this.domNode.options.length] = new Option (value, value);
			this.domNode.selectedIndex = this.domNode.options.length - 1;
		},
		
		promptAddItem: function()
		{
			selectedOption = this.domNode.options[this.domNode.selectedIndex]
			if (selectedOption.value == '__NEW__')
			{
				newText = prompt(this.newItemPrompt, '');
				if (newText != null)
				{
					selectedOption.text = newText;
					selectedOption.value = newText;
					this.appendPromptNode();
				}
				else
				{
					zen.set(this.domNode, this.value);
				}
			}
			this.value = zen.get(this.domNode);
		}
	}
);

dojo.declare
(
	"zen.panel", 
	[dijit._Widget], 
	{
		show:"true",
		fn:"",
		listen:"",
		format:"",
		toggle:"",
		
		postCreate: function()
		{
			if (typeof this.listen == 'string')
			{
				if (this.listen.length)
				{
					this.listen = this.listen.split(",");
					for (var i = 0 ; i < this.listen.length ; i++)
					{
						dojo.connect(dojo.byId(this.listen[i]), "onkeyup", this, "refresh");
						dojo.connect(dojo.byId(this.listen[i]), "onchange", this, "refresh");
					}
				}
			}
			
			this.refresh();			
		},

		refresh: function()
		{
			if (this.fn.length)
			{
				zen.set(this.domNode, zen.dataType.format(dojo.eval(this.fn), this.format));
			}
			
			if (this.show != "")
			{
				if (dojo.eval(this.show))
				{
					zen.show(this.domNode, this.toggle);
				}
				else
				{
					zen.hide(this.domNode, this.toggle);
				}
			}
		}		
	}
);

dojo.declare
(
	"zen.toggle",
	[dijit._Widget, dijit._Templated], 
	{
		inputId:"",
		show:"",
		value:"0",
		templateString:"<div class='zen-toggle' dojoAttachEvent='onclick:toggle'><img dojoAttachPoint='imageElement'/><span dojoAttachPoint='containerNode'></span><input dojoAttachPoint='hiddenNode' id='${inputId}' type='hidden' value='${value}'></div>",
		
		postCreate:function()
		{
			this.refresh();
		},
		
		refresh:function()
		{
			this.imageElement.src = (this.hiddenNode.value > 0) ? "/zen/skin/default/arrowDown.gif" : "/zen/skin/default/arrowRight.gif";
			if (zen.get(this.hiddenNode) == 1)
			{
				dojo.addClass(this.domNode, "zen-selected");
			}
			else
			{
				dojo.removeClass(this.domNode, "zen-selected");
			}
		},
		
		toggle:function()
		{
			if (zen.get(this.hiddenNode) > 0)
			{
				zen.set(this.hiddenNode, 0);
			}
			else
			{
				zen.set(this.hiddenNode, 1);
			}

			this.refresh();
		}
	}
);
