SEARCH_COOKIE_PREFIX = 'mktsearch:';
LOADING_MSG = "Loading Categories";
ATOM_MIN_WIDTH = 300;
ATOM_EXPANSION_STEP = 150;
EVENT_DATE_RANGE = 90;
EVENT_LISTING_ORDER = 'l.start_date ASC';
NORMAL_LISTING_ORDER = '';

PAGEMODE_NORMAL = 'normal';
PAGEMODE_EVENTS = 'events';
CATMODE_ATOM = 'atom';
CATMODE_SELECT = 'select';

COOKIE_LIFETIME = 0.021; // Approximately 30 minutes

var atom = null;
var categoryMode = null;
var categoryData = null;
var categoryMap = new Array();

var pageMode = PAGEMODE_NORMAL;
var search_date = new Date();
var event_dates = new Array();
var init_search;
var nextIndex = new Array();
var defaultResultsPerPage;
var pageLoaded = false;

var atomFlashVars = {onSelect: "atomNodeSelected"};
var atomSwfParams = {
        menu: "false",
        scale: "noScale",
        allowFullscreen: "true",
        allowScriptAccess: "always",
   		wmode: "transparent"
};
var atomAttributes = {id:"atom"};
swfobject.embedSWF("/components/com_mykidstime/assets/atom/atom.swf",
				   "atomWrapper",
				   ATOM_MIN_WIDTH + ATOM_EXPANSION_STEP,
				   ATOM_MIN_WIDTH,
				   "9.0.0",
				   "expressInstall.swf",
				   atomFlashVars,
				   atomSwfParams,
				   atomAttributes,
				   atomLoaded);

// Fetch category data
new Json.Remote("/index.php?option=com_mykidstime&view=categories&format=json",
		        {onComplete: categoriesLoaded}).send();

window.addEvent('load', function() {

	init_search = true;
	defaultResultsPerPage = $('count').value;

	var haveRegion = false;
	var criteria = "";

	if (window.searchCriteria) {
		for (fld in window.searchCriteria) {
			if ($(fld)) {
				setElementValue($(fld), window.searchCriteria[fld]);
				if (fld == 'region') {
					haveRegion = true;
					regionChanged();
				}
				criteria += fld + ' ' + window.searchCriteria[fld] + '\n';
			}
		}
	}
	else {
		// Restore saved cookie settings
		$A($('searchForm').elements).each( function(el) {
				if ($(el).hasClass('remember')) {  // IE seems to require the $(el)... stupid IE!
					cookieVal = Cookie.get(SEARCH_COOKIE_PREFIX + el.id);
					if (cookieVal.length && (el.id == 'cname' || el.id == 'cnames')) cookieVal = cookieVal.replace(/\+/g, ' ');
					if (cookieVal.length && el.id == 'keyword') cookieVal = cookieVal.replace(/(\S)\+\S/g, function(m){return m.replace(/\+/, ' ');});
					setElementValue(el, cookieVal);
					if (el.id == 'region') {
						haveRegion = cookieVal.length > 0;
						regionChanged();
					}
					criteria += el.id + ' ' + cookieVal + '\n';
				}
			});

		if ($('listing_type').value.toLowerCase() == "event") {
			// Initialise event search date from cookie if it exists
			search_date_cookie = Cookie.get(SEARCH_COOKIE_PREFIX + 'search_date');
			if (search_date_cookie != false) search_date = new Date(search_date_cookie);
		}

	}
	//alert(criteria);

	if ($('listing_type').value && !$('cnames').value)
		$('cnames').value = $('listing_type').value.ucfirst();

	// Establish calendar control
	resetCalendar();
	getEventDates(search_date.getFullYear(), search_date.getMonth());

	// Initialise region field from user's cookie region if we don't have a region from other search criteria
	region = Cookie.get(REGION_COOKIE_LABEL);
	if (!haveRegion && region > 0) {
		setElementValue($('region'), region);
		regionChanged();
	}

	// Register drop-down change events
	$('region').addEvent('change', regionChanged);
	$('location').addEvent('change', locationChanged);

	$$('.moreresults').each(function (el) {el.addEvent('click', fetchMoreResults);});
	$('searchForm').addEvent('submit', doSearch);
	$('search_btn').disabled = false;

	jQuery("#keyword").autocomplete({
		minLength: 3,
		source: "/index.php?option=com_mykidstime&task=search.suggest"
	});

	pageLoaded = true;
});

function atomLoaded(resultObj) {
	categoryMode = resultObj.success ? CATMODE_ATOM : CATMODE_SELECT;
	atom = $('atom');
	populateCategories();
}

function populateCategories() {

	// We could be here before the page loading is complete,
	// before the categories have been or
	// before atom has completed initialising,
	// so need to check before populating atom or drop-down list
	if (!pageLoaded ||
		!categoryData ||
		!categoryMode ||
	    (categoryMode == CATMODE_ATOM && !atom.setAtoms)) {

		if (categoryMode == CATMODE_ATOM && atom.setAtoms)
			atom.setAtoms([LOADING_MSG], {size: 80});

		// come back in 0.1 seconds
	    setTimeout(populateCategories, 100);
		return;
	}

	if (categoryMode == CATMODE_ATOM) {
    	atom.setAtoms(categoryData.data, categoryData.params); //.loadUrl("/index.php?option=com_mykidstime&task=listings.getAtomCategoryData");
        showCategoryTrail();
	}
	else if (categoryMode == CATMODE_SELECT) {
		// Populate and configure the category drop-down list
		populateCategoryDropdownList();
	}

    // Set event mode if applicable
	if ($('listing_type').value.toLowerCase() == "event")
		eventMode();

	// Perform initial search
	if (init_search)
		doSearch();
	init_search = false;
}

function categoriesLoaded(categories) {
	categoryData = categories;
	buildCategoryMap(categoryData.data, new Array());
}

function buildCategoryMap(catData, catTrail) {
	catcount = 0;
	if (catData) {
		for (var i = 0; i < catData.length; i++) {
			if (catData[i] instanceof Array) {
				catItem = catData[i][0];
				children = catData[i][1];
			}
			else {
				catItem = catData[i];
				children = null;
			}
			thisTrail = catTrail.slice();
			thisTrail.push(catItem.label);
			if (catItem.id) {
				categoryMap[catItem.id] = thisTrail;
				catcount++;
			}
			if (children != null) // && level < 2)
				catcount += buildCategoryMap(children, thisTrail);
		}
	}
	return catcount;
}

function populateCategoryDropdownList() {
	catSelect = $('category_id');

	lastltype = '';
	catSelect.options.length = 0;
	addOption(catSelect, 'Select a category...', '');
	var reverseMap = [];
	var trailList = [];

	for (var id in categoryMap) {
		if (typeof(categoryMap[id]) != 'function') {
			trailStr = categoryMap[id].join(',');
			reverseMap[trailStr] = id;
			trailList.push(trailStr);
		}
	}
	trailList.sort();
	for (var i = 0; i < trailList.length; i++) {
		trail = trailList[i].split(',');
		id = reverseMap[trailList[i]];
		ltype = trail[0];
		if (lastltype != ltype)
			addOption(catSelect, ltype, ltype);
		addOption(catSelect, '---- ' + trail.join(' > '), ltype + ':' + id);
		lastltype = ltype;
	}

	catSelect.value = Cookie.get(SEARCH_COOKIE_PREFIX + 'listing_type') + ':' +
	                  Cookie.get(SEARCH_COOKIE_PREFIX + 'cid');
	catSelect.addEvent('change', categorySelectedFromList);
}

function showCategoryTrail() {

	if (!$('cid').value && !$('listing_type').value)
		return;

	if ($('cid').value)
		catTrail = categoryMap[$('cid').value];
	else
		catTrail = [$('listing_type').value];

	$('cnames').value = catTrail.join(",");

	// Workaround for atom bug that causes top-level node not to be selected properly
	if (init_search && catTrail.length == 1) {
		init_search = 2;
		atom.showItem(['Class', 'Other']);
	}
	// End workaround

	if (catTrail.length > 0) {
		atom.showItem(catTrail);
	}
}

function atomNodeSelected(nodes)
{
	if (nodes[0].label == LOADING_MSG || init_search == 2)
		return;

	// Prepare the category trail
	var catTrail = new Array();
	for (var i = 0; i < nodes.length; i++)
		catTrail[i] = nodes[i].label;
	var catTrailString = catTrail.join(",");
	var clearingSelection = (nodes.length == 1 && catTrailString == $('cnames').value);

	// If selecting the existing root node and this is already the current node
	// then clear the selection instead.
	if (clearingSelection) {
		selectCategory(null, [], true);
	}
	else {
		// Otherwise, update internal variables with the selection
		catId = (nodes.length > 1) ? nodes[nodes.length - 1].id : "";
		selectCategory(catId, catTrail, false);
	}

	if (!init_search)
		doSearch();
}

function categorySelectedFromList() {

	vals = $('category_id').value.split(':');
	ltype = vals[0];
	catId = vals[1];

	if (catId) {
		selectCategory(catId, categoryMap[catId], false);
	}
	else {
		selectCategory(null, [ltype], false);
	}

	if (!init_search)
		doSearch();
}

function eventMode() {
	pageMode = PAGEMODE_EVENTS;

	if (categoryMode == CATMODE_ATOM) {
		// Hack to avoid wasting vertical space when Event selected, since no third level categories for this.
		// The following should be adjusted if this ever changes.
		atom.style.height = ATOM_MIN_WIDTH + "px";
		atom.style.width = "250px";
	}

	$('start_date').value = search_date.format('yyyy-mm-dd');
	$('evt_calendar_wpr').style.display = "";
	$('listing_order').value = EVENT_LISTING_ORDER;
	$('count').value = 10000;

	$$('#results_area .tab').each(function (el) {window.tabsManager.hideTab($('tab:' + el.id));});
	$$('#events_area .tab').each(function (el) {window.tabsManager.showTab($('tab:' + el.id));});
}

function normalMode() {
	pageMode = PAGEMODE_NORMAL;

	if (categoryMode == CATMODE_ATOM) {
		var nodes = atom.getSelectedItems();

		hasChildren = nodes[nodes.length - 1].children != null;
		atom.style.height = ((nodes.length < 2 || (nodes.length == 2 && !hasChildren)) ? ATOM_MIN_WIDTH : ATOM_MIN_WIDTH + ATOM_EXPANSION_STEP) + "px";
		atom.style.width = ATOM_MIN_WIDTH + ATOM_EXPANSION_STEP + "px";
	}

	$('start_date').value = '';
	$('end_date').value = '';
	$('evt_calendar_wpr').style.display = "none";
	$('listing_order').value = NORMAL_LISTING_ORDER;
	$('count').value = defaultResultsPerPage;

	$$('#events_area .tab').each(function (el) {window.tabsManager.hideTab($('tab:' + el.id));});
	$$('#results_area .tab').each(function (el) {window.tabsManager.showTab($('tab:' + el.id));});
}

function selectCategory(catId, catTrail, updateDisplay)
{
	var oldListingType = $('listing_type').value;
	var catTrailString = catTrail.join(",");
	var catName = catTrail.length > 1 ? catTrail[catTrail.length - 1] : '';

	if (updateDisplay) {
		if (categoryMode == CATMODE_ATOM)
			atom.showItem(catTrail);
		else {
			if (catTrail.length)
				$('category_id').value = catTrail[0] + (catTrail.length > 1 ? ':' + catId : '');
			else
				$('category_id').value = '';
		}
	}

	if (catTrail.length > 0) {
		$('cid').value = catId;
		$('listing_type').value = catTrail[0];
		$('cname').value = catName;
		$('cnames').value = catTrailString;
	}
	else {
		$('cid').value = "";
		$('listing_type').value = "";
		$('cname').value = "";
		$('cnames').value = "";
	}

	// Adjust atom display area, and create calendar control if Event selected
	if (catTrail[0] == 'Event') {
		eventMode();
	}
	else {
		normalMode();
	}
}

function regionChanged() {
	UpdateRegionLocations($('region'), $('location')); //, window.locations);
	if (!init_search)
		doSearch();
}

function locationChanged() {
	if (!init_search)
		doSearch();
}

function doSearch(evt) {
	// Stops the submission of the form.
	if (evt)
		new Event(evt).stop();

	if (!validateSearchCriteria()) {
		if (evt)
			alert("Please provide a keyword, or select a category or region to search on.");
		return false;
	}

	resetResults();

	$('searchForm').send({
		onRequest: showSearching,
		onSuccess: renderSearchResults,
		onFailure: searchFailed
	});

	return false;
}

function resetResults() {
	$('itemType').value = '';
	$('startIndex').value = 1;
	$$('.moreresults').each(function(el){el.style.display = 'none';});
	$('results_counts').innerHTML = '';
	$('results_suggestions').innerHTML = '';
}

function validateSearchCriteria() {
	if ($('keyword').value.length || $('listing_type').value.length || $('region').value != "0")
		return true;

	return false;
}

function showSearching() {
	$('searchingImg').style.display = '';
}

function showFetchingMore() {
	$('fetchingImg').style.display = '';
}

function searchFailed() {
	$('searchingImg').style.display = 'none';
	$('results_counts').innerHTML = 'Search failed';
	$('fetchingImg').style.display = 'none';
	alert('Unfortunately, your search request has failed due to technical difficulties. Please try again, or contact us for assistance.');
}

function fetchMoreResults(evt) {
	evt = new Event(evt);
	itemType = evt.target.value;

	$(evt.target).style.display = 'none';

	$('itemType').value = itemType;
	$('startIndex').value = nextIndex[itemType];
	$('searchForm').send({
		onRequest: showFetchingMore,
		onSuccess: renderSearchResults,
		onFailure: searchFailed
	});

	return false;
}

function renderSearchResults(searchResultsStr)
{
	$('searchingImg').style.display = 'none';
	try {
		searchResults = eval('(' + searchResultsStr + ')');
	}
	catch (e) {
		searchFailed();
		return;
	}

	// If this is a fresh search, as opposed to fetching the next 20 items
	if (!$('itemType').value.length) {

		// Update the keyword and region criteria, as these may have been automatically updated
		// by the search engine
		$('keyword').value = searchResults.criteria.keyword;
		$('region').value = searchResults.criteria.region;

		// Save user's search criteria in cookies for reuse on returning to the page.
		criteria = '';
		$A($('searchForm').elements).each(function(el){
				if (el.hasClass('remember')) {
					Cookie.set(SEARCH_COOKIE_PREFIX + el.id, getElementValue(el), {duration:COOKIE_LIFETIME, path:'/'});
					criteria += el.id + ' ' + getElementValue(el) + '\n';
				}
			});
		Cookie.set(SEARCH_COOKIE_PREFIX + 'search_date', search_date, {duration:COOKIE_LIFETIME, path:'/'});
		//alert(criteria);

		// Clear existing results
		$('listings_results').innerHTML = '';
		$('organisations_results').innerHTML = '';
		$('articles_results').innerHTML = '';

		$('upcoming_results').innerHTML = '';
		$('national_results').innerHTML = '';
		$('regular_results').innerHTML = '';

		$('results_counts').innerHTML = '';

		renderSearchCriteria();
	}
	else {
		$('fetchingImg').style.display = 'none';
	}

	var selectedType = '';

	if (pageMode == PAGEMODE_EVENTS) {

		renderEvents(searchResults.listings);

		// Select an appropriate tab
		selectedType = 'upcoming';
		try {
//			if (searchResults.listings.count == 0) {
//				if (searchResults.organisations.count > 0) {
//					selectedType = 'organisations';
//				} else if (searchResults.articles.count > 0) {
//					selectedType = 'articles';
//				}
//			}
		}
		catch (e) {}
	}
	else {
		renderListings(searchResults.listings, 'listings_results'); //, 'listings', 'Listings', renderListing);
		renderItemsOfType(searchResults.organisations, 'organisations', 'Organisations', renderOrganisation);

		// If performing a category search, hide the articles tab
		if ($('keyword').value) {
			window.tabsManager.showTab($('tab:articles_results_wpr'));
			renderItemsOfType(searchResults.articles, 'articles', 'Content Articles', renderArticle);
		}
		else {
			window.tabsManager.hideTab($('tab:articles_results_wpr'));
		}

		// Select an appropriate tab
		selectedType = 'listings';
		try {
			if (searchResults.listings.count == 0) {
				if (searchResults.organisations.count > 0) {
					selectedType = 'organisations';
				} else if (searchResults.articles.count > 0) {
					selectedType = 'articles';
				}
			}
		}
		catch (e) {}
	}

	if (!$('itemType').value) {
		window.tabsManager.switchTab($('tab:' + selectedType + '_results_wpr'));

		totalResults = Number(searchResults.listings ? searchResults.listings.count : 0) +
					   Number(searchResults.organisations ? searchResults.organisations.count : 0)+
					   Number(searchResults.articles ? searchResults.articles.count : 0);

		$('results_counts').innerHTML = '<div class="mkt_srch_subheading"> Found ' + totalResults + ' matching items. ' +
										(totalResults ? 'See results below.</div>' : '</div>');

		renderCategories(searchResults.relatedCategories);
	}
}

function renderEvents(listings)
{

//	renderListings(searchResults.listings); //, 'listings', 'Listings', renderListing);

	addResultCount('Upcoming', 0, $('upcoming_results').parentNode.id);
	addResultCount('National', 0, $('national_results').parentNode.id);
	addResultCount('Regular', 0, $('regular_results').parentNode.id);

	if (!listings || !listings.items)
		return false;

	if (!listings.items || !listings.items.length) {
		$('upcoming_results').innerHTML = '<div class="mkt_srch_noresults">No listings were found matching your search criteria.</div>' +
		  								  '<div class="mkt_srch_noresults">Please note: If you are a provider of classes, camps, activites etc, please visit the List With Us page under the Contact Us menu to submit a free listing for your business.</div>';
		return false;
	}

	var results = new Array();
	results["upc"] = "";
	results["nat"] = "";
	results["reg"] = "";
	var prevEnhanced = new Array();
	prevEnhanced["upc"] = false;
	prevEnhanced["nat"] = false;
	prevEnhanced["reg"] = false;
    var suffix = new Array();
    var counts = new Array();
    counts["upc"] = 0;
    counts["nat"] = 0;
    counts["reg"] = 0;

	var srch_region = $('region').value;
	var group;

	for (var i=0; i < listings.items.length; i++) {
        var listing = listings.items[i];
        if (Number(listing.recurring_event)) {
        	group = "reg";
        }
        else if (srch_region > 0 && srch_region != listing.region_id) {
        	group = "nat";
        }
        else {
        	group = "upc";
        }

    	// Output a spacer if moving from enhanced to normal listings
    	var enhanced = Number(listing.enhanced);
    	if (prevEnhanced[group] && !enhanced) {
    		results[group] += '<div class="resultsSeparator"></div>';
    	}
    	prevEnhanced[group] = enhanced;

        suffix[group] = (suffix[group] == "odd") ? 'even' : 'odd';

        results[group] += renderListing(listing, suffix[group]);
        counts[group]++;
	}

	$('upcoming_results').innerHTML += results["upc"];
	$('national_results').innerHTML += results["nat"];
	$('regular_results').innerHTML += results["reg"];

	addResultCount('Upcoming', counts["upc"], $('upcoming_results').parentNode.id);
	if (counts["nat"]) {
		window.tabsManager.showTab($('tab:national_results_wpr'));
		addResultCount('National', counts["nat"], $('national_results').parentNode.id);
	}
	else {
		window.tabsManager.hideTab($('tab:national_results_wpr'));
	}
	if (counts["reg"]) {
		window.tabsManager.showTab($('tab:regular_results_wpr'));
		addResultCount('Regular', counts["reg"], $('regular_results').parentNode.id);
	}
	else {
		window.tabsManager.hideTab($('tab:regular_results_wpr'));
	}
}

function renderSearchCriteria() {

	criteriaHTML = '';

	function _addCriteria(elementId, label, value, canRemove) {
		criteriaHTML +=
			'<tr class="mkt_srch_criteria" id="criteria:' + elementId + '">' +
				'<td class="mkt_srch_criteria_value"><div class="mkt_srch_criteriaLabel">' + label + ':</div>' + value + '</td>' +
		    	'<td width="30px" class="mkt_srch_removeCriteria">';
		if (canRemove) {
			criteriaHTML += '<img class="mkt_srch_criteria_remove" src="/components/com_mykidstime/views/browse/tmpl/redX.png"/>';
		}
		else {
			criteriaHTML += '<img class="mkt_srch_criteria_no_remove" src="/components/com_mykidstime/views/browse/tmpl/greyX.png"/>';
		}
		criteriaHTML += '</td></tr>';
		criteriaHTML += '<tr><td></td></tr>';
	}

	$('search_criteria').innerHTML = '';

	if ($('listing_type').value) {
		var catTrailString = $('cnames').value.split(',').join(" &nbsp;&raquo;&nbsp; ");
		_addCriteria('cid', 'Category', catTrailString, true);
	}

	var keyword = $('keyword').value;
	if (keyword) {
		var wordcount = keyword.split(" ").length;
		if (wordcount > 1) {
			var match = getElementValue($('match')).ucfirst();
			keyword += ' (' + match + ')';
		}
		_addCriteria('keyword', 'Keyword(s)', keyword, true);
	}

	if ($('region').value > 0)
		_addCriteria('region', 'County', getSelectedLabel($('region')), true);

	if ($('location').value > 0)
		_addCriteria('location', 'Location', getSelectedLabel($('location')), true);

	if ($('start_date').value) {
		displayValue = $('start_date').value;
		if ($('listing_type').value == 'Event')
			displayValue += ' (plus ' + EVENT_DATE_RANGE + ' days)';
		_addCriteria('start_date', 'Date', displayValue, false);
	}

	// Wrap the lot...
//	$('search_criteria').innerHTML = '<div class="mkt_srch_subheading"> Searched For: </div><div style="display: inline-block">' + $('search_criteria').innerHTML + '</div>';
	$('search_criteria').innerHTML = '<div id="searchCriteriaWrapper" class="mkt_srch_subheading"> Searched For: </div><div style="display:inline-block"><table cellspacing="0">' + criteriaHTML + '</table></div>';

	$$('.mkt_srch_criteria_remove').each(function (el){el.addEvent('click', removeSearchCriteria);});
}

function addResultCount(resultType, count, tabid) {
	if (!$('itemType').value.length) { // Only update if this is the first search, rather than a 'fetch more' search
//		$('results_counts').innerHTML += "<div class=\"mkt_result_count\"><div>" + count + '</div> ' + resultType + '</div>';
		// Update the tab label to include the number of results found
		$resultsWpr = $(tabid);
		window.tabsManager.updateLabel($resultsWpr.id, $resultsWpr.title + ' (' + count + ')');
	}
}

function renderItemsOfType(resultsForType, itemType, label, renderFunc)
{
	if (!resultsForType || !resultsForType.items) {
		addResultCount(label, 0, itemType + '_results_wpr');
		return false;
	}

	var results = '';
	addResultCount(label, resultsForType.count, itemType + '_results_wpr');
	nextIndex[itemType] = Number(resultsForType.startIndex) + Number(resultsForType.items.length);

	$('more' + itemType.ucfirst()).style.display = (nextIndex[itemType] < resultsForType.count) ? '' : 'none';
	$('more' + itemType.ucfirst()).innerHTML = 'Next ' + Math.min($('count').value, resultsForType.count - nextIndex[itemType] + 1) + ' ' + itemType + '...';

	if (!resultsForType.items || !resultsForType.items.length) {
		$(itemType + '_results').innerHTML = '<div class="mkt_srch_noresults">No ' + itemType + ' were found matching your search criteria.</div>';
		return false;
	}

	for (var i=0; i < resultsForType.items.length; i++) {

    	var item = resultsForType.items[i];

        var suffix = (i % 2) ? 'even' : 'odd';
        results += renderFunc(item, suffix);
	}

	$(itemType + '_results').innerHTML += results;
}

function renderArticle(article, classSuffix) {
	var hostname = window.location.hostname;
	hostname = 'www.' + hostname.substr(hostname.indexOf('mykidstime'));
	var result = '';

	result += '<a href="http://' + hostname + article.href + '">';
    result += '<div class="lst1_row_box_' + classSuffix + ' ' + classSuffix + '">';
    result += '		<div class="mkt_srchres_title">' + article.title + '</div>';
    if (article.thumbnail_image_url)
    	result += '		<div class="mkt_srchres_thumbnail"><img src="' + article.thumbnail_image_url + '"/><div class="mkt_srchres_tn_corners"></div></div>';
    result += '		<table class="mkt_srchres_details">';
   	result += '		<tr class="mkt_srchres_description"><td>' + article.text + '</td></tr>';
    result += '		</table>';
    result += '		<div style="clear:both"></div>';
    result += '		<div style="display:none">' + article.score + '</div>';
    result += '</div>';
    result += '</a>';

	return result;
}

function renderListings(listings, targetDiv)
{
	if (!listings || !listings.items) {
		addResultCount('Listings', 0, 'listings_results_wpr');
		return false;
	}

	var results = '';
	addResultCount('Listings', listings.count, $(targetDiv).parentNode.id);
	nextIndex['listings'] = Number(listings.startIndex) + Number(listings.items.length);

	$('moreListings').style.display = (nextIndex['listings'] < listings.count) ? '' : 'none';
	$('moreListings').innerHTML = 'Next ' + Math.min($('count').value, listings.count - nextIndex['listings'] + 1) + ' listings...';

	if (!listings.items || !listings.items.length) {
		$(targetDiv).innerHTML = '<div class="mkt_srch_noresults">No listings were found matching your search criteria.</div>' +
		  								  '<div class="mkt_srch_noresults">Please note: If you are a provider of classes, camps, activites etc, please visit the List With Us page under the Contact Us menu to submit a free listing for your business.</div>';
		return false;
	}

	var prevEnhanced = false;

	for (var i=0; i < listings.items.length; i++) {

    	var listing = listings.items[i];

    	// Output a spacer if moving from enhanced to normal listings
    	var enhanced = Number(listing.enhanced);
    	if (prevEnhanced && !enhanced) {
    		results += '<div class="resultsSeparator"></div>';
    	}
    	prevEnhanced = enhanced;

        var suffix = (i % 2) ? 'even' : 'odd';
        results += renderListing(listing, suffix);
	}

	$(targetDiv).innerHTML += results;
}

function renderListing(listing, classSuffix) {
	var enhanced = Number(listing.enhanced_article_id);
	var hostname = window.location.hostname;
	hostname = 'www.' + hostname.substr(hostname.indexOf('mykidstime'));
	var result = '';
	var label = listing.name.length ? listing.name : listing.organisation_name;
	var locationInfo = formatLocation(listing);

	if (listing.listing_type == 'event' && !listing.start_date && !listing.time_info)
		listing.time_info = 'See listing for days/times';

    result += '<a href="http://' + hostname + listing.href + '">';
    result += '<div class="lst1_row_box_' + classSuffix + ' mkt_srchres_' + classSuffix + (enhanced ? ' enhanced' : '') + '">';
    result += '	   <div class="mkt_srchres_category">'
    	   +  '        <div class="mkt_related_category">'
    	   +  '            <table><tr><td><a id="' + listing.category_id + '" class="mkt_related_category" href="#">' + categoryMap[listing.category_id].join(' &raquo; ') + '</a></td></tr></table>'
    	   +  '        </div>'
    	   +  '    </div>';
    result += '        <div class="mkt_srchres_title">' + label + '&nbsp;</div>';
	if (listing.schedule_count > 0)
		result += '		<div class="mkt_srchres_bookonline">'
			   +  (listing.listing_type == 'product' ? 'Purchase online!' : 'Book online!')
			   +  '</div>';
    if (listing.thumbnail_image_url) {
    	// Rounded images trick here courtesy of http://maxvoltar.com/archive/rounded-corners-on-images-css-only
    	result += '		    <div class="mkt_srchres_thumbnail listing_thumbnail_wpr" style="background-image: url(' + listing.thumbnail_image_url + ')">';
    	result += '			    <img src="' + listing.thumbnail_image_url + '" alt="Category Image" />';
    	result += '		    </div>';
    }
    result += '		<table class="mkt_srchres_details">';
    result += '			<tr class="mkt_srchres_organisation"><th>Who:</th><td><a href="http://' + hostname + listing.org_href + '">' + listing.organisation_name + '</a></td></tr>';
    if (locationInfo)
        result += '		<tr class="mkt_srchres_location"><th>Where:</th><td>' + locationInfo + '</td></tr>';
    if (listing.start_date || listing.end_date || listing.time_info)
    	result += '		<tr class="mkt_srchres_startdate"><th>When:</th><td>' + formatDateTimeInfo(listing) + '</td></tr>';
    if (enhanced)
    	result += '		<tr class="mkt_srchres_description"><th>What:</th><td>' + listing.description + '</td></tr>';
    result += '		</table>';
    result += '		<div style="clear:both"></div>';
    result += '		<div style="display:none">' + listing.score + '</div>';
    result += '</div></a>';

    return result;
}

function formatLocation(listing)
{
	var result = '';
	loc = listing.location_name;
	reg = listing.region_name;

	if (!reg)
		return null;

	if (loc && loc.length)
		result = loc;

	result += result.length ? ' - ' + reg : reg;

	return result;
}

function formatDateTimeInfo(listing)
{
	var result = '';
	if (listing.start_date) {
		sdate = new Date(listing.start_date.replace(/-/g, '/'));
		result = sdate.format(DISPLAY_DATE_FORMAT);
	}
	if (listing.end_date) {
		edate = new Date(listing.end_date.replace(/-/g, '/'));
		result += (result ? ' - ' : 'until ') + edate.format(DISPLAY_DATE_FORMAT);
	}

	if (listing.time_info) {
		result += (result ? ', ' : '') + listing.time_info;
	}
	return result;
}

function renderOrganisation(org, classSuffix) {

	var enhanced = Number(org.enhanced_article_id);
	var hostname = window.location.hostname;
	hostname = 'www.' + hostname.substr(hostname.indexOf('mykidstime'));
	var result = '';

	result += '<a href="http://' + hostname + org.href + '">';
    result += '<div class="lst1_row_box_' + classSuffix + ' mkt_srchres_' + classSuffix + (enhanced ? ' enhanced' : '') + '">';
    result += '		<div class="mkt_srchres_title">' + org.name + '</div>';
    if (org.thumbnail_image_url) {
    	result += '		<div class="mkt_srchres_thumbnail listing_thumbnail_wpr" style="background-image: url(' + org.thumbnail_image_url + ')">';
    	result += '			<img src="' + org.thumbnail_image_url + '" alt="Category Image" />';
    	result += '		</div>';
    }
    result += '		<table class="mkt_srchres_details">';
    result += '			<tr class="mkt_srchres_location"><th>Where:</th><td>' + formatLocation(org) + '</td></tr>';
    if (org.business_phone || org.mobile_phone)
    	result += '			<tr class="mkt_srchres_contact"><th>How:</th><td>' + (org.business_phone ? org.business_phone : org.mobile_phone) + '</td></tr>';
    if (org.email)
    	result += '			<tr class="mkt_srchres_contact"><th>How:</th><td>' + (org.email) + '</td></tr>';
    if (org.description)
    	result += '		<tr class="mkt_srchres_description"><th>What:</th><td>' + org.description + '</td></tr>';
    result += '		</table>';
    result += '		<div style="clear:both"></div>';
    result += '		<div style="display:none">' + org.score + '</div>';
    result += '</div>';
    result += '</a>';


	return result;
}

function renderCategories(relatedCategories) {
	var result = '';
	for (var id in relatedCategories) {
		var cat = relatedCategories[id];
		result += '<div class="mkt_related_category"><a id="' + id + '" class="mkt_related_category" href="#">' + cat + '</a></div>';
	}

	if (result.length)
		result = '<div class="mkt_srch_subheading">Related Category Suggestions:</div>' + result;

	$('results_suggestions').innerHTML = result;

	$$('a.mkt_related_category').each(function (el) {el.addEvent('click', altCategorySelected);});
}

function removeSearchCriteria(evt) {
	evt = new Event(evt);
	var row = evt.target.parentNode.parentNode;
	var criteria = row.id.substr('criteria:'.length);

	switch (criteria) {
		case 'keyword':
			$('keyword').value = '';
			break;
		case 'region':
			$('region').value = 0;
			regionChanged();
			// break intentionally left out here to ensure the location field is cleared
		case 'location':
			$('location').value = "";
			break;
		case 'cid':
			selectCategory(null, new Array(), true);
			break;
		case 'oid':
			$('oid').value = '';
			break;
		case 'oname':
			$('oname').value = '';
			break;
	}

	$(row).remove();
	// If all criteria removed - clear 'Searched For' text as well as the table
	if (!validateSearchCriteria()) {
		$('results_counts').innerHTML = '<div class="mkt_srch_subheading"> Enter or select one or more search criteria to perform a search</div>';
		collapseFx = new Fx.Style( 'searchCriteriaWrapper', 'opacity', { duration: 1000 } );
		collapseFx.start(1, 0);
		setTimeout("$('search_criteria').innerHTML = ''", 1100);
	}
	else {
		// Still some criteria, schedule another search to happen
		setTimeout("doSearch()", 200);
	}
}

function altCategorySelected(evt) {
	evt = new Event(evt);
	evt.stop();

	catId = evt.target.id;
	catTrail = categoryMap[catId];
	selectCategory(catId, catTrail, true);
	$('keyword').value = '';
	doSearch();
}

function clearListings()
{
	$('listings_results').innerHTML = '';
}


/*
// Event related functions
*/

function evtDateChanged(calendar)
{
	// This function is called even if the end-user only
	// changed the month/year. In order to determine if a date was
	// clicked use the dateClicked property of the calendar:
	if (calendar.dateClicked) {
		// OK, a date was clicked
		search_date = calendar.date;

		key = String(search_date.getFullYear()) + String(search_date.getMonth());
		if (event_dates[key] == null) {
			setTimeout('getEventDates(' + search_date.getFullYear() + ', ' + search_date.getMonth() + ')', 1);
		}

		$('start_date').value = search_date.format('yyyy-mm-dd');
		$('end_date').value = new Date(search_date.getFullYear(), search_date.getMonth(), search_date.getDate() + EVENT_DATE_RANGE).format('yyyy-mm-dd');

		if (!init_search)
			doSearch();
	}

	return true;
}

function evtDateStatus(date, y, m, d) {
	if (dateHasEvent(date.getFullYear(), date.getMonth(), date.getDate())) {
		return "special";
	}
	else
		return false; // other dates are enabled
		// return true if you want to disable other dates
}

function dateHasEvent(y, m, d)
{
	key = String(y) + String(m);
	if (event_dates[key] == null) {
		return false;
	}
	return event_dates[key][d];
}

function getEventDates(y, m)
{
	new Json.Remote('index.php?option=com_mykidstime&task=listings.evtdates&y=' + y + '&m=' + (Number(m) + 1),
			{onComplete: function(response) {processEventDates(y, m, response);}}).send();
}

function processEventDates(y, m, response)
{
	key = String(y) + String(m);
	event_dates[key] = response; //new Array(); //Object();
//	result = event_dates[key];
//
//	regex = /<day\>[0-9]{1,2}\<\/day>/g;
//	arr = response.match(regex);
//
//	$A(arr).each(function(d){result[((/>([0-9]*)</).exec(d))[1]] = true;});

	resetCalendar();

	return true;
}

function formatDateRange(sdate, edate)
{
	if (sdate && edate) {
		sdate = new Date(sdate.replace(/-/g, '/'));
		edate = new Date(edate.replace(/-/g, '/'));
		if (sdate.getMonth() == edate.getMonth()) {
			if (sdate.getDate() == edate.getDate()) {
				return sdate.format('dd mmm');
			}
			return sdate.format('dd') + ' - ' + edate.format('dd mmm');
		}
		else {
			return sdate.format('dd mmm') + ' - ' + edate.format('dd mmm');
		}
	}
	else if (sdate) {
    	return (new Date(sdate.replace(/-/g, '/'))).format('dd mmm');
    }
	else if (edate) {
   		return 'ends ' + (new Date(edate.replace(/-/g, '/'))).format('dd mmm');
    }

    return '';
}

function resetCalendar()
{
	$('evt_calendar').innerHTML = '';

	Calendar.setup(
			{
				flat			: "evt_calendar",
				flatCallback	: evtDateChanged,
			//Temporarily removed the following until find a better solution.
				//dateStatusFunc	: evtDateStatus,
				weekNumbers		: false,
				displayArea		: "evtdate",
				showOthers		: true,
				date		    : search_date,
				daFormat		: "%Y-%m-%d"
				//range			:
			}
		);
}

