(function() {
var L = YAHOO.lang, Dom = YAHOO.util.Dom, Evt = YAHOO.util.Event, U = ZC.Util, _GT = U.GetText, JSManager = ZC.JSManager, oCSO;

oCSO = ZC.Core.ClientSideObject.Create('QuickFind');
oCSO.prototype.Setup = function()
{
	var aMenuItems, sName, oMenu, oMenuBarItem, fnAddToMenuBar, fnInitMenu, elAttachElement, aQuickFindLinks;

	aMenuItems = [];
	for (sName in this.aDef.Items)
		if (L.hasOwnProperty(this.aDef.Items, sName))
			aMenuItems.push(sName);

	fnInitMenu = function()
	{
		oMenu = new YAHOO.widget.Menu('QuickFindMenu');
		oMenu.addItems(aMenuItems);
		oMenu.subscribe('click', this.MenuClickHandler, this, true);
	}
	
	switch (this.aDef.AttachTo)
	{
		case 'Button':
			elAttachElement = Dom.get(this.aDef.AttachToID);
			if (elAttachElement)
			{
				if (aMenuItems.length == 1)
				{
					var sItemName = aMenuItems[0];
					this.oYUIButton = new YAHOO.widget.Button({ type: 'push', label: _GT('Quick find') + ': ' + sItemName, container: elAttachElement });
					this.oYUIButton.on('click', function() { this.OpenQuickFind(sItemName); }, this, true);
				}
				else
				{
					fnInitMenu.apply(this);
					oMenu.render(document.body);
					this.oYUIButton = new YAHOO.widget.Button({ type: 'menu', label: _GT('Quick find'), menu: oMenu, container: elAttachElement });
				}
				this.elContext = this.oYUIButton.get('element');
			}
			break;

		case 'AdminMenu':
		default:
			fnInitMenu.apply(this);
			oMenuBarItem = new YAHOO.widget.MenuBarItem('QuickFindMenuBarItem', { text: _GT('Quick find'), submenu: oMenu });

			fnAddToMenuBar = function()
			{
				// runs after manager has finished initialising to make sure adminmenu exists
				var oAdminMenu = JSManager.GetWidget('adminmenu'), oYUIMenuBar;
				if (oAdminMenu)
				{
					oYUIMenuBar = oAdminMenu.oYUIMenuBar;
					oYUIMenuBar.insertItem(oMenuBarItem, this.GetAttribDefault('MenuPos', 1));
					oYUIMenuBar.render();
					this.elContext = oMenuBarItem.element;
				}
			}
			JSManager.GetEvent('ManagerInit').subscribe(fnAddToMenuBar, this, true);
			break;
	}

	// attach to links with href="#QuickFindName", class="qflink"
	aQuickFindLinks = Dom.getElementsByClassName('qflink', 'a');
	if (aQuickFindLinks.length)
	{
		Evt.on(aQuickFindLinks, 'click', function(oEvent)
		{
			var elTarget = Evt.getTarget(oEvent),
				sOpenQuickFindID = elTarget.href.replace(/.*#/, '');

			this.OpenQuickFind(sOpenQuickFindID);
		}, this, true);
	}
}

oCSO.prototype.MenuClickHandler = function(sEventType, aArgs)
{
	if (aArgs.length < 2) 
		return; // user probably clicked in the menu but outside a menu item

	this.OpenQuickFind(aArgs[1].cfg.getProperty('text'));
}

/**
 * Opens a quick find dialog for the specified name
 * @param {String} sName the name of the quickfind dialog to open
 */
oCSO.prototype.OpenQuickFind = function(sName)
{
	var sName, aItemDef, aACDef, iIEVer, fnSelectHandler, sLoadingClass = 'qf-loading', 
		fnAddLoadingClass, fnRemoveLoadingClass, fnDisplayErrorMessage, fnDisplayExtraResultsMessage, 
		oYUIDialog, oYUIAutoComplete, oYUIDatasource, oYUIMenu, oYUIMenuBarItem,
		elDialogBody, elACOuter, elACLabel, elACInput, elACContainer, elACResults, elAdvancedSearch, elErrorMessage;

	aItemDef = this.aDef.Items[sName];

	oYUIDatasource = new YAHOO.util.XHRDataSource(aItemDef.AjaxURL + '&'); // ampersand added for query=... param
	oYUIDatasource.responseSchema = { resultsList: 'Results', fields: [ 'HTML', 'URLs', 'Text' ], metaFields: { ExtraRows: 'ExtraRows' } };

	elDialogBody = document.createElement('div');
	elDialogBody.className = 'qf-dialog';

	// outer element for contents, to allow easy animation
	elACOuter = document.createElement('div');
	elDialogBody.appendChild(elACOuter);

	oYUIDialog = JSManager.CreateDialog(aItemDef.DialogTitle, elDialogBody, document.body,
	{
		width: '22em',
		context: [this.elContext, 'tl', 'bl']
	});

	elACLabel = document.createElement('label');
	elACLabel.innerHTML = aItemDef.FieldCaption;
	elACOuter.appendChild(elACLabel);

	elACContainer = document.createElement('div');
	elACOuter.appendChild(elACContainer);

	elACInput = document.createElement('input');
	elACInput.type = 'text';
	elACContainer.appendChild(elACInput);

	elACResults = document.createElement('div');
	elACContainer.appendChild(elACResults);

	// z-index workaround
	Dom.setStyle(elACContainer, 'z-index', 1000 - (Dom.getRegion(elACInput).top / 10));

	aACDef = {
		animHoriz: false,
		animVert: true,
		queryQuestionMark: false,
		queryDelay: 0.5,
		resultTypeList: false,
		forceSelection: false
	};

	oYUIAutoComplete = new YAHOO.widget.AutoComplete(elACInput, elACResults, oYUIDatasource, aACDef);

	iIEVer = YAHOO.env.ua.ie;
	if (iIEVer && iIEVer < 7)
		oYUIAutoComplete.useIFrame = true; // work around IE bug that causes select elements to appear above the AC suggestion box

	oYUIAutoComplete.formatResult = function(oResultData, sQuery, sResultMatch)
	{
		return oResultData.HTML;
	}
	oYUIAutoComplete.doBeforeLoadData = function(sQuery, oResponse, oPayload)
	{
		if (L.isUndefined(oResponse.meta) || L.isUndefined(oResponse.meta.ExtraRows) || oResponse.meta.ExtraRows == 0)
		{
			oYUIAutoComplete.setFooter(false);
			return true;
		}

		oYUIAutoComplete.setFooter('<div class="qf-extrarows">' + U.sprintf(_GT('%d more items matched...'), oResponse.meta.ExtraRows) + '</div>');
		return true;
	}
	fnSelectHandler = function(sType, aArgs) 
	{
		// create a new element to display the selected value
		var elSelectedValue = document.createElement('span'), elLinkList, elFirstLink, oAnimOut, oAnimIn;
		elSelectedValue.className = 'qf-selectedvalue';
		elSelectedValue.innerHTML = _GT('Selected: ') + aArgs[2].Text;
		Dom.setStyle(elSelectedValue, 'opacity', 0);
		Dom.addClass(elSelectedValue, 'hide');
		elDialogBody.appendChild(elSelectedValue);

		oAnimOut = new YAHOO.util.Anim(elACOuter, { opacity: { to: 0 } }, 0.5);
		oAnimIn = new YAHOO.util.Anim(elSelectedValue, { opacity: { to: 1 } }, 0.5);
		oAnimOut.onComplete.subscribe(function() { Dom.addClass(elACOuter, 'hide'); oAnimIn.animate(); });
		oAnimIn.onStart.subscribe(function() { Dom.removeClass(elSelectedValue, 'hide'); });
		
		if (aArgs[2].URLs.length == 1)
		{
			elSelectedValue.appendChild(document.createElement('br'));
			elSelectedValue.appendChild(document.createElement('br'));
			elSelectedValue.appendChild(document.createTextNode(_GT('Loading...')));
			oAnimIn.onComplete.subscribe(function() { window.location = aArgs[2].URLs[0].URL; })
		}
		else
		{
			elSelectedValue.appendChild(document.createElement('br'));
			elSelectedValue.appendChild(document.createElement('br'));
			elSelectedValue.appendChild(document.createTextNode(_GT('Select an action:')));

			elLinkList = document.createElement('ul');
			elLinkList.className = 'qf-linklist';
			U.ForEach(aArgs[2].URLs, function (aURL)
			{
				var elAnchor = document.createElement('a'),
					elLI = document.createElement('li');

				elAnchor.href = aURL.URL;
				elAnchor.appendChild(document.createTextNode(aURL.Caption));
				elLI.appendChild(elAnchor);
				elLinkList.appendChild(elLI);

				if (!elFirstLink)
					elFirstLink = elAnchor;
			});

			elSelectedValue.appendChild(elLinkList);
			oAnimIn.onComplete.subscribe(function() { elFirstLink.focus(); })
		}
		oAnimOut.animate();
	}
	oYUIAutoComplete.itemSelectEvent.subscribe(fnSelectHandler, this, true);
	oYUIAutoComplete.suppressInputUpdate = true;

	fnAddLoadingClass = function()
	{
		Dom.addClass(elErrorMessage, 'hide');
		Dom.addClass(elACOuter, sLoadingClass);
	}
	fnRemoveLoadingClass = function()
	{
		Dom.removeClass(elACOuter, sLoadingClass);
	}
	oYUIAutoComplete.dataRequestEvent.subscribe(fnAddLoadingClass);
	oYUIAutoComplete.dataReturnEvent.subscribe(fnRemoveLoadingClass);
	oYUIAutoComplete.dataErrorEvent.subscribe(fnRemoveLoadingClass);

	elErrorMessage = document.createElement('span');
	elErrorMessage.className = 'qf-error hide';
	elACOuter.appendChild(elErrorMessage);

	fnDisplayErrorMessage = function()
	{
		elErrorMessage.innerHTML = _GT('An error has occurred loading data, please refresh the page and try again.');
		Dom.removeClass(elErrorMessage, 'hide');
	}
	oYUIAutoComplete.dataErrorEvent.subscribe(fnDisplayErrorMessage);

	if (aItemDef.AdvancedSearchURL)
	{
		elAdvancedSearch = document.createElement('a');
		elAdvancedSearch.className = 'qf-advsearch';
		elAdvancedSearch.href = aItemDef.AdvancedSearchURL;
		elAdvancedSearch.innerHTML = _GT('Advanced search');

		elACOuter.appendChild(elAdvancedSearch);
	}

	this.oYUIAutoComplete = oYUIAutoComplete;
	
	oYUIDialog.render();
	oYUIDialog.show();

	elACInput.focus();
}

})();
