(function() {
var L = YAHOO.lang, Dom = YAHOO.util.Dom, U = ZC.Util, _GT = U.GetText;
var oEL;

oEL = ZC.Core.EventListener.Create('Alert');
	/**
	 * Event handler, called when the event fires.
	 * @param {Object} oWidget the widget that the event fired on
	 * @param {Object} oEvent the custom event that fired
	 * @param {Object} oSrcEvent the browser event that caused this event to fire (if available)
	 */
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	ZC.JSManager.Alert(this.aDef.Message);
}

oEL = ZC.Core.EventListener.Create('EnableDisable');

oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var bEnable, sEnabledClass, sDisabledClass, sPopulateWhenDisabledFrom, mValueWhenDisabled, oPopulateFromWidget;

   	bEnable = this._SearchLists(this._GetWidgetValue(oWidget), this.aDef.EnableWhenSrcEquals, this.aDef.EnableWhenSrcNotEquals);

	sEnabledClass = this.aDef.EnabledClass || '';
	sDisabledClass = this.aDef.DisabledClass || 'disabled';

	this.oDestWidget.Enable(bEnable, sEnabledClass, sDisabledClass);
	if (bEnable)
	{
		if (!L.isUndefined(this.ValueWhenEnabled))
		{
			this.oDestWidget.SetValue(this.ValueWhenEnabled);
			delete this.ValueWhenEnabled;
		}
		return;
	}

	if (this.AttribIsset('ValueWhenDisabled'))
	{
		mValueWhenDisabled = this.GetAttrib('ValueWhenDisabled');
	}
	else if (sPopulateWhenDisabledFrom = this.GetAttribDefault('PopulateWhenDisabledFrom')) // assignment
	{
		oPopulateFromWidget = ZC.JSManager.GetWidget(sPopulateWhenDisabledFrom);
		if (oPopulateFromWidget)
			mValueWhenDisabled = oPopulateFromWidget.GetValue();
	}	

	if (!L.isUndefined(mValueWhenDisabled))
	{
		// save old value, restore if we enable again
		this.ValueWhenEnabled = this.oDestWidget.GetValue();
		this.oDestWidget.SetValue(mValueWhenDisabled);
	}	
}

oEL = ZC.Core.EventListener.Create('EnableDisableTab');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	this.oTabView = ZC.JSManager.GetWidget(this.aDef.TabViewName);
	if (!L.isUndefined(this.oTabView))
	{
		var bEnable = this._SearchLists(this._GetWidgetValue(oWidget), this.aDef.EnableWhenSrcEquals, this.aDef.EnableWhenSrcNotEquals);
		this.oTabView.EnableTab(this.aDef.TabID, bEnable);
	}
}

/**
 * TODO: the whole SelectOrUpload widget possibly wants replacing
 * it could probably be done with a ShowHide eventlistener
 */
oEL = ZC.Core.EventListener.Create('SelectOrUpload');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var sDestId = this.oDestWidget._elInput.id;
	var eSelectDiv = Dom.get('div.' + sDestId + '.select');
	var eUploadDiv = Dom.get('div.' + sDestId + '.upload');

	if (oWidget.GetValue() == 1)
	{
		eSelectDiv.style.display='block';
		eUploadDiv.style.display='none';
	}
	else
	{
		eSelectDiv.style.display='none';
		eUploadDiv.style.display='block';
	}
}

oEL = ZC.Core.EventListener.Create('SetOptionsFromJSArray');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	if (!L.isUndefined(window[this.aDef.ArrayName]))
	{
		var aNewOptions = window[this.aDef.ArrayName][this._GetWidgetValue(oWidget)];
		this.oDestWidget.SetAttrib('Options', aNewOptions);
	}
}

oEL = ZC.Core.EventListener.Create('SetOptionsFromAjax');
oEL.prototype.Setup = function()
{
	this.oSendFields = {};

	ZC.JSManager.GetEvent('ManagerInit').subscribe(function() {
		U.ForEach(this.GetAttribDefault('SendFields', {}), function(sWidgetName, sQueryParam)
		{
			var oWidget = this.oDestWidget.oForm.GetWidget(sWidgetName) || ZC.JSManager.GetWidget(sWidgetName);

			if (L.isNumber(sQueryParam))
				sQueryParam = sWidgetName;

			if (oWidget)
				this.oSendFields[sQueryParam] = oWidget;
		}, this);
	}, this, true);

	return true;
}

oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var oCallback = {
			customevents: {
				onFailure: 	function()
				{
					ZC.JSManager.Alert(_GT("The server was unable to retrieve the data"));
				},
				onSuccess: 	function(sEventType, aArgs)
				{
					var oResponse = YAHOO.lang.JSON.parse(aArgs[0].responseText);
					this.oDestWidget.SetAttrib('Options', oResponse);
				}
			},
			scope: this
		},
		sURL = ZC.JSManager.URL(this.oSendFields, this.GetAttrib('AjaxURL'));

	YAHOO.util.Connect.asyncRequest('GET', sURL, oCallback);
}

oEL = ZC.Core.EventListener.Create('SetValue_FromSource');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	oDestWidget.SetValue(this._GetWidgetValue(oWidget));
}

oEL = ZC.Core.EventListener.Create('ShowHideElements');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
   	var Elements, 
		bShow = this._SearchLists(this._GetWidgetValue(oWidget), this.aDef.ShowWhenSrcEquals, this.aDef.ShowWhenSrcNotEquals);

	if (this.aDef.ElementType && this.aDef.ElementClass)
	{
		Elements = YAHOO.util.Selector.query(this.aDef.ElementType + '.' + this.aDef.ElementClass);
	}
	else if (this.aDef.ElementID)
	{
		Elements = this.aDef.ElementID;
	}
	else
	{
		// ElementType + ElementClass, or ElementID not specified. Default to the destination widget.
		this.oDestWidget.Show(bShow);
		return;
	}

	if (bShow)
	{
		Dom.removeClass(Elements, 'hide');
	}
	else
	{
		Dom.batch(Elements, function(el)
		{
			el.blur();
			Dom.addClass(el, 'hide');
		});
	}
}

oEL = ZC.Core.EventListener.Create('CallJSFunction');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	if (this.aDef.JSArgs)
	{
		eval(this.aDef.JSFunction + '(' + this.aDef.JSArgs + ');');
	}
	else
	{
		var fn = window[this.aDef.JSFunction];
		if (L.isFunction(fn))
			fn();
	}
}

oEL = ZC.Core.EventListener.Create('SetRelatedOptions_FromSource');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var elDest = Dom.get(this.aDef.ID + ".1");
	if (elDest)
		setOptionsRelatedTo(elDest, this._GetWidgetValue(oWidget));
}

oEL = ZC.Core.EventListener.Create('SetRelatedOptions_FromInitialValue');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var sID = this.aDef.ID;
	var elDest = Dom.get(sID + '.1');
	var elInitial = Dom.get(sID + '.initial');

	var opt = this._GetWidgetValue(oWidget) + '-' + elInitial.value;
	for (var i = 0, iMax = elDest.length; i < iMax; i++)
	{
		if (elDest.options[i].value == opt)
		{
			elDest.value=(opt);
			return;
		}
	}
}

oEL = ZC.Core.EventListener.Create('AutoPopulate');
oEL.prototype.Setup = function()
{
	this.aCache = {};
	this.oLookupFields = {};

	if (this.oDestWidget.oParent != this.oDestWidget.oForm)
		this.oParent = this.oDestWidget.oParent;
	this.oForm = this.oDestWidget.oForm;

	ZC.JSManager.GetEvent('ManagerInit').subscribe(function()
	{
		U.ForEach(this.GetAttrib('LookupFields'), function(sField)
		{
			var oWidget = 
				(this.oParent && this.oParent.GetWidget(sField)) 
				|| this.oForm.GetWidget(sField)
				|| ZC.JSManager.GetWidget(sField);

			if (oWidget)
				this.oLookupFields[sField] = oWidget;
		}, this);
	}, this, true);

	var sLoadingElementID = this.GetAttribDefault('LoadingElement'), elLoading;
	if (sLoadingElementID && (elLoading = Dom.get(sLoadingElementID))) // assignment
	{
		this.elLoading = elLoading;
	}

	return true;
}
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	var oCallback = {
		customevents: {
			onStart: 	function() { Dom.addClass(this.elLoading, 'ap-loading'); },
			onComplete: function() { Dom.removeClass(this.elLoading, 'ap-loading'); },
			onFailure: 	function()
			{
				ZC.JSManager.Alert(_GT("The server was unable to retrieve the data"));
			},
			onSuccess: 	function(sEventType, aArgs)
			{
				var oResponse;
			   	if (sEventType == 'fromcache')
				{
					oResponse = aArgs;
				}
				else
				{
					oResponse = YAHOO.lang.JSON.parse(aArgs[0].responseText);
					this.aCache[sURL] = oResponse;
				}

				U.ForEach(oResponse, function(sValue, sKey)
				{
					var sFromColour = this.GetAttribDefault('AnimateFromColour', '#0cf'),
						oWidget, oAnim, sBG;

					oWidget = 
						(this.oParent && this.oParent.GetWidget(sKey)) 
						|| this.oForm.GetWidget(sKey)
						|| ZC.JSManager.GetWidget(sKey);

					if (sValue && oWidget)
					{
						oWidget.SetValue(sValue);

						if (this.GetAttribDefault('AnimateWhenLoaded', true))
						{
							oAnim = new YAHOO.util.ColorAnim(oWidget._elInput);
							sBG = oAnim.getAttribute('backgroundColor');

							oAnim.attributes = { backgroundColor: { from: sFromColour, to: sBG } };
							oAnim.duration = 0.5;
							oAnim.animate();
						}
					}
				}, this);
			}
		},
		scope: this
	},
		sURL = ZC.JSManager.URL(this.oLookupFields, this.GetAttrib('AjaxURL'));

	// this assumes we get the same value each time for the same query
	if (!L.isUndefined(this.aCache[sURL]))
	{
		oCallback.customevents.onSuccess.call(this, 'fromcache', this.aCache[sURL]);
	}
	else
	{
		YAHOO.util.Connect.asyncRequest('GET', sURL, oCallback);
	}
}

oEL = ZC.Core.EventListener.Create('SetValue_ToValue');
oEL.prototype.HandleEvent = function(oWidget, oEvent, oSrcEvent)
{
	if (!this._SearchLists(this._GetWidgetValue(oWidget), this.GetAttribDefault('SetWhenSrcEquals', undefined), this.GetAttrib('SetWhenSrcNotEquals', undefined)))
		return;

	this.oDestWidget.SetValue(this.GetAttrib('Value'));
}

})();
