// Initialize filter class settings
function filter() {
	// built-in object for category list
	this.dataSource = new Object();
	this.xml = new Object();
	this.filterSettings = new Array();
	this.listingSettings = new Array();
	this.serverPath = '';
	this.parameters = '';
	this.type = 'filter';
	this.prefix = '';
	this.initialized = 0;
	this.showListing = true;
}

// Show or hide listing
filter.prototype.showFilterListing = function(show) {
	if (show) {
		this.showListing = true;
	} else {
		this.showListing = false;
	}
}

// Returns true if the passed value is found in the array.
// Returns false if it is not
filter.prototype.inArray = function(value) {
	var i;
	for (i=0; i < this.length; i++) {
		// Matches identical (===), not just similar (==).
		if (this[i] === value) {
			return true;
		}
	}
	return false;
};

// Reset all cookies belong to this board
filter.prototype.reset = function() {
	/*
	// Unused code
	for (i = 0; i < this.controls.length; i++) {
		name = this.prefix + '_' + this.controls[0];
		this.deleteCookie(name);
	}
	*/
};

// Set cookie
filter.prototype.setCookie = function(name, value) {
    var cookieString = name + "=" + escape(value) + ";path=/";
    document.cookie = cookieString;
};

// Get cookie
filter.prototype.getCookie = function(name) {
    if (!name) return '';
    
    var rawCookies, tmp, i;
    var cookies = new Array();
    
    rawCookies = document.cookie.split('; ');
    for (i=0; i < rawCookies.length; i++) {
        tmp = rawCookies[i].split('=');
        cookies[tmp[0]] = unescape(tmp[1]);
    }

    if (cookies[name] != null) {
        return cookies[name];
    } else {
        return '';
    }
};

// Delete cookie
filter.prototype.deleteCookie = function(name) {
	var date = new Date(2000, 1, 1);
	document.cookie = name + "=;expires= " + date.toGMTString() +  "; "  +  "; ";
};

// Sleeping...
filter.prototype.sleep = function(napTime){
	var sleeping = true;
	var now = new Date();
	var alarm;
	var startingMSeconds = now.getTime();
	while(sleeping){
		alarm = new Date();
		alarmMSeconds = alarm.getTime();
		if(alarmMSeconds - startingMSeconds > napTime) {
			sleeping = false;
		}
  	}
};

// Init data source for Filter
filter.prototype.initDataSource = function(xml) {
	// Load XML object
	this.xml = xml;
	
	// Init data source for catogory list
	for (var type in this.filterSettings) {
		xmlNodeName = this.filterSettings[type]['xmlNodeName'];
		this.initCategoryListData(xmlNodeName, type);
	}
};

// Init data source for category list
filter.prototype.initCategoryListData = function(nodeName, type) {
	if (1 != this.initialized) {
		this.dataSource[type] = new Object();
	}
	
	// Init data source for filter conditions
	var filter = this;
	$(nodeName, this.xml).each(function() {
		// Get the category list id and name
		var category = $(this).attr('id');
		var name = $(this).attr('name');
		name += ':';
		//alert(category);
		
		// Check if the list was initialized already
		var selectedIndex = '';
		if (1 == filter.initialized) {
			selectedIndex = filter.dataSource[type][category].selectedIndex;
		}
		
		filter.dataSource[type][category] = new Object();
		filter.dataSource[type][category].selectedIndex = selectedIndex;
		//alert(filter.dataSource[type][category].selectedIndex);
		
		// The first element
		filter.dataSource[type][category]['null'] = new Object();
		filter.dataSource[type][category]['null'].value = '';
		filter.dataSource[type][category]['null'].text = name;
		filter.dataSource[type][category]['null'].count = -1;
			
		// Add items to category list data source
		$("item", this).each(function() {
			var itemValue = $('value', this).text();
			filter.dataSource[type][category][itemValue] = new Object();
			filter.dataSource[type][category][itemValue].value = $("value", this).text();
			filter.dataSource[type][category][itemValue].text = $("text", this).text();
			filter.dataSource[type][category][itemValue].count = $("count", this).text();
		});
		
		// Set the selected index for category
		filter.dataSource[type][category].selectedIndex = selectedIndex;
	});	
};

// Populate category list by using data source
filter.prototype.populateCategoriesList = function(type) {
	// Hide loading icon...
	var loadingContainer = this.filterSettings[type]['loadingContainer'];
	if ('' != loadingContainer && 'undefined' != typeof(loadingContainer)) {
		$(loadingContainer).hide();
	}
	
	// Construct the container name
	var containerID = this.filterSettings[type]['container'];
	//alert(type + '|' + containerID + '|');
	var container = $(containerID)[0];
	
	// Check if the filter form has been initialized
	if (1 != this.initialized) {
		container = this.initContainer(container);
		
		// Check if we need to add text box
		if ('search' == type) {
			this.addControlToForm(container, 'input', 'keyword', 'textBox');
		}
	} else if ('search' == type) {
		// The category list already initialized
		return;
	}

	// Loop to show object's value
	for (var category in this.dataSource[type]) {
		var listID = '#' + category;
		var object = '';
		
		// Check if the filter form has been initialized
		if (1 != this.initialized) {
			this.addControlToForm(container, 'select', category, '');
		} else {
			// Remove all items form this dropdown list
			object = $(listID)[0];
			this.removeAllListItems(object);
		}

		// Create category list
		object = $(listID)[0];
		for (var item in this.dataSource[type][category]) {
			//alert(item);
			if ('selectedIndex' != item) {
				value = this.dataSource[type][category][item].value;
				text = this.dataSource[type][category][item].text;
				count = this.dataSource[type][category][item].count;
				this.addListItem(object, value, text, count);
			}
		}
		
		// If user reset the form, clear all selected indexies
		if ('null' == this.parameters || '' == this.parameters) {
			this.dataSource[type][category].selectedIndex = '';
		}
			
		// Set the default value
		object.value = this.dataSource[type][category].selectedIndex;
	}
};
	
// Remove all list items from category list
filter.prototype.removeAllListItems = function(object) {
	while(object.length > 0) {
		object.remove(0);
	}
};

// Add item to category list
filter.prototype.addControlToForm = function(container, ctrlType, ctrlID, cssClass) {
	// Create a LI element to wrap list control
	element = document.createElement("li");
	container = container.appendChild(element);
	
	// Construct the category list name
	var ctrl = document.createElement(ctrlType);
	ctrl.id = ctrlID;
	ctrl.name = ctrlID;
	
	// Add css class name for text box
	if ('' != cssClass && 'undefined' != typeof(cssClass)) {
		ctrl.className = 'textBox';
	}
	
	container.appendChild(ctrl);
};

//Add item to category list
filter.prototype.initContainer = function(container) {
	// Append an ol element to container
	element = document.createElement("ol");
	container = container.appendChild(element);
	list = container;
	return list;
};

// Add item to category list
filter.prototype.addListItem = function(object, value, text, count) {
	// Create a new option for dropdown list
	var item =document.createElement('option');
	item.value = value;
	if (-1 != count) {
		item.text = text + ' (' + count + ')';
		
		// Disable items with 0
		// Only do this on jobs (filter results) page
		if (0 == count && this.showListing) {
			item.disabled = true;
		}
	} else {
		item.text = text;
	}	

	// Add items to object
	try { 
		// standards compliant
		object.add(item, null); 
	} catch(ex) {
		// IE only
		object.add(item); 
	}
};

// Populate the listing includes listing body, paginator, counter etc.
filter.prototype.populateListing = function() {
	var filter = this;
	var counterContainer = this.listingSettings['counterContainer'];
	
	// Show total items count
	var counter = $("counter", this.xml).text();
	var note = $("note", this.xml).text();
	if ('' == counter) {
		counter = '0';
	}
	
	if ('' != counterContainer && 'undefined' != typeof(counterContainer)) {
		$(counterContainer).html(note);
		
		var headCounterContainer = this.listingSettings['headCounterContainer'];
		$(headCounterContainer).html("(" + counter + ")");
		
		if (!this.showListing) {
			return;
		}
	}
	
	var listingContainer = this.listingSettings['listingContainer'];
	var paginatorContainer = this.listingSettings['paginatorContainer'];
	var listingTable = this.listingSettings['listingTable'];
	var listingBaseLink = this.listingSettings['listingBaseLink'];
	var listingType = this.listingSettings['listingType'];
	var viewingContainer = this.listingSettings['viewingContainer'];
	
	// Hide loading icon...
	var loadingContainer = this.listingSettings['loadingContainer'];
	if ('' != loadingContainer && 'undefined' != typeof(loadingContainer)) {
		$(loadingContainer).hide();
	}
	
	// Take user to the top of the page
	// window.location.href = '#';
	
	// Get Item ID set
	// TODO
	
	// Populate search results listing...
	var html = '';
	if ('div' == listingType) {
		if (counter > 0) {
			// Construct page listing
			var classList =new Array("title", "detail industry", "detail functionalarea", "detail location", "detail", "detail", "detail action", "preview","rawTitle");
			
			html = '';
			var columnList = Array();
			var index = 1;
			$("columns > column", this.xml).each(function() {
				columnList[index] = $(this).text();
				index++;
			});
			
			var prefix = $("prefix", this.xml).text();
			var no = $("no", this.xml).text();
			$("items > item", this.xml).each(function() {
				no++;
				var id = $(this).attr('id');				
				var url = $(this).attr('url');
				var linkHref = listingBaseLink + url;
				
				// TODO: Check the attribute to decide when we need to show link
				var index = 0;
				html += '<div class="row">';
				$("value", this).each(function() {
					if (0 == index) {
						var name = id + "/" + no + "/" + counter;						
						var itemLink = '<h3><a name="' + name + '" href="' + linkHref + '"><span>' + no + ". " + $(this).text() + '</span></a></h3>';
						html += '<div class="' + classList[index] + '">' + itemLink + '</div>';
					} else if (4 == index) {
						// Commented out temporarily
						// var emailHref = listingBaseLink + "index/type/refer/id/" + id;
						var emailHref = listingBaseLink + url + "-email-friend";						
						var emailLink = '<a class="emailToFriend thickbox" href="' + emailHref + '">' + columnList[index] + '</a>';
						
						// Show 'Add to shortlist' or 'Remove from shortlist' link
						index++;
						var shortlistLink = '<a id="' + id + '" class="addToShortlist thickbox" href="javascript:void(0)">' + columnList[index] + '</a>';
						index++;
						var inShortlist = false;
						$("#shortlist ol li").each(function(){
							if($(this).attr("jobid") == id){
								inShortlist = true;
							}
						});
						
						if (inShortlist) {
							shortlistLink = '<a id="' + id + '" class="removeToShortlist thickbox" href="javascript:void(0)">' + columnList[index] + '</a>';
						}
						
						html += '<div class="' + classList[index] + '">' + emailLink + '<br/>' + shortlistLink + '</div>';
					} else if (7 == index) {
						var viewMoreLink = ' <a class="moreInfo" href="' + linkHref + '">' + columnList[index] + '</a>';
						html += '<div class="' + classList[index] + '">' + $(this).text() + viewMoreLink + '</div>';
					} else if(8== index){
						html += '<div class="' + classList[index] + '" style="display:none"><span>' + $(this).text() + '</span></div>';
					} else {
						html += '<div class="' + classList[index] + '">' + columnList[index] + ':<br/><span style="font-weight: normal">' + $(this).text() + '</span></div>';
					}
					index++;
				});
				html += '</div>';
			});
			
			// Construct the paginator
			var paginator = $("paginator", this.xml).text();
			var viewing = $("viewing", this.xml).text();
			var idset = $("idset", this.xml).text();
			filter.setCookie("idset", idset);
			filter.setCookie("total", counter);
			
		} else {
			var error = $("error", this.xml).text();
			html += "<div>" + error + "</div>";
			var paginator = '';			
		}
	} else {	
		// Construct item listing
		html = '<table id="table" class="tablesorter" border="0" cellpadding="0" cellspacing="1">'; 
		if (counter > 0) {
			// Construct table header
			html += "<thead><tr>";
			$("column", this.xml).each(function() {
				// For the first column only
				// TODO: Check the attribute of the first column
				isFirst = 0;
				if (isFirst){ 
					html += '<th class=\"header headerSortDown\">' + $(this).text() + '</th>';
				} else {
					html += '<th>' + $(this).text() + '</th>';
				}
			});
			html += '</tr></thead>';
			
			// Construct table body
			html += '<tbody>';
			$("items > item", this.xml).each(function() {
				html += '<tr>';
				
				var id = $("id", this).text();
				var linkHref = listingBaseLink + id;
				
				// TODO: Check the attribute to decide when we need to show link
				var itemLink = '<a href="' + linkHref + '">' + $("title", this).text() + '</a>';
				$("value", this).each(function() {
					html += '<td>' + $(this).text() + '</td>';
				});
				html += '</tr>';
			});
			html += '</tbody>';
			
			// Construct the paginator
			var paginator = $("paginator", this.xml).text();
		} else {
			var error = $("error", this.xml).text();
			html += "<tr><td>" + error + "</tr></td>";
			var paginator = '';
		}
		html += '</table>';
	}
	
	// Update listing
	$(listingContainer).html(html);
	
	// classList[index]
	$(".title h3 a").click(function(e) {
		var name = $(this).attr("name");
		name = name.replace(/0/g, "");
		var pos = name.indexOf("/");
		var key = name.substr(0, pos);
		var value = name.substr(pos + 1);
		filter.setCookie(key, value);
	});
	
	$(paginatorContainer).html(paginator);
	
    $(".addToShortlist").click(function(e) {
    	e.preventDefault();
    	addToshorlistByObject(this);
    });
    $(".removeToShortlist").click(function(e) {
    	e.preventDefault();
    	removeShorlistByObject(this);
    });
    
	if ("" != viewingContainer) {
		$(viewingContainer).html(viewing);
	}
	
	$(listingTable).tablesorter({
		// Striping looking
		widgets: ['zebra']	
	});
};

// Handle Filter response
filter.prototype.handleResponse = function() {
	// Populate categories list in filter and/or search form
	for (var type in this.filterSettings) {
		this.populateCategoriesList(type);
	}
	
	// Populate the listing includes listing body, paginator, counter etc.
	this.populateListing();
	
	// Register events
	this.registerEvents();
};

// Register event
filter.prototype.registerEvents = function() {
	var filter = this;
	
	// Always rigister click event
	// add markup to container and apply click handlers to anchors
	var paginatorLink = this.listingSettings['paginatorLink'];
	
	if (this.showListing && '' != paginatorLink && 'undefined' != typeof(paginatorLink)) {
		$(paginatorLink).click(function(e){
			//e.preventDefault();
			
			var page = $(this)[0].name;
			filter.setCookie("page", page);
			
			// Construct parameters and referesh overview listing
			// TODO
			var type = filter.type;
			var selectControl = filter.filterSettings[type]['selectControl'];
			//alert(type + ' : ' + selectControl);
			parameters = filter.consturctParameters(selectControl);
			
			// Attach keyword if type is 'search'
			if ('search' == type) {
				var keyword = filter.filterSettings[type]['keywordControl'];
				parameters += $(keyword)[0].id + ':' + $(keyword)[0].value + ';';
			}
			
			// attach page as necessary
			if ('' != page && 'undefined' != typeof(page)) {
				parameters += 'page:' + page;
			}
			
			filter.parameters = parameters;
			filter.initOverviewListing();
		});	
	}
	
	// Avoid to register one event more than one times
	if (this.initialized) {
		return;
	}
	
	// For filter form
	var resetControl = filter.filterSettings['filter']['resetControl'];
	var selectControl = filter.filterSettings['filter']['selectControl'];
	
	// Dropdown list change event
	$(selectControl).change(function(e) {
		e.preventDefault();
		var type = 'filter';
		
		// Get control Id and update it to Datasource
		var ctrlHandle = e.srcElement ? e.srcElement : e.target;
		var ctrlID = ctrlHandle.id;
		var selectedIndex = ctrlHandle.value;
		var count = filter.dataSource[type][ctrlID][selectedIndex].count;
		
		// This is a temp solution, we can use ctrl prfix (in Control ID) to fix this issue
		
		// Check if we need to refresh listing
		// If not, just exit this function
		// TODO
		
		filter.dataSource[type][ctrlID].selectedIndex = selectedIndex;
		
		// Construct parameters and referesh overview listing
		var selectControl = filter.filterSettings[type]['selectControl'];
		filter.type = type;
		
		if (0 == count) {
			parameters = ctrlID + ':' + selectedIndex + ';';
			
			// Reset other controls value because the item with 0 was clicked
			$(selectControl).each(function() {
				$(this)[0].selectedIndex  = 0;
				filter.dataSource[type][$(this)[0].id].selectedIndex = "";
			 });			
		} else {
			//filter.setCookie('parameters','Industry:;FunctionArea:;City:;page:1');
			parameters = filter.consturctParameters(selectControl);
			parameters = parameters +"page:1";
		}
		
		filter.parameters = parameters;
		
		filter.initOverviewListing();
		
		// Save browser based cookies
		// TODO
		
		// Show Reset button
		$(resetControl).show();
	});	

	// Reset event
	$(resetControl).click(function(e) {
		e.preventDefault();
		filter.resetOverviewListing(resetControl);
		filter.reset();
	});	
	
	// Submit event
	type = 'search';
	if ('undefined' != typeof(filter.filterSettings[type])) {
		var submitControl = filter.filterSettings[type]['submitControl'];
		var resetControlEx = filter.filterSettings[type]['resetControl'];
		$(submitControl).click(function(e) {
			e.preventDefault();
			
			// Search overview listing
			var selectControl = filter.filterSettings[type]['selectControl'];
			filter.type = type;
			parameters = filter.consturctParameters(selectControl);
			
			// Attach keyword
			var keyword = filter.filterSettings[type]['keywordControl'];
			parameters += $(keyword)[0].id + ':' + $(keyword)[0].value + ';';
			filter.parameters = parameters;
			//alert(parameters);
			filter.initOverviewListing();
			
			// Show Reset button
			$(resetControlEx).show();
		});
		
		// Reset event
		var formControl = filterSettings[type]['formControl'];
		$(resetControlEx).click(function(e) {
			e.preventDefault();
			filter.resetOverviewListing(resetControlEx);
			$(formControl)[0].reset();
		});
	}
};

// Construct parameters
filter.prototype.consturctParameters = function(selectControl) {
	var parameters = '';
	
	$(selectControl).each(function() {
		 parameters += $(this)[0].id + ':' + $(this)[0].value + ';';		 
	 });
	return parameters;
};

//Init filter settings
filter.prototype.initFilterSettings = function(filterSettings) {
	this.filterSettings = filterSettings;
};

// Init listing settings
filter.prototype.initListingSettings = function(listingSettings) {
	this.listingSettings = listingSettings;
};

// Init server path and parameters
filter.prototype.initAJAXSettings = function(ajaxSettings) {
	this.serverPath = ajaxSettings['serverPath'];
	this.parameters = ajaxSettings['parameters'];
};

// Init cookie settings
filter.prototype.initCookieSettings = function(cookiePrefix) {
	this.prefix = cookiePrefix;
};

// Reset overview page settings
filter.prototype.resetOverviewListing = function(resetControl) {
	// Reset overview listing
	filter.parameters = 'null';
	filter.initOverviewListing();
	
	// Hide Reset button
	$(resetControl).hide();	
};

// Init overview page settings
filter.prototype.initOverviewListing = function() {
	// Show loading icon...
	var loadingContainer = this.listingSettings['loadingContainer'];
	
	if (this.showListing && '' != loadingContainer && 'undefined' != typeof(loadingContainer)) {
		$(loadingContainer).show();
		
		// Show the mask layer
		var board = $(".listing");
		var offset = board.offset();
		$(loadingContainer).css({ position: "absolute", width: board.width() + 5, height: board.height(), left: offset.left, top: offset.top, zIndex: 1000 });
		$(loadingContainer + " iframe").css({ width: "100%", height: "100%"});		
		
	}
	
	// Populate filter form
	var filter = this;
	var parameters = this.parameters; 
	
	// Check if we need to fetch items
	// Fetch items only if 'type' equals to 'filter'
	var listingContainer = this.listingSettings['loadingContainer'];
	if ('' != listingContainer && 'undefined' != typeof(listingContainer)) {
		this.type = "filter";
	} else {
		this.type = "default";
	}
	
	// alert(this.serverPath + '?type=' + this.type + '&parameters=' + this.parameters);
	$.post(this.serverPath, {type: this.type, parameters: this.parameters}, function(xml) {
		// Init data source
		filter.initDataSource(xml);
		
		// Handle filter response
		filter.handleResponse();
		
		// Check if the current value of dropdown list is match with the value in parmameters
		// Set default value if not match
		// This case will occur if user set default value before initializing search results listing
		filter.syncData(parameters);		
		
		// Set the flag to indicate the form has been initialized
		filter.setInitFlag(1);
		
		// Save filter conditions
		filter.setCookie("parameters", parameters);
	});	
};

// Set the flag to indicate the filter form has been initialize
filter.prototype.setInitFlag = function(initialized) {
	this.initialized = initialized;
};

// Format raw value
// Return N/A if raw value is undefined or empty
filter.prototype.formatValue = function(raw) {
	var result = raw;
	if ('undefined' == raw || '' == raw) {
		result = 'N/A';
	}
	return result;
};

// Check if the current value of dropdown list is match with the value in parmameters
// Set default value if not match
// This case will occur if user set default value before initializing search results listing
filter.prototype.syncData = function(parameters) {
	var parameterList = parameters.split(";");
	for (key in parameterList) {
		var parameter = parameterList[key].split(":");
		if ("" != parameter[0]){
			var id = "#" + parameter[0];
			var currentValue = $(id).val();
			if ("" != parameter[1]) {
				$(id).val(parameter[1]);
			}
		}
	}
};
