/*
 * File: course_search_form.js
 * 
 * @author Paul Osborne, for Kiss Online Marketing.
 * 
 * Course search utility. Uses MVC and Observer patterns. 
 * 
 */

///////////////////////////////////////////////////////////////////////////////
//
// Instances
// 
//
///////////////////////////////////////////////////////////////////////////////

var searchController; 
var searchModel; 
var methodsPanel;
var levelsPanel;
var venuesPanel;
var resultsPanel;

var autoSubmit 		= true; 		// Submit query for each selection (also hides the submit button).

var disableSearch = function() {
	// Disable all checkboxes.
	$('input:checkbox').attr('disabled','true');	
	// Disable search button.
	$('#courseSearchSubmitButton').attr('disabled','true');
	$('#courseSearchSubmitButton').addClass('searchDisabled');
	// Disable cols 2 and 3
	$('#searchStep2').addClass('searchDisabled');
	$('#searchStep3').addClass('searchDisabled');
}
var enableSearch = function() {
	// Disable all checkboxes.
	$('input:checkbox').removeAttr('disabled');	
	$('#courseSearchSubmitButton').removeClass('searchDisabled');
	// Disable search button.
	$('#courseSearchSubmitButton').removeAttr('disabled');	
	// Disable cols 2 and 3
	$('#searchStep2').removeClass('searchDisabled');
	$('#searchStep3').removeClass('searchDisabled');
}

//
// Gets a preselected method, level or venue. The path needs to 
// be of the form: /courses/search/index/mll2v3
// e.g. /courses/search/index/m2   # method=2
// e.g. /courses/search/index/m2l1  # method=2, level=1
// e.g. /courses/search/index/m2v12  # method=2, venue=12
//
var getPreselectedItemFromPath = function(prefix) {
	var pathname 	= document.location.pathname;
	var tokens 		= pathname.split("/");
	var itemId;
	for (var i = 0; i < tokens.length; i++) {
		if (tokens[i] == 'index') {
			var x 	= tokens[i + 1];
			var x2 	= x.match(prefix+"[0-9]+"); 
			if (x2 && x2.length >= 0 ) {
				itemId 	= x2[0].replace(prefix, "");
			}
			break;
		}
	}
	return itemId;
}

///////////////////////////////////////////////////////////////////////////////
//
// Configuration
// 
//
///////////////////////////////////////////////////////////////////////////////

var config = (function() {
    var x = {
        'METHODS_CHANGED':				"mchange",
        'LEVELS_CHANGED':				"lchange",
        'VENUES_CHANGED':				"vchange",
        'RESULTS_CHANGED':				"rchange",
        'SELECTIONS_CHANGED':			"schange",
        'LIST_METHODS_URL':				"/courses/search/listMethods/" + escape("m.order"),  // Use no-parameter or "m.name" to sort by name
        'LIST_LEVELS_URL':				"/courses/search/listLevels",
        'LIST_VENUES_BY_LEVEL_URL':		"/courses/search/listVenuesByLevel",
        'LIST_VENUES_BY_METHOD_URL':	"/courses/search/listVenuesByMethod",
        'LIST_COURSE_INSTANCES_URL':	"/courses/search/listCourseInstances"	
    };
    return {
		get: function(name) { 
		    	return x[name]; 
		}
   };
})();


///////////////////////////////////////////////////////////////////////////////
//
// Controller Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SearchController(m) {

	var model = m;
	
	this.init = function() {
		
		var preselectedMethodId	= getPreselectedItemFromPath("m");
		var preselectedLevelId 	= getPreselectedItemFromPath("l");
		var preselectedVenueId	= getPreselectedItemFromPath("v");
		
		model.init(preselectedMethodId, preselectedLevelId, preselectedVenueId);
		setTimeout("searchController.search()", 500);
	}
	
	this.getModel = function() {
		return model;
	}
	
	this.toggle = function(type, id) {
		if (!type) return;
		if (type == "method") { 
			this.toggleMethod(id);
		} else if (type == "level") {
			this.toggleLevel(id);
		} else if (type == "venue") {
			this.toggleVenue(id);
		}
		if (autoSubmit) { 
			$("#courseSearchSubmitButton").click();
		}
	}
	
	this.toggleMethod = function(methodId) {
		model.toggleMethod(methodId);
	}
	
	this.toggleLevel = function(levelId) {
		model.toggleLevel(levelId);
	}

	this.toggleVenue = function(venueId) {
		model.toggleVenue(venueId);
	}

	this.search = function() {
		model.findCourseInstances();
	}
	
	this.registerObserver = function(key, observer) {
		if (observer) {
			model.addObserver(key, observer);
		}
	}
	
	this.hasMethodSelected = function() {
		return this.getModel().hasMethodSelected();
	}
	
}

///////////////////////////////////////////////////////////////////////////////
//
// SearchModel Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SearchModel() {

	this.methods 				= new SelectableItemGroup();
	this.levels					= new SelectableItemGroup();
	this.venues					= new SelectableItemGroup();
	this.searchResults			= new Array();
	var observers				= new Array();
	this.isInitComplete       	= false;
	
	this.preselectedMethodId;
	this.preselectedLevelId;
	this.preselectedVenueId;
	
	this.init = function(methodId, levelId, venueId) {
		
		this.preselectedMethodId	= methodId ? methodId : 0;
		this.preselectedLevelId		= levelId;
		this.preselectedVenueId		= venueId;
		
		this.findMethods();

//		while(!this.isInitComplete) {
//			setTimeout()
//			this.waitOnInitComplete();
//		}
	}
	
//	this.waitOnInitComplete = function() {
//		this.methods.selectItem("method"+this.preselectedMethodId);
//		this.levels.selectItem("level"+this.preselectedLevelId);
//		this.venues.selectItem("venue"+this.preselectedVenueId);
//		this.isInitComplete =   
//				(!this.preselectedMethodId 
//				|| !this.preselectedMethodId > 0
//				|| this.methods.isSelected("method"+this.preselectedMethodId)
//				)
//				&& 
//				(!this.preselectedLevelId 
//				|| !this.preselectedLevelId > 0 
//				|| this.levels.isSelected("level"+this.preselectedLevelId)
//				)
//				&& 
//				(!this.preselectedVenueId 
//				|| !this.preselectedVenueId > 0 
//				|| this.venues.isSelected("venue"+this.preselectedVenueId)
//				);
//	}	
	
	this.clearPreselected = function() {
		this.preselectedMethodId	= undefined;
		this.preselectedLevelId		= undefined;
		this.preselectedVenueId		= undefined;
	}
	
	this.notifyObservers = function(changeType) {
		for (var i=0; i < observers.length; i++) {
	    	var ob = observers[i];
	        ob.modelChanged(changeType, this);
	    }
	}
	
	this.addObserver = function(key, observer) {
		if (observer) {
			observers.push(observer);
		}
	}
	
	this.setMethodData = function(data) {
		var allMethods		= new Array();
		
		$.each(data.items, function(i,item){
			var m = new SelectableItem("method", "method" + item.itemId, item.name, item.itemId, false);
			m.infoUrl = item.infoUrl;
			if (m.value == searchController.getModel().preselectedMethodId) {
				m.isSelected = true;
			}
			allMethods.push(m);
		});

		var isChanged = this.methods.setItems(allMethods);
		if (isChanged) {
			this.notifyObservers(config.get("METHODS_CHANGED"));
		}
	}
	
	this.setLevelData = function(data) {
		var allLevels		= new Array();
		
		$.each(data.items, function(i,item){
			var m = new SelectableItem("level", "level" + item.itemId, item.name, item.itemId, false);
 			if (m.value == searchController.getModel().preselectedLevelId) {
				m.isSelected = true;
			}
			allLevels.push(m);
		});

		var isChanged = this.levels.setItems(allLevels);
		if (isChanged) {
			this.notifyObservers(config.get("LEVELS_CHANGED"));
		}
	}
	
	this.setVenueData = function(data) {
		var allVenues		= new Array();
		
		$.each(data.items, function(i,item){
			var m = new SelectableItem("venue", "venue" + item.itemId, item.name, item.itemId, false, item.country);			
			if (m.value == searchController.getModel().preselectedVenueId) {
				m.isSelected = true;
			}
			allVenues.push(m);
		});

		var isChanged = this.venues.setItems(allVenues);
		if (isChanged) {
			this.notifyObservers(config.get("VENUES_CHANGED"));
		}
	}
	
	var setCourseInstanceData = function(data) {
		var allCourseInstances = new Array();
		
		$.each(data.schedules, function(i,item){
			
			var instance = new CourseInstance(item);
			allCourseInstances.push(instance);
			
		});

		this.searchResults = allCourseInstances;
		this.notifyObservers(config.get("RESULTS_CHANGED"));
		
	}

	this.findMethods = function() {
		$.getJSON(config.get("LIST_METHODS_URL"), function(data) {
			var m = searchController.getModel();
			m.setMethodData(data);
		});
		this.findLevels();
	}
	
	this.findLevels = function() {
		var selectedMethods = 
			this.preselectedMethodId ? [{value: this.preselectedMethodId}] : this.methods.getSelectedItems(); 
		var query 			= buildUrlQuery(selectedMethods);
		$.getJSON(config.get("LIST_LEVELS_URL") + query, function(data) {
			var m = searchController.getModel();
			m.setLevelData(data);
		});
		this.findVenues();
	}

	this.findVenues = function() {
		var selectedMethods = 
			this.preselectedMethodId ? [{value: this.preselectedMethodId}] : this.methods.getSelectedItems(); 
		var selectedLevels = 
			this.preselectedLevelId ? [{value: this.preselectedLevelId}] : this.levels.getSelectedItems();
		var url;
		var filter;
		if (selectedLevels && selectedLevels.length > 0) {
			url		= config.get("LIST_VENUES_BY_LEVEL_URL");
			filter	= selectedLevels;			
		} else {
			url		= config.get("LIST_VENUES_BY_METHOD_URL");
			filter	= selectedMethods;			
		}		
		
		var query = buildUrlQuery(filter);
		$.getJSON(url + query, function(data) {
			var m = searchController.getModel();
			m.setVenueData(data);
		});
	}

	this.findCourseInstances = function() {
		
		var selectedMethods = 
			this.preselectedMethodId ? [{value: this.preselectedMethodId}] : this.methods.getSelectedItems();
		var methodQuery 	= 
			(selectedMethods && selectedMethods.length > 0) ?
					joinValues(selectedMethods, "/m") : ""; 
		
		var selectedLevels = 
				this.preselectedLevelId ? [{value: this.preselectedLevelId}] : this.levels.getSelectedItems();
		var levelQuery 	= 
			(selectedLevels && selectedLevels.length > 0) ?
					joinValues(selectedLevels, "/l") : ""; 

		var selectedVenues = 
			this.preselectedVenueId ? [{value: this.preselectedVenueId}] : this.venues.getSelectedItems(); 
		var venueQuery 	= 
			(selectedVenues && selectedVenues.length > 0) ?
					joinValues(selectedVenues, "/v") : "";
					
		var query = methodQuery + levelQuery + venueQuery;
		$.getJSON(config.get("LIST_COURSE_INSTANCES_URL") + query, function(data) {
			var m = searchController.getModel();
			setCourseInstanceData.call(m, data);
		});
					
	}
	
	var joinValues = function(valueItems, prefix) {
		var joined = "";
		for (var i = 0; valueItems && i < valueItems.length; i++) {
			joined += prefix + valueItems[i].value;
		}
		return joined;
	}
	
	this.hasMethodSelected = function() {
		var selectedMethods	= this.methods.getSelectedValues();
		return selectedMethods && selectedMethods.length > 0;
	}
	
	this.hasLevelSelected = function() {
		var selectedLevels	= this.levels.getSelectedValues();
		return selectedLevels && selectedLevels.length > 0;
	}

	this.hasVenueSelected = function() {
		var selectedVenues = this.venues.getSelectedValues();
		return selectedVenues && selectedVenues.length > 0;
	}

	var buildUrlQuery = function(items) {
		var q = "/";
		for ( var i = 0; i < items.length; i++) {
			var item = items[i];
			if (item && item.value) { 
				q += items[i].value + "/";
			}
		}
		return q;
	}
	
	this.toggleMethod = function(methodId) {
		this.clearPreselected();
		this.methods.deselectAll();
		this.levels.deselectAll();
		this.venues.deselectAll();
		this.methods.toggleItem(methodId);
		this.findLevels();
		this.notifyObservers(config.get("SELECTIONS_CHANGED"));
	}

	this.toggleLevel = function(levelId) {
		this.clearPreselected();
		this.venues.deselectAll();
		this.notifyObservers(config.get("VENUES_CHANGED"));
		this.levels.toggleItem(levelId);
		this.findVenues();
		this.notifyObservers(config.get("SELECTIONS_CHANGED"));
	}

	this.toggleVenue = function(venueId) {
		this.clearPreselected();
		this.venues.toggleItem(venueId);
		this.notifyObservers(config.get("SELECTIONS_CHANGED"));
	}

}

///////////////////////////////////////////////////////////////////////////////
//
// SelectableItemGroup Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SelectableItemGroup() {

	this.allItems		= new Array();	// Selected and non-selected items.
	this.stateHash		= '';			// Hash of current state e.g. 1210121231348. Used to detect changes in state.

	this.setItems = function(items) {	
		
		var isChanged = false;
		
		if (!items || !(items instanceof Array)) {
			return isChanged;
		}
		
		// Make sure the data has changed...
		var newStateHash 	= getStateHash(items);
		if (newStateHash != this.stateHash) {

			this.allItems 		= new Array();
			for ( var i = 0; i < items.length; i++) {
				var anItem = items[i];
				this.allItems.push(anItem);
			}
			
			// Store the new hash.
			this.stateHash = newStateHash;
			
			isChanged = true;
		}
		
		return isChanged;
	}

	this.toggleItem = function(id) {
		var item = this.getItemById(id);
		if (item) {
			item.isSelected = !item.isSelected;
		}
		return this.updateHash();
	}
	
	this.selectItem = function(id) {
		if (!id) return false;
		var item = this.getItemById(id);
		if (item) {
			item.isSelected = true;
		}
		return this.updateHash();
	}

	this.isSelected = function(id) {
		var item = this.getItemById(id);
		if (item) {
			return item.isSelected;
		}
		return false;
	}
	
	this.deselectAll = function() {
		var selectedItems = new Array();
		for ( var i = 0; i < this.allItems.length; i++) {
			var item = this.allItems[i];
			item.isSelected = false;
		}
		return this.updateHash();
	}
	
	this.updateHash = function() {
		var updatedHash	= getStateHash(this.allItems);
		var isChanged 	= this.stateHash != updatedHash;
		this.stateHash 	= updatedHash;
		return isChanged;
	}
	
	this.getItemById = function(id) {
		if (!id) return;
		for ( var i = 0; i < this.allItems.length; i++) {
			var item = this.allItems[i];
			if (item.id == id) {
				return item;
			}
		}
	}
	
	this.getSelectedItems = function() {
		var selectedItems = new Array();
		for ( var i = 0; i < this.allItems.length; i++) {
			var item = this.allItems[i];
			if (item.isSelected) {
				selectedItems.push(item);
			}
		}
		return selectedItems;
	}
	
	this.getSelectedValues = function() {
		var selectedValues = new Array();
		for ( var i = 0; i < this.allItems.length; i++) {
			var item = this.allItems[i];
			if (item.isSelected) {
				selectedValues.push(item.value);
			}
		}
		return selectedValues;
	}
	
	var getStateHash = function(someItems) {
		if (!someItems instanceof Array) {
			return;
		}
		var hash = "";
		for (var i = 0;  i < someItems.length; i++) {
			var item = someItems[i];
			hash += item.value;
			if (item.isSelected) {
				hash += "x";
			}
		}
		return hash;
	}
	
}

///////////////////////////////////////////////////////////////////////////////
//
// SelectableItem Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SelectableItem(type, id, name, value, isSelected, group) {
	this.type		= type;
	this.id			= id;
	this.name		= name;
	this.value		= value;
	this.isSelected	= isSelected;
	this.group		= group;
	this.infoUrl;
}

///////////////////////////////////////////////////////////////////////////////
//
// SearchPanel Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SearchPanel(elementId) {

	this.id 						= elementId;
	this.name						= elementId;
	this.element					= $("#" + elementId);
	this.isMultipleSelectAllowed	= false;
	
	// Default behaviour to be overwritten
	this.modelChanged = function(changeType, model, build) {
	}

	this.update = function(html) {

		var oldElement = $("#"+elementId+" > *");
		oldElement.hide();
		oldElement.replaceWith(html)

		var newElement = $("#"+elementId+" > *");
		newElement.hide();
		newElement.fadeIn("slow");
		
	}
	
	this.append = function(html) {

		var oldElement = $("#"+elementId+" > *");
		oldElement.append(html)
		
	}
		
}

///////////////////////////////////////////////////////////////////////////////
//
// SelectablePanel Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function SelectablePanel(elementId, isMultipleSelectAllowed) {

	this.prototype 					= new SearchPanel(elementId);  // extends SearchPanel
	this.isMultipleSelectAllowed	= isMultipleSelectAllowed;
	
	// Default behaviour to be overwritten
	this.modelChanged = function(changeType, model) {
		return this.prototype.modelChanged(changeType, model);
	}

	this.update = function(html) {
		this.prototype.update(html);
	}

	this.append = function(html) {
		this.prototype.append(html);
	}

	this.build = function(itemGroup) {

		if (!itemGroup) {
			return;
		}
		
		var items 	= itemGroup.allItems;
		var html 	= "<ul class='searchPanelList'>";
		for ( var i = 0; i < items.length; i++) {
			
			var item		= items[i];
			var id   		= item.id;
			var type		= item.type;
			var value		= item.value;
			var text		= item.name;
			var checked		= item.isSelected ? "checked='checked'" : "";
			var formType	= this.isMultipleSelectAllowed ? "checkbox" : "radio";
			var onclick		= "searchController.toggle('" + type +"','"+ id +"');";
			
			html += "<li><input type='"+formType+"' name='"+type+"' id='"+id+"' value='"+value+"' "+checked+" onclick=\""+onclick+"\" ><label for='"+id+"'>"+text+"</label></input></li>";
			
		}
		html += "</ul>";

		this.update(html);
	}

	//
	//Override: Use JQueryUI Accordion rather than simple checkbox list. 
	//
	this.buildAccordion = function(itemGroup) {

		if (!itemGroup) {
			return;
		}
		
		var group = "";
		
		var items 	= itemGroup.allItems;
		var html 	= "<div id=\"accordion\" >";
		for ( var i = 0; i < items.length; i++) {

			var item		= items[i];
			
			// Check for a new group...
			if (group != item.group) {
				if (group != "") { 
					html += "</ul>";
				}
				group = item.group;
				html += "<h3 class='accordionHeader'><a href=\"#\">"+group+"</a></h3>";
				html += "<ul class='searchPanelList'>";
			}

			
			var id   		= item.id;
			var type		= item.type;
			var value		= item.value;
			var text		= item.name;
			var checked		= item.isSelected ? "checked=true" : "";
			var formType	= this.isMultipleSelectAllowed ? "checkbox" : "radio";
			var onclick		= "searchController.toggle('" + type +"','"+ id +"')";
			
			html += "<li><input type='"+formType+"' name='"+type+"' id='"+id+"' value='"+value+"' "+checked+" onclick=\""+onclick+"\" /><label for='"+id+"'>"+text+"</label></input></li>";
			
		}
		html += "</ul>";
		html += "</div>";
			
		this.update(html);
		
	}	

}

///////////////////////////////////////////////////////////////////////////////
//
// Levels Panel (A SelectablePanel with a footer containing a comparison link).
// 
//
///////////////////////////////////////////////////////////////////////////////

function LevelSelectPanel(elementId, isMultipleSelectAllowed) {

	this.prototype = new SelectablePanel(elementId, isMultipleSelectAllowed);  // extends SelectablePanel

	this.build = function(itemGroup) {
		
		this.prototype.build(itemGroup);
		
		var myModel			= searchController.getModel();
		var selectedMethod	= myModel.methods.getSelectedItems()[0];
		var infoUrl			= selectedMethod ? selectedMethod.infoUrl : null;
		
		if (myModel && myModel.hasMethodSelected() && infoUrl ) {
			var html 	=	"<div id=\"comparisonLinkContainer\">";
			html		+=	"<a id=\"comparisonLink\" class=\"iframe\" href=\""+infoUrl+"\">Unsure which level to choose?</a>";
			html		+=	"</div><!-- end comparisonLinkContainer -->";
			this.prototype.append(html);
		}
		
		$("#comparisonLink").fancybox({
			'padding'			: 0,
			'margin'			: 0,
			'autoscale'			: 'false',
			'height'			: 550,
			'width'				: 800,
			'modal'				: false,
			'type'				: 'iframe',
			'scrolling'			: 'auto',
			'centerOnScroll'	: 'true'
		});	
		
	}

}

///////////////////////////////////////////////////////////////////////////////
//
// SelectablePanel Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function ResultsPanel(elementId) {

	this.prototype = new SearchPanel(elementId);	  // extends SearchPanel

	// Default behaviour to be overwritten
	this.modelChanged = function(changeType, model) {
		return this.prototype.modelChanged(changeType, model);
	}
	
	this.build = function(model) {
		var selectedMethods = model.methods.getSelectedItems();
		var method;
		
		if (selectedMethods && selectedMethods.length == 1) {
			method = selectedMethods[0];
		} 
		
		if (!method) {
			return;
		}
			
		var html	= "<div>";

		html += "<table id=\"resultsTable\" class='coursesTable' cellpadding='0' cellspacing='0'>";

		html += "<thead>";
		html += "<tr><th class=\"resultMethodTitle\" colspan=\"6\">" + method.name + "</th></th>";
		html += "<tr>";
		html += "<th class=\"dateCol\">Date</th>";
		html += "<th class=\"locationCol\">Location</th>";
		html += "<th class=\"levelCol\">Course level</th>";
		html += "<th class=\"priceCol\">Price</th>";
		html += "<th class=\"basePriceCol\">&nbsp;</th>";
		html += "<th class=\"actionsCol\">&nbsp</th>";
		html += "</tr>";
		html += "</thead>"; 

		html += "<tbody>"; 
		var courses = model.searchResults;
		for ( var i = 0; i < courses.length; i++) {
			var course 		= courses[i];
			var altStyle 	= (i%2 == 0) ? "oddRow" : "evenRow";
			var saleStyle	= course.isSale() ? "sale" : "";
			html += "<tr class=\""+altStyle+"\">";
			html += "<td class=\"dateCol "+altStyle+"\">"+course.startDate+"</td>";
			html += "<td class=\"locationCol "+altStyle+"\">"+course.venueName+"</td>";
			html += "<td class=\"levelCol "+altStyle+"\">"+course.name.substring(method.name.length)+"</td>";
			html += "<td class=\"priceCol "+altStyle+" "+saleStyle+"\">"+course.getFormattedPrice()+"</td>";
			html += "<td class=\"basePriceCol "+altStyle+" "+saleStyle+"\"><span>"+course.getFormattedBasePrice()+"<span></td>";
			html += "<td class=\"actionsCol "+altStyle+"\"><a class=\"bookNowButton\" href=\"/courses/bookings/create/"+course.scheduleId+"\" ><!--- --></a></td>";
			html += "</tr>";
		} 
		html += "</tbody>"; 
		
		html += "</table>";
		html += "</div>";
		
		this.prototype.update(html);
	}
	
}

///////////////////////////////////////////////////////////////////////////////
//
// CourseInstance Class
// 
//
///////////////////////////////////////////////////////////////////////////////

function CourseInstance(data) {
	this.courseId 			= data.courseId;
	this.courseName			= data.courseName;
	this.currency			= data.currency;
	this.isAccommIncluded	= data.isAccommIncluded;
	this.isBookingAllowed	= data.isBookingAllowed;
	this.isGuaranteed		= data.isGuaranteed;
	this.language			= data.language;
	this.name				= data.name;
	this.price				= data.price;
	this.salePrice			= data.salePrice;
	this.scheduleId			= data.scheduleId;
	this.startDate			= data.startDate;
	this.venueId			= data.venueId;
	this.venueName			= data.venueName;
	
	this.getFormattedPrice = function() {
		var p = this.isSale() ? this.salePrice : this.price;
		return decoratePriceWithCurrency(p, this.currency, 0);
	}
	
	this.getFormattedBasePrice = function() {
		return decoratePriceWithCurrency(this.price, this.currency, 0);
	}
	
	this.getFormattedSalePrice = function() {
		return decoratePriceWithCurrency(this.salePrice, this.currency, 0);
	}
	
	this.isSale = function() {
		return this.salePrice && this.salePrice > 0;
	}

	var decoratePriceWithCurrency = function(n, currency, decimalPlaces) {
		if (!n) return "&nbsp;";
		
		n = parseFloat(n);
		var p = n.toFixed(decimalPlaces);
		if (currency) {
			if (currency == "GBP") {
				p = "&pound;" + p; 
			} else if (currency == "EUR") { 
				p = "&euro;" + p; 
			} else if (currency == "USD") {
				p = "&#36;" + p;
			} else {
				p = p + "" + currency; 
			}
		}
		
		return p;
		
	}
		
}

///////////////////////////////////////////////////////////////////////////////
//
// On ready. Script entry point.
// 
//
///////////////////////////////////////////////////////////////////////////////
$(document).ready(function() {

	searchModel			= new SearchModel();
	searchController 	= new SearchController(searchModel);
	methodsPanel		= new SelectablePanel("selectMethodPanel", false);
	levelsPanel			= new LevelSelectPanel("selectLevelPanel", true);
	venuesPanel			= new SelectablePanel("selectVenuePanel", true);
	resultsPanel		= new ResultsPanel("courseSearchResultsPanel");

	if (autoSubmit) {
		$("#courseSearchActionsPanel").hide();
	} else { 
		$("#courseSearchActionsPanel").show();
	}
	
	methodsPanel.modelChanged = function(changeType, model) {
		if (changeType == config.get("METHODS_CHANGED")) {
			methodsPanel.build(model.methods);
		}
	}
		
	levelsPanel.modelChanged = function(changeType, model) {
		if (
				changeType		== config.get("METHODS_CHANGED") 
				|| changeType	== config.get("LEVELS_CHANGED")
			) {
			levelsPanel.build(model.levels);
		}
	}

	venuesPanel.modelChanged = function(changeType, model) {
		if (
				changeType 		== config.get("METHODS_CHANGED")
				|| changeType 	== config.get("LEVELS_CHANGED")
				|| changeType 	== config.get("VENUES_CHANGED")
			) {
			venuesPanel.buildAccordion(model.venues);
			$("#accordion").accordion();
		}
	}

	resultsPanel.modelChanged = function(changeType, model) {
		if (changeType == config.get("RESULTS_CHANGED")) {
			resultsPanel.build(model);
		}

		if (!searchController.getModel().hasMethodSelected()) {
			disableSearch();
		} else {
			enableSearch();
		}		
	}	
	
	searchController.registerObserver("methodsPanel",	methodsPanel);
	searchController.registerObserver("levelsPanel",	levelsPanel);
	searchController.registerObserver("venuesPanel",	venuesPanel);
	searchController.registerObserver("resultsPanel",	resultsPanel);
	
	searchController.init();
	
});


