/**
 * Defines the ajax search script.
 */
function AjaxSearch(formId, useSidebar)
{
	Dispatcher.call(this, "onupdate", "onupdatecomplete");

	// Initialize ajax urls
	this._url = this.GetBaseHref() + "/toon/zoekresultaat_ajax.sxml";
	this._paginationUrl = this.GetBaseHref() + "/toon/productlist.sxml";
	this._updateUrl = "/toon/update.xml";

	// Store parameters
	this._formId = formId;
	this._useSidebar = (typeof(useSidebar) == "undefined" ? false : (useSidebar == true));

	/**
	 * This value control wheather the search url links
	 */
	this._passContext = true;

	// Initialize ajax messaging variables
	this._busy = true;
	this._ignoreBusy = false;
	this._updateCode = 0;
	this._lastUpdateCode = 0;
	this._resultcount = 0;
	this._stones = new Stones();
	this._cookie = new CookieManager();
	this._initState = true;

	// Get cached search context
	var value = location.hash;
	if (value.length > 1 && value.charAt(0) == "#")
	{
		value = value.substring(1, value.length);
	}
	this._cachedSearchContextId = (value.length > 0) ? value : null;

	// Initialize navigation variables
	this._currentPage = 1;
	this._currentSort = "";
	this._sortDir = "stijgend";
	this._posted = false;

	var $this = this;
	window.setTimeout(function ()
	{
		$this.Init();
	}, 50);

};

AjaxSearch.prototype =  new Dispatcher;

/**
 * To ignore the portal context when using advanced search, set this variable
 * to true.
 */
AjaxSearch.ignoreContext = true;
AjaxSearch.current = null;

AjaxSearch.setup = function()
{
	var refineElem = document.getElementById("search_refine");
	var useSidebar = refineElem != null;

	AjaxSearch.current = new AjaxSearch("search", useSidebar);
	Calendar.setup(AjaxSearch.current);
}

/**
 * Initialize Ajax search form
 */
AjaxSearch.prototype.Init = function()
{
	// Check for fixed theme mode
	// Find and store necessary elements
	var self = this;
	this._form = $("form#" + this._formId);
	this._results = $("#search_result_list");
	this._searchContextField = $("input[name='SearchContextId']", this._form);
	this._searchContextId = this._searchContextField.val();

	log.message("Context id: " + this._searchContextId);

	var contextField = $("input[name='context']", this._form);
	if (contextField.length == 1)
	{
		this._searchContext = contextField.val();

		// Add suffix for home context
		if ((/^home$/i).test(this._searchContext))
			this._searchContext = this._searchContext + "_zoek";
	}

	this._initialSearchContext = this._searchContextId;
	this._resultcountelem = $("#resultCount");
	this._selectboxes = $("select", this._form);
	this._sideBar = $("#search_refine_container").eq(0);
	this._loading = $("#loading");
	this._loadreplace = $("#loadreplace");
	
	this._type = 'searchresult';
	if($("#search .resulttitle").has(".productlist").length == 1){
		this._type = 'productlist';
	}
	
	var summaryTitle = $("#search .resulttitle .searchresult");
	this.elements = {
		counterResult: $("span.highlight", summaryTitle).eq(0), 
		counterAccommodations: $("span.highlight", summaryTitle).eq(1), 
		counterAccommodationsContainer: $("span.accommodations", summaryTitle)
	};

	// Check if all elements are found
	if (this._form.length != 1)
	{
		return ;
	}
	if (this._searchContextField.length != 1)
	{
		return ;
	}
	if (this._results.length == 1)
	{
		this._navigation = $(".search-controls");
		this.AttachNavigation();
	}

	// Bind search buttons
	$("#submitButton", this._form).bind("click", { self: this }, self.OnSearch);
	$(".search-advanced", this._form).eq(0).bind("click", { self: this }, self.OnSearch);
	$(".search-again").eq(0).bind("click", { self: this }, self.OnCleanSearchPath);

	// Setup sidebar events
	if (this._sideBar.length == 1)
	{
		this._crumbOverview = $(".resultspecs", this._form).eq(0);
		this.AttachCrumbEvents();

		// Search results
		this.AttachSidebarEvents();
		this.AttachAlternativesEvents();
	}
	else
	{
		// Search advanced
		this._selectboxes.bind("change", function()
		{
			self.Update(this);
		});
	}

	var performLastOperations = true;
	if ((typeof(location.hash) != "undefined") && (location.hash != "") && this._useSidebar)
	{
		// Back-button used, reload search-results
		var searchContextId = this._cookie.getSearchContextId();
		if (null !== searchContextId)
		{
			performLastOperations = false;
			this.DisableTheme();
			
			// Retrieve results for stored searchcontext
			this.set_SearchContextId(searchContextId);
			var data = this.GetData(3);
			data["currentPage"] = this._cookie.getCurrentPage();
			this._ignoreBusy = true;
			this.Search(data);
		}
	}

	if (performLastOperations == true)
	{
		if (!this._useSidebar)
		{
			// Reset select fields to default, for when back button is used
			this._selectboxes.not(".selected").each(function()
			{
				this.selectedIndex = 0;
			});

			// Enable fields
			this.SetFieldsEnabled(true);
		}

		// Enable search functionality
		this._busy = false;
	}
};

AjaxSearch.prototype.GetBaseHref = function()
{
	var base = document.getElementsByTagName("base")[0];
	if (base != null && base.getAttribute("href") != null)
		return base.getAttribute("href");
	else
		return "";
}

/**
 * Get and process new search results for active searchcontextid
 */
AjaxSearch.prototype.Update = function(field, senddata)
{
	var self = this;
	if (this._busy == false || this._ignoreBusy == true)
	{
		this._busy = true;
		this._ignoreBusy = false;

		// Either use field to gather data, or use supplied senddata
		var data = null;
		if (typeof(field) == "undefined" || field == null)
		{
			// Data override
			data = senddata;
		}
		else
		{
			var value = $(field).val();
			if (typeof(value) == "undefined" || value == "")
			{
				// No value selected, so delete
				var name = $(field).attr("name");
				if (typeof(name != "undefined"))
				{
					var seqid = this._stones.find(name);
					if (seqid == null)
						seqid = $(field).metadata().seqid;
					if (typeof(seqid) != "undefined")
					{
						data = self.GetData(1, "deletebreadcrum", seqid);
						$(field).removeClass("crumbed");
					}
				}
			}
			else
			{
				// Value selected
				data = this.GetData(1, "attribute", $(field).attr("name"), value);
				$(field).addClass("crumbed");
			}
		}

		// Verify that data will be sent
		if (data !== null)
		{
			// Disable select fields and show loading
			this.SetFieldsEnabled(false);
			this.SetLoading(true);
			this.fireEvent("onupdate");

			$.get(this._updateUrl, data, function(xml) {
				// change context of 'this'
				self.CallbackUpdate(xml)
			});
		}
		else
		{
			this._busy = false;
		}
	}

	return false;
};

/**
 * Get search results for current searchcontextid
 */
AjaxSearch.prototype.CallbackUpdate = function(xml)
{
	this.fireEvent("onupdatecomplete");

	var self = this;
	try
	{
		// Update searchresult counter and parameters
		var fields = $("SEARCH > FIELDS", xml);
		if (fields.length > 0)
		{
			this._resultcount = fields.attr("aantal");
			this._resultcountelem.html(this._resultcount);

    		// Update SearchContextId
			$("SEARCH > EASYASK > SearchContextId", xml).each(function()
			{
				self.set_SearchContextId($(this).text());
			});

			this.SetupCrumbs($("SEARCH > PATH", xml));
			var count = this.ProcessFields(fields);
		}
	} catch(e) { log.message(e); }

	// Enable fields
	this.SetFieldsEnabled(true);
	this.SetLoading(false);

	self._busy = false;
};

/**
 * Get and process new search results for active searchcontextid
 */
AjaxSearch.prototype.Search = function(data)
{
	this._initState = false;

	// Check if AJAX call is not in progress
	var self = this;
	if (this._busy == false || this._ignoreBusy == true)
	{
		this._busy = true;
		this._ignoreBusy == false;

		// Get post data
		if (typeof(data) == 'undefined')
			data = this.GetData(3);

		// If results cannot be displayed on current page, submit search
		if (this._results.length > 0)
		{
			// Disable select fields
			this.SetFieldsEnabled(false);

			// Show loading message
			this._results.hide();
			this.SetLoading(true);

			this.fireEvent("onupdate");

			// Override URL and post data for pagination
			var url = this._url;
			if("navigate" === data.actie) {
				url = this._paginationUrl;
				data = {
					searchcontextid: data.searchcontextid,
					page: data.param1
				};
			}

			// Execute search
			$.get(url, data, function(xml)
			{
				self.CallbackSearch(xml);
			});
		}
		else
		{
			// Submit to searchresults page
			this._busy = false;
			this._form.submit();
		}
	}

	return false;
};

/**
 * Callback after search
 */
AjaxSearch.prototype.CallbackSearch = function(xml)
{
	this.fireEvent("onupdatecomplete");

	var self = this;

	try
	{
		var search = $("Main > SEARCH", xml);

		// Check for timeout
		if (search.length != 0)
		{
			var searchresults = $("RESULT", search);

			// Update SearchContextId
			$("EASYASK > SearchContextId", search).each(function()
			{
				self.set_SearchContextId($(this).text(), true);
			});

			// Set hash, if unset
			if ((typeof(location.hash) != "undefined") && (location.hash == ""))
				location.hash = this._searchContextId;

			// Update searchresult counter and parameters
			var accommodationCount = parseInt(searchresults.attr("accos"));
			this._resultcount = parseInt(searchresults.attr("aantal"));
			this._resultcountelem.html(this._resultcount);

			// update title bar counters
			this.elements.counterResult.text(this._resultcount); 
			this.elements.counterAccommodations.text(accommodationCount);
			
			if (this._resultcount <= 100 && accommodationCount < this._resultcount) {
				this.elements.counterAccommodationsContainer.removeClass("hide");
			} else {
				this.elements.counterAccommodationsContainer.addClass("hide");
			}
			
			if(this._type == 'productlist'){
				$("#search .resulttitle .productlist").remove();
				$("#search .resulttitle .searchresult, " +
				"#search .resultspecs, " +
				"#search .resultlinks, " +
				"#search .resultcount").removeClass("hide");
				
				$("#search").removeClass("productlist");
				
				this._type = 'searchresult';
			}

			// Display search results
			this.ProcessProductList($("ProductList", searchresults));

			// Update form contents
			this.ProcessFields($("Main > SEARCH > FIELDS", xml));

			// Setup navigation
			this.SetupNavigation(searchresults);
			this.SetupCrumbs($("PATH", search));
			this.AttachAlternativesEvents();

			// Hide loading message
			if (this._resultcount > 0)
				this._results.show();

			ui.initializeClickables();
		}
		else
		{
			this._resultcountelem.html("0");
		}
	}
	catch (e)
	{
	}
	// Enable select fields
	this.SetLoading(false);
	this.SetFieldsEnabled(true);
	this._busy = false;
};

/**
 * Display search field options, returns number of visible fields
 */
AjaxSearch.prototype.ProcessFields = function(fields)
{
	if (fields.length <= 0)
	{
		return  -1;
	}

	var self = this;
	if (this._useSidebar)
	{
		var html = fields.text().replace(/ xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"/g, "");
		this._sideBar.html(html);
		this.AttachSidebarEvents();
	}
	else
	{
		var count = 0;

		this._selectboxes.each(function()
		{
			// Find the current field
			var field = null;
			var fieldName = $(this).attr("name");
			$("Field", fields).each(function()
			{
				if (field != null) return;

				var name = $(this).attr("name");
				if (fieldName == name)
					field = $(this);
			});

			if (field != null)
			{
				// Fill field
				self.FillField(this, field, "Option");

				// Show field and label
				$(this).prev("label[name='lbl_" + $(this).attr("name") + "']").show();
				$(this).show();

				count++;
			}
			else
			{
				// Crop field to current selection
				var fieldname = $(this).attr("name").toLowerCase(); switch (fieldname)
				{
					case "streek":
					case "plaats":
						if (self._stones.find($(this).attr("name")) == null)
							$(this[0]).text("Geen voorkeur");
						break;
					default:
						self.CropField(this);
						break;
				}
			}
		});

	}

	return count;
};

// Fill the specified select element with the xml content at the xpath-specified node.
/**
 * @@@ NOTE Less efficient version, but no issues in FF
 */
AjaxSearch.prototype.FillField = function(element, xml, xpath)
{
	if ($(element).length > 0)
	{
		var optcount = $(xpath, xml).length;

		// Determine if the category has selectable options
		var hasOptions = false;
		if (optcount == 1)
		{
			var totalCount = this._resultcount;
			$(xpath, xml).each(function() {
				var count = Number($(this).attr("count"));
				if (count && (count < totalCount))
					hasOptions = true;
			});
		}
		else if (optcount > 1)
			hasOptions = true;

		// Add selection class
		if (hasOptions)
			$(element).removeClass("selected");
		else
			$(element).addClass("selected");

		if ($(xml).attr("empty") == "true")
			$(element).removeClass("crumbed");

		var idx = 0;

		$(element).empty();
		if (hasOptions)
			element.options[idx++] = new Option("Geen voorkeur", "");

		var value = this._stones.findValue($(element).attr("name"));
		var selectedIndex = 0;
		$(xpath, xml).each(function()
		{
			var key = $(this).attr("key");
			var isLine = (key == "$LINE");
			var showSeperator = (idx <= 1 && hasOptions) || isLine;

			if (showSeperator)
			{
				element.options[idx++] = new Option("--------------------", "");
				if (isLine)
					return;
			}

			var text = $(this).text();
			var count = $(this).attr("count");
			count = (count ? " (" + count + ")": "");
			var selected = $(this).attr("selected") == "selected" || text == value;
			if (selected)
				selectedIndex = idx;
			element.options[idx++] = new Option(text + count, text, false, selected);
		});
		element.selectedIndex = selectedIndex;
	}
};

/**
 * Crop the select field to the currently active element, and add a 'no preference' option for crumbed items.
 */
AjaxSearch.prototype.CropField = function(element)
{
	var text = $(element[element.selectedIndex]).text();
	var value = $(element).val();

	var func = element.onchange;
	if($.browser.safari)
	    element.onchange = null;

	var idx = 0;
	$(element).empty().addClass("selected");
	if ($(element).filter(".crumbed").length > 0)
	{
		element.options[idx++] = new Option("Geen voorkeur", "");
		element.options[idx++] = new Option("--------------------", "");
	}
	element.options[idx] = new Option(text, value, true, true);
	element.selectedIndex = idx;
	
	if($.browser.safari)
	{
	    element.blur();
	    element.onchange = func;
	    element.focus();
	}
};

/**
 * Display search results
 */
AjaxSearch.prototype.ProcessProductList = function(productList)
{
	var html = productList.text().replace(/ xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"/g, "");

	// Display search results
	$("#search_result_list").empty();
	$("#search_result_list").append(html);

};

/**
 * Display page and sorting links
 */
AjaxSearch.prototype.SetupNavigation = function(searchResults)
{
	var self = this;

	if (searchResults.length == 0)
		this._navigation.hide();
	else
	{
		this._navigation.show();

		var count = parseInt(searchResults.attr("aantal"));
		if (count == 0)
		{
			return ;
		}
		this._currentPage = parseInt(searchResults.attr("page"));
		this._cookie.setCurrentPage(this._currentPage);
		this.totalPage = parseInt(searchResults.attr("pages"));

		var lowPage = (this._currentPage - 4 <= 1 ? 1 : this._currentPage - 4);
		var highPage = (lowPage + 8 >= this.totalPage ? this.totalPage : lowPage + 8);
		
		// Create page links
		var pageLinks = new Array();
		for (var i = lowPage; i <= highPage; i++)
		{
			pageLinks.push(
					'<a href="#" class="navigate' +
						(this._currentPage == i ? ' active' : '') +
						(i == highPage ? ' last' : '') +
					' {page: ' + i + '}"><span>' + i + '</span></a>');
		}
		pageLinks = pageLinks.join("");

		// Update page numbering
		$(".paging > span", this._navigation).each(function()
		{
			$("a", this).remove(".navigate");
			$("a.prev", this).after(pageLinks);
			$(this).find("a.navigate").bind("click",
			{
				ajaxSearch: self
			}, self.OnPageChange);
		});

		if (this._currentPage > 1)
			$(".prev", this._navigation).removeClass("hide");
		else
			$(".prev", this._navigation).addClass("hide");

		if (this._currentPage < this.totalPage)
			$(".next", this._navigation).removeClass("hide");
		else
			$(".next", this._navigation).addClass("hide");

		var sortList = $("SortList", searchResults);
		if (sortList.length > 0)
		{
			var sortcat = sortList.attr("current");
			if (typeof(sortcat) != "undefined")
			{
				var sortelems = sortcat.split(",");
				if (sortelems.length == 2)
				{
					this._currentSort = sortelems[0];
					this._sortDir = sortelems[1] == "f" ? "aflopend" : "stijgend";
				}
			}

			// Create sort links
			var sortLinks = new Array();
			var elems = $("SortItem", sortList);

			for (var i = 0; i < elems.length; i++)
			{
				var sortType = $(elems[i]).attr("type");
				sortLinks.push(
					'<a href="#" class="' +
						(sortType == self._currentSort ? "active " : "") +
						(i == elems.length - 1 ? "last " : "") +
							'{sort: \'' + sortType + '\'}"><span>' +
						$(elems[i]).attr("title") + '</span></a> ');
			}
			sortLinks = sortLinks.join("");

			// Update sort categories
			$(".sorting", this._navigation).each(function()
			{
				$("span", this).each(function()
				{
					$(this).empty().append(sortLinks).find("a").bind("click",
					{
						ajaxSearch: self
					}, self.OnSortChange);

				}); $(this).removeClass("hide");

			});
		}
	}
};

/**
 * When the sidebar is used, sets up the breadcrumb overview.
 */
AjaxSearch.prototype.SetupCrumbs = function(path)
{
	var self = this;
	if (this._useSidebar == true)
	{
		// Sidebar mode
		Calendar.setup(this);

		if (0 < $(path).length)
		{
			var html = $(path).text().replace(/ xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"/g, "");
			if (html.length > 0)
			{
				if (this._initState != true)
					this.HideCrumbsTitle();

				this._crumbOverview.html(html);
				this.AttachCrumbEvents();
			}
			else
			{
				this._crumbOverview.empty();
			}
		}
	}
	else
	{
		this._stones = this.GenerateStones(path);
	}
};

AjaxSearch.prototype.GenerateStones = function(path)
{
	var $this = this;
	var result = new Stones();
	$("STONE", path).each(function(id)
	{
		var id = $(this).attr("sequence");
		var name = $("Key", this).text();
		var value = $("WAARDE", this).text();
		result.add(id, name, value);
	});
	return result;
}

AjaxSearch.prototype.HideCrumbsTitle = function()
{
	var titleElem = document.getElementById("crumbsTitle");
	if (titleElem)
		titleElem.style.display = "none";
}


/**
 * Prepare data object array for submit.
 */
AjaxSearch.prototype.GetData = function(easyaskstate, action, param1, param2)
{
	var data = new Object();
	data["searchcontextid"] = this.get_SearchContextId();
	if (typeof(this._searchContext) != "undefined")
	{
		data["context"] = this._searchContext;
	}
	if (typeof(easyaskstate) != "undefined")
	{
		data["easyaskstate"] = easyaskstate;
		if (typeof(action) != "undefined")
		{
			data["actie"] = action;
			if (typeof(param1) != "undefined")
			{
				data["param1"] = param1;
				if (typeof(param2) != "undefined")
				{
					data["param2"] = param2;
				}
			}
		}
	}
	return data;
}

/**
 * Disables the select element with the specified id and displays a loading message.
 */
AjaxSearch.prototype.SetFieldsEnabled = function(enabled)
{
	this._selectboxes.each(function()
	{
		if (typeof(enabled) != 'undefined' && enabled)
		{
			$(this).removeAttr("disabled");
		}
		else
		{
			$(this).attr("disabled", "disabled");
		}
	});
};

/**
 * Removes any theme specific elements that should not be displayed with searchresults.
 */
AjaxSearch.prototype.DisableTheme = function()
{
	$("#infoblocks").remove();
	$("#theme_introduction").remove();
}

/**
 * Enables or disables the loading animation. If enabled the number of search results display is hidden.
 */
AjaxSearch.prototype.SetLoading = function(enabled)
{
	if (this._loading.length > 0)
	{
		if (enabled == true)
		{
			this._loading.show();
			this._loadreplace.hide();
		}
		else
		{
			this._loading.hide();
			this._loadreplace.show();
		}
	}
};

/**
 * Attaches events for sidebar options
 */
AjaxSearch.prototype.AttachSidebarEvents = function()
{
	if (this._sideBar.length > 0)
	{
		var self = this;
		self._lastListId = null;
		$(".footer", this._sideBar).bind("click",
		{
			self: this
		}, this.OnToggleViewAll);

		$(".close", this._sideBar).bind("click",
		{
			self: this
		}, this.OnToggleViewAll);

		$("ul", this._sideBar).find("a").bind("click",
		{
			self: this

		}, this.OnSidebarItemSelected);
	}
}

/**
 * Attaches event for search result navigation elements
 */
AjaxSearch.prototype.AttachNavigation = function()
{
	var self = this;

	$(".paging > span", this._navigation).each(function()
	{
		$(this).find("a.navigate").bind("click",
		{
			ajaxSearch: self
		}, self.OnPageChange);

		$(this).find("a.prev").bind("click",
		{
			self: self
		}, self.OnPageShift);

		$(this).find("a.next").bind("click",
		{
			self: self
		}, self.OnPageShift);

	}
	);
	$(".sorting > span", this._navigation).each(function()
	{
		$(this).find("a").bind("click",
		{
			ajaxSearch: self
		}, self.OnSortChange);
	});
};

/**
 * Attaches events for breadcrums
 */
AjaxSearch.prototype.AttachCrumbEvents = function()
{
	this._crumbOverview.find("a").bind("click",
	{
		self: this
	}, this.OnCrumbDelete);
}

AjaxSearch.prototype.AttachAlternativesEvents = function() {
	var $this = this;
	var container = $("#search_results table");
	container.bind('mouseover', function(e) {
		var elem = $(e.target).parents("tr");
		$(elem).children("td").addClass("over");
	});
	container.bind('mouseout', function(e) {
		var elem = $(e.target).parents("tr");
		$(elem).children("td").removeClass("over");
	});
	container.bind('click', function (e) {
		var elem = $(e.target).parents("tr");
		if (0 < elem.length) {
			var href = $(elem).find("a").attr("href");
			location.href = href + '&searchContextId=' + $this.get_SearchContextId();
		}
		return false;
	});
};

/**
 * Set or get the search context id
 */
AjaxSearch.prototype.set_SearchContextId = function(value, setCookie)
{
	if (arguments.length >= 1 && typeof(value) != "undefined" && $.trim(value) != "")
	{
		this._searchContextId = value;
		if (setCookie == true)
		{
			this._cookie.setSearchContextId(value);
		}
	}
}

AjaxSearch.prototype.get_SearchContextId = function()
{
	return this._searchContextId;
}

/**
 * Link to advanced search
 */
AjaxSearch.prototype.OnSearch = function(e)
{
	var self = e.data.self;
	var value = self.get_SearchContextId();
	if (self._posted == false)
	{
		//self._posted = true;
		if ((typeof(value) != "undefined" && $.trim(value) != ""))
		{
			var addContext = this.href.indexOf("context=") == -1 && typeof(self._searchContext) != "undefined";
			var part1 = this.href + (this.href.indexOf("?") != -1 ? "&" : "?");
			var part2 = addContext ? "context=" + self._searchContext + "&" : "";
			var part3 = "searchContextId=" + encodeURIComponent(value);
			var href = part1 + part2 + part3;

			top.location.href = href;
		}
		else
		{
			top.location.href = this.href;
		}
	}

	return false;
}

/**
 * Selects an option from the sidebar
 */
AjaxSearch.prototype.OnSidebarItemSelected = function(e)
{
	var cat = $(this).parent("li").parent("ul");
	if (cat.length > 0)
	{
		var key = cat.metadata().category;
		var value = $(this).metadata().value;
		var self = e.data.self;
		self.Refine(key, value);
	}
	return false;
};

AjaxSearch.prototype.Refine = function(key, value)
{
	if (this._busy != true)
	{
		this.DisableTheme();
	
		var data = this.GetData(3, "attribute", key, value);
		this.Search(data);
		return true;
	}
	return false;
};

/**
 * Toggles the view all popup for a top 10
 */
AjaxSearch.prototype.OnToggleViewAll = function(e)
{
	var self = e.data.self;
	var listid = $(this).metadata().listid;
	if (listid != self._lastListId)
	{
		if ((typeof(self._lastListId) != "undefined") && (self._lastListId != null))
		{
			$("#" + self._lastListId).hide();
		}

		$("#" + listid).show();
		self._lastListId = listid;
	}
	else
	{
		$("#" + listid).hide();
		self._lastListId = null;
	}
	return false;
};

/**
 * Callback event for page change
 */
AjaxSearch.prototype.OnPageChange = function(event)
{
	// Change active page and retrieve search results
	var page = $(this).metadata().page;
	var self = event.data.ajaxSearch;

	if (self._currentPage != page && !(self._busy))
	{
		var data = self.GetData(3, "navigate", page);
		self._currentPage = page;
		self.Search(data);
	}

	return false;
};

/**
 * Callback event for page change
 */
AjaxSearch.prototype.OnPageShift = function(e)
{
	var self = e.data.self;
	if (!(self._busy))
	{
		// Change active page and retrieve search results
		var shiftNext = $(this).metadata().shiftNext == true;
		var page = self._currentPage + (shiftNext ? 1 : -1);
		var data = self.GetData(3, "navigate", page);
		self._currentPage = page;
		self.Search(data);
	}

	return false;
};

/**
 * Callback event for sort change
 */
AjaxSearch.prototype.OnSortChange = function(event)
{
	// Change sort method and retrieve search results
	var sort = $(this).metadata().sort;

	var self = event.data.ajaxSearch;
	if (!(self._busy))
	{
		if (self._currentSort == sort)
		{
			self._sortDir = (self._sortDir == "stijgend" ? "aflopend" : "stijgend");
		}
		else
		{
			self._currentSort = sort;
			self._sortDir = "stijgend";
		}

		// Perform new search with changed data
		var data = self.GetData(3, "sort", self._currentSort, self._sortDir);
		self.Search(data);
	}

	return false;
};

/**
 * Delete a breadcrumb from the breadcrumb overview
 */
AjaxSearch.prototype.OnCrumbDelete = function(e)
{
	var self = e.data.self;
	if (!(self._busy))
	{
		var seqid = $(this).metadata().seqid;

		if (typeof(seqid) != "undefined" && self._busy != true)
		{
			var data = self.GetData(3, "deletebreadcrum", seqid);
			self.Search(data);
		}
	}

	return false;
}

/**
 * Removes all breadcrumbs
 */
AjaxSearch.prototype.OnCleanSearchPath = function(e)
{
	var self = e.data.self;
	if (!(self._busy))
	{
		if (self._useSidebar)
		{
			var data = self.GetData(3, "cleansearchpath");

			// reset the search context to the initial value
			//data.searchcontextid = self._initialSearchContext;

			self.Search(data);
		}
		else
		{
			// Remove selected and crumbed styles
			self._selectboxes.each(function()
			{
				$(this).removeClass("crumbed").removeClass("selected");
			});

			var data = self.GetData(1, "cleansearchpath");
			self.Update(null, data);
		}
	}

	return false;
}

function Stones()
{
	this.stones = new Object();
}

Stones.prototype.add = function(id, name, value)
{
	name = name.toLowerCase();
	this.stones[id] = { name: name, value: value };
}

Stones.prototype.find = function(name, value)
{
	name = name.toLowerCase();
	for (var id in this.stones)
	{
		var item = this.stones[id];
		if (item.name == name && (item.value == value || value == null))
			return id;
	}
	return null;
}

Stones.prototype.findValue = function(name)
{
	name = name.toLowerCase();
	for (var id in this.stones)
	{
		var item = this.stones[id];
		if (item.name == name)
			return item.value;
	}
	return null;
}

function CookieManager() {
	this.cookieName = CookieManager.getCookieName();
}

CookieManager.getCookieName = function() {
	var result = "context_default";
	var url = location.href;
	var index = url.lastIndexOf(".htm");
	if (index >  - 1)
	{
		url = url.substring(0, index);
		index = url.lastIndexOf("/");
		if (index >  - 1)
		{
			result = "context_" + url.substring(index + 1, url.length);
		}
	}
	return result;
};

CookieManager.prototype.setSearchContextId = function(searchContextId) {
	var page = this.getCurrentPage();
	this.setSearchSettings(searchContextId, page);
};

CookieManager.prototype.setCurrentPage = function(page) {
	var searchContextId = this.getSearchContextId();
	this.setSearchSettings(searchContextId, page);
};

CookieManager.prototype.getSearchContextId = function() {
	return this.getSearchSettings().searchContextId;
};

CookieManager.prototype.getCurrentPage = function() {
	return this.getSearchSettings().page;
};

CookieManager.prototype.setSearchSettings = function(searchContextId, page) {
	var content = "{0};{1}".format(searchContextId || "", page || "");
	$.cookie(this.cookieName, content);
}

CookieManager.prototype.getSearchSettings = function() {
	var content = String($.cookie(this.cookieName));
	if (typeof(content) === "undefined" || content === null || content.indexOf(";") === -1)
		return { searchContextId: null, page: 1 };
	
	var values = content.split(";");
	return { searchContextId: values[0] !== "" ? values[0] : null , page: Number(values[1]) };
}

function Calendar(container, ajaxSearch)
{
	this.container = container;
	this.ajaxSearch = ajaxSearch;
	this.months = $(".calendarmonth", this.container);
	this.active = $(this.months).filter(".active");
	this.highlightedCells = $("td.dayactive", this.months);

	this.bindMonthChangeEvent();
	this.bindCellClickEvent();
}

Calendar.prototype.bindMonthChangeEvent = function()
{
	var $this = this;
	$("a.next", this.months).bind("click", function() { return $this.nextMonth(); });
	$("a.prev", this.months).bind("click", function() { return $this.previousMonth(); });
}

Calendar.prototype.bindCellClickEvent = function()
{
	var $this = this;
	$("tbody", this.months).bind("click", function(evt) { return $this.tableClick(evt); });
}

Calendar.prototype.tableClick = function(evt)
{
	var target = evt.target;
	var isWeekSelector = target.nodeName == "SPAN" || (target.nodeName == "TD" && $(target).attr("class") == "weekselector");
	var isDaySelector = target.nodeName == "TD";
	
	if (isWeekSelector)
	{
		var cell = target.nodeName == "SPAN" ? $(target).parent() : target;
		var week = getWeek(cell);
		this.selectWeek(week);
	}
	else if (isDaySelector)
	{
		var week = getWeek(target);
		var day = Number($(target).text());
		this.selectDay(target, week, day);
	}
	
	function getWeek(cell) {
		var className = $(cell).parent().attr("class");
		/\bweek(\d+)/.exec(className);
		return Number(RegExp.$1);
	}
}

Calendar.prototype.nextMonth = function()
{
	var next = this.active.next(".calendarmonth");
	if (next.length != 0)
		this.showMonth(next);
	return false;
}

Calendar.prototype.previousMonth = function()
{
	var prev = this.active.prev(".calendarmonth");
	if (prev.length != 0)
		this.showMonth(prev);
	return false;
}

Calendar.prototype.showMonth = function(active)
{
	this.active.removeClass("active");
	this.active = active;
	this.active.addClass("active");
}

Calendar.prototype.getTableCells = function(week, day)
{
	var result = [];
	if (isNaN(week))
		return $(result);

	var wholeWeek = isNaN(day);
	$(".week" + week + " td", this.container).each(function() {
		if (wholeWeek || $(this).text() == day)
			result[result.length] = this;
	});
	return $(result);
}

Calendar.prototype.selectDay = function(cell, week, day)
{
	var key = $(cell).metadata().key;
	if (key != null)
		if (this.ajaxSearch.Refine("kalender", key))
			this.highlightDate(week, day);
}

Calendar.prototype.selectWeek = function(week)
{
	this.highlightDate(week);
}

Calendar.prototype.highlightDate = function(week, day)
{
	this.highlightedCells.removeClass("dayactive")
	this.highlightedCells = this.getTableCells(week, day);
	this.highlightedCells.addClass("dayactive");
}

Calendar.instance = null;
Calendar.setup = function(ajaxSearch)
{
	var calendar = $("#sidebar .calendar");
	if (calendar.length != 0)
		Calendar.instance = new Calendar(calendar, ajaxSearch);
}

$(document).ready(AjaxSearch.setup);
