/* PortalApplication Object / Class */

function PortalApplication(portalView, userID) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication
		# DESCR:*		Portal Application constructor.
		# :*			Sets up the Javascript Portal Object,
		# :*			loads saved settings, booked marked properties
		# :*			and viewed Properties.
		# USAGE:*		PortalApp = new PortalApplication(portalView[,userID]');
		# :*			Used in the body onload="PortalApp = new PortalApplication('residential');"
		# :*			stage of the Portal page wrap.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.portalView = (portalView) ? portalView : '';
	this.isResidential = (this.portalView == 'residential') ? 1 : 0;
	this.userID = (userID) ? userID : 0;

	this.savedSettings = new SavedSettings(this.portalView, 0);
	this.propertyRequest = null;
	this.ajaxWait = null;

	var cookiePrefix = (this.portalView) ? this.portalView + '.' : '';
	this.bookmarkedProperties = new Object();
	this.bookmarkCount = 0;
	this.bookmarkCookieName = cookiePrefix + 'bookMarked';

	this.viewedCount = 0;
	this.viewedCookieName = cookiePrefix + 'viewedProperties';
	this.viewedPropertiesLimit = 15;

	this.loadBookmarkedProperties();
	this.loadViewedProperties();
}

PortalApplication.prototype.obtainSearchResults = function() {

	/*	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.obtainSearchResults
		# DESCR:*		Public funtion to grab the saved search settings from the cookie and
		# :*			load the search page. This replaces the PortalSearch.obtainSearchResults
		# :*			function as Realestateview.com.au will not use ajax searches.
		# USAGE:*		<button class="buttonSmall" type="submit" onClick="PortalApp.saveSearch('refinesearch');PortalApp.obtainSearchResults();return false;">Search</button>
		# RETURNS:*		Returns nothing. The browser is directed to load a new URL link.
		# :*			results.
		# %ENDPUBLIC% */

	var searchParams = PortalApp.savedSettings.toURLString();

	var url = "/portal/search?rm=search&" + searchParams;
	window.location = url;
}

PortalApplication.prototype.suburbAutocomplete = function(textControlID) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.suburbAutocomplete
		# DESCR:*		Creates new AutoComplete objects for each of the textControlIDs
		# :*			passed.			
		# USAGE:*		Portalapp.suburbAutocomplete('ressub');
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var AutoCompleteOptions = { script: '/portal/search?rm=suburbautocomplete&',
									valueSep: ',',
									varname: 'sub',
									maxentries: 40,
									shownoresults: false,
									minchars: 2};

		switch (textControlID) {
			case 'advsearchsub':
				AutoCompleteOptions = { script: function(subcontent) {
											var scriptname = '/portal/search?rm=suburbautocomplete';
											return scriptname + '&cs=' + $F('advcs') + '&sub=' + subcontent;
										},
										valueSep: ',',
										varname: 'sub',
										maxentries: 40,
										shownoresults: false,
										minchars: 2};
				var advSearchAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					advSearchAutocomplete.submit = function() { return true; };
				break;
				
			case 'reportsubone':
				AutoCompleteOptions = { script: function(subcontent) {
											var scriptname = '/portal/search?rm=suburbautocomplete';
											return scriptname + '&cs=' + $F('state') + '&sub=' + subcontent;
										},
										valueSep: ',',
										varname: 'reportsubone',
										maxentries: 40,
										shownoresults: false,
										minchars: 2};
				var reportSubOneAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					reportSubOneAutocomplete.submit = function() { return true; };
				break;
			
			case 'reportsubtwo':
				AutoCompleteOptions = { script: function(subcontent) {
											var scriptname = '/portal/search?rm=suburbautocomplete';
											return scriptname + '&cs=' + $F('state') + '&sub=' + subcontent;
										},
										valueSep: ',',
										varname: 'reportsubtwo',
										maxentries: 40,
										shownoresults: false,
										minchars: 2};
				var reportSubTwoAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					reportSubTwoAutocomplete.submit = function() { return true; };
				break;			

			case 'searchsub':
				var searchAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					searchAutocomplete.submit = function() { return true; };
				break;
				
			case 'auctionsearchsub1':
				var searchAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					searchAutocomplete.submit = function() { return true; };
				break;
			
			case 'auctionsearchsub2':
				var searchAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					searchAutocomplete.submit = function() { return true; };
				break;		

			case 'refinesub':
				var refineAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					refineAutocomplete.submit = function() { return true; };
				break;

			case 'csrefinesub':
				AutoCompleteOptions = { script: function(subcontent) {
											var scriptname = '/portal/search?rm=suburbautocomplete';
											return scriptname + '&cs=' + $F('csrefine') + '&sub=' + subcontent;
										},
										valueSep: ',',
										varname: 'sub',
										maxentries: 40,
										shownoresults: false,
										minchars: 2};

				var csRefineAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					csRefineAutocomplete.submit = function() { return true; };
				break;

			case 'agentsub':
				if (document.getElementById(textControlID)) {
					var agentAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					agentAutocomplete.submit = function() { return true; };
				}
				break;

			case 'auctionalertsub':
				AutoCompleteOptions.script = function(subcontent) {
						return '/portal/search?rm=suburbautocomplete&suburbonly=1&cs=' + $F('auctionalertcs') + '&sub=' + subcontent;
					}
				var auctionAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					auctionAutocomplete.submit = function() { return true; };
				break;

			default:
				break;

		}
}

PortalApplication.prototype.propertyDataSuburbAutocomplete = function(textControlID) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.propertyDataSuburbAutocomplete
		# DESCR:*		Creates new AutoComplete object for each of the textControlIDs
		# :*			passed.	The Property Data Auto complete behaves differently to the
		# :*			normal Portal autocomplete, so it has it's own ajax runmode	
		# USAGE:*		Portalapp.propertyDataSuburbAutocomplete('propertydatasub');
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var AutoCompleteOptions = { script: function() {
										var scriptname= '/portal/propertydata?rm=suburbautocomplete';
										return scriptname + '&cs=' + $F('propertydatastate') + '&sub=' + $F('propertydatasub');
									},
									//valueSep: ',',
									varname: 'sub',
									maxentries: 100,
									shownoresults: false,
									minchars: 2};

		switch (textControlID) {
			case 'propertydatasub':
				var propertyDataAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
					propertyDataAutocomplete.submit = function() { return true; };
				break;

			default:
				break;

		}
}

PortalApplication.prototype.AgentnameAutocomplete = function(textControlID) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.AgentnameAutocomplete
		# DESCR:*		Creates new AutoComplete object for each of the textControlIDs
		# :*			passed.	The Agent Auto complete behaves differently to the
		# :*			normal Portal autocomplete, so it has it's own ajax runmode	
		# USAGE:*		Portalapp.AgentAutocomplete('agent');
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var AutoCompleteOptions = { script: function() {
										var scriptname= '/stats/tracking_report?rm=agentautocomplete';
										return scriptname + '&agent=' + $F('agent');
									},
									//valueSep: ',',
									varname: 'agent',
									maxentries: 20,
									shownoresults: false,
									minchars: 2};

		switch (textControlID) {
			case 'agent':
				var agentnameAutocomplete = new AutoComplete(textControlID, AutoCompleteOptions);
				agentnameAutocomplete.submit = function() { return true; };
				break;

			default:
				break;

		}
}

PortalApplication.prototype.getCheckBoxInputArray = function(formName, formInputName) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.getCheckBoxInputArray
		# DESCR:*		Obtain the values of the check boxes within a form.
		# :*			if they are checked.
		# USAGE:*		var CheckBoxArrayValue = this.getCheckBoxInputArray(formName, name);
		# :*			fromName: Name of the form to look for
		# :*			formInputName: name of the checkboxes to get values from
		# RETURNS:*		Returns array of forms input values
		# :*			if they are checked. 
		# %ENDPUBLIC% */

	var CheckBoxen = document.forms[formName][formInputName];
	var CheckBoxValues = new Array();
	for(var i = 0;i < CheckBoxen.length; i++) {
		if (CheckBoxen[i].checked)
			CheckBoxValues.push(CheckBoxen[i].value);
	}

	return CheckBoxValues;
}

PortalApplication.prototype.saveSearch = function(formName, noCookie) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.saveSearch
		# DESCR:*		Saves the form search settings to the savedSettings object.
		# :*			Uses the forms input names as class member accessors
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.saveSearch(nameOfForm[, noCookie]);
		# :*			nameOfForm: Name of the form to save values from.
		# :*			noCookie: Flag - if true, don't save values to cookie (just put in savedSettings)'.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Obtain all form elements
	var el = document.forms[formName].elements;

	// for each form element found
	for(var i = 0; i < el.length; i++) {
		var value = null;
		var name = el[i].name;

		// input type
		switch (el[i].type) {

			case 'checkbox':
				// If we have check boxes which are an array of the same name, will have to add a test for this here
				// This handles single check boxes
				value = (el[i].checked) ? el[i].value : '';
				// This handles arrayed checkboxes
				//gets all the values of same named checkboxes in an array
				//value = this.getCheckBoxInputArray(formName, name);
				break;

			case 'text':
				value = el[i].value;
				break;

			case 'search':
				value = el[i].value;
				break;

			case 'select-one':
				if (el[i].selectedIndex!=-1) {
					if (el[i].options[el[i].selectedIndex].value != "") {
						value = new Array(el[i].options[el[i].selectedIndex].value);
					}
				}

			case 'select-multiple':
				value = new Array();
				for(var j = 0;j < el[i].length;j++) {
					if (el[i].options[j].selected) {
						value.push(el[i].options[j].value);
					}
				}
				break;

			case 'hidden':
				value = el[i].value;
				break;

			default:
				break;
		}

		if (value != null) {
			// save the value in the object, use it's name to reference it
			this.savedSettings[name] = value;
		}
	}

	// tell object to write cookies (unless noCookie requested)
	if (!noCookie) {
		this.savedSettings.saveSettings();
	}
}

PortalApplication.prototype.updateForm = function(formName, elementName) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.updateForm
		# DESCR:*		Sets forms input variables with saved settings in savedSettings Object
		# :*			originally read from cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.updateForm(nameOfForm, elementName);
		# :*			nameOfForm: the form to update
		# :*			elementName: the element to update
		# :*			if elementName is blank, all elements are update
		# :*			else only elements matching that name are updated
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */


	// Obtain all form elements
	var el;
	try {
		el = document.forms[formName].elements;
	} catch(e) {
		// do nothing. We want el to be defined.
	}
	// for each form element
	if (el) {
		for(var i = 0;i < el.length; i++) {
		
			var name = el[i].name;
		
			if ((elementName == '') || (name == elementName)) {
				// input type
				switch (el[i].type) {
					case 'checkbox':
						// If we have check boxes which are an array of the same name, will have to add a test for this here
						// This handles single check boxes
						el[i].checked = (this.savedSettings[name] == el[i].value) ? true : false;
						break;

						// This handles arrayed checkboxes
						var selected = false;
						var arr = this.savedSettings[name];
						if (arr != null) {
							// loop through stored values to find ones we need to select
							for(var j = 0; j < arr.length; j++) {
								if (arr[j] == el[i].value) {
									// selected value found so select it
									selected = true;
								}
							}

							// if array is empty then we should select all in the group for business rules
							if (arr.length == 0) {
								selected = true;
							}
					
							el[i].checked = selected;
						}
						break;

					case 'text':
						el[i].value = this.savedSettings[name];
						break;
	
					case 'search':
						el[i].value = this.savedSettings[name];
						break;

					case 'select-one':
					  	var value = this.savedSettings[name];

						if (typeof(value) == 'object') {
							value = value[0];
						}
					
						for(var j = 0; j < el[i].length; j++) {
							if (el[i].options[j].value ==  value) {
								//found match so select it
								el[i].options[j].selected = true;
							}
						}
						break;

					case 'select-multiple':
					  	var value = this.savedSettings[name];
						for(var j = 0; j < el[i].length; j++) {
							for(var l = 0; l < value.length; l++) {
								if (el[i].options[j].value ==  value[l]) {
									//found match so select it
									el[i].options[j].selected = true;
								}
							}
						}
						break;

					case 'hidden':
						// Skip updating "rm", "P", "portalsection, "portalview",  "con" or "ptr" if they are in the form.
						if (name != "rm" && name != "P" && name != "portalsection" && name != "portalview" && name != "con" && name != "ptr" && (this.savedSettings[name] != undefined)) {
							el[i].value = this.savedSettings[name];
						}
						break;

					default:
						break;
				}
			}
		}
	}
}

PortalApplication.prototype.updateSortControl = function(elementID) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.updateSortControl
		# DESCR:*		Sets Sort Control with saved settings in savedSettings Object
		# :*			originally read from cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.updateSortControl(elementName);
		# :*			elementName: the sort Select control id to update
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var value = this.savedSettings['sor'];

		if (typeof(value) == 'object') {
			value = value[0];
		}
		if ($(elementID) != null){				
			for(var j = 0; j < $(elementID).length; j++) {
				if ($(elementID).options[j].value ==  value) {
					//found match so select it
					$(elementID).options[j].selected = true;
				}
			}
		}	
}

PortalApplication.prototype.selectAllCheckboxes = function(formName, CheckboxArrayName) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.selectAllCheckboxes
		# DESCR:*		Given a name of a form and a checkbox Array Name, Check all of the 
		# :*			checkbox Array contents.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.selectAllCheckboxes(formName, CheckboxArrayName);
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var CheckBoxen = document.forms[formName][CheckboxArrayName];

		// Make all of the checkboxes in the CheckboxArrayName checked = true.
		for (i = 0; i < CheckBoxen.length; i++) {
			if (CheckBoxen[i].type == 'checkbox') {
				CheckBoxen[i].checked = true;
			}
		}
}

PortalApplication.prototype.checkIfAllCheckboxesEmpty = function(formName, CheckboxArrayName) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.checkIfAllCheckboxesEmpty
		# DESCR:*		Given a name of a form and a checkbox Array Name, verify if all of the 
		# :*			checkbox Array contents are unchecked. If they are all unchecked, make them all
		# :*			checked.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.checkIfAllCheckboxesEmpty(formName, CheckboxArrayName);
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

		var CheckBoxen = document.forms[formName][CheckboxArrayName];
		// Assume form Checkbox Array is all unchecked
		var uncheckedArrayOfCheckboxes = true;

		for (i = 0; i < CheckBoxen.length; i++) {
			if (CheckBoxen[i].type == 'checkbox') {
				if (CheckBoxen[i].checked == true) {
					uncheckedArrayOfCheckboxes = false;
				}
			}
		}

		if (uncheckedArrayOfCheckboxes == true) {
			// If our array is all unckecked, check them all.
			this.selectAllCheckboxes(formName, CheckboxArrayName);
		}
}

PortalApplication.prototype.updateRSSLink = function(id) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.updateRSSLink
		# DESCR:*		Given an ID of an <a href=""></a> pertaining to an RSS link,
		# :*			update the href="" to point to the parameters in the 'lastSearch'
		# :*			cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.updateRSSLink('RSSLink');
		# RETURNS:*		Returns True if update successeful, False if not. 
		# %ENDPUBLIC% */

	if (id) {
		var searchParams = this.savedSettings.toURLString();
		$(id).href = '/portal/rss?rss=1&' + searchParams;
		return true;
	}

	return false;
}

PortalApplication.prototype.prettyURL = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.prettyURL
		# DESCR:*		Pretty the URL's for printing. Will allow all urls without http://
		# :*			part to have a http:// part.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.prettyURL();
		# :*			Used in the body onload="PortalApp = new PortalApplication(); PortalApp.prettyURL();"
		# :*			stage of the Portal page wrap.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	var xurl = document.getElementsByTagName("a");

	for (i = 0; i < xurl.length; i++) {
		xurl[i].href = xurl[i].href;
	}
}

PortalApplication.prototype.loadBookmarkedProperties = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.loadBookmarkedProperties
		# DESCR:*		Loads the bookmark cookie and selects the approprate property checkboxes
		# USAGE:*		Internal Function: Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Read the bookMarked cookie
 	var savedString = this.savedSettings.readCookie(this.bookmarkCookieName);
 	
 	if(savedString != null) {
 		// If there is a cookie 
 		var bookmarkedArray = savedString.split(',');//split cookie string in to array
 		for (var i = 0; i < bookmarkedArray.length; i++) {
 			var orderid = bookmarkedArray[i];
 			if (orderid) {
 				// if a value, create a new bookmark
 				this.bookmarkedProperties[orderid] = new BookmarkedProperties(orderid);
				// Increment count
 				this.bookmarkCount++;
 			}
 		}
		// Select the approprite checkboxes if they exist on the page.
		this.selectBookmarkedProperties();
	}

	this.showHistoryCount(this.bookmarkCookieName, 1);
}

PortalApplication.prototype.selectBookmarkedProperties = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.selectBookmarkedProperties
		# DESCR:*		Selects the appropriate property checkboxes in the bookmarkedProperties object.
		# USAGE:*		Internal Function: Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Select the approprite checkboxes if they exist on the page.
	if (document.forms['propertyResults']) {
		for (bookmark in this.bookmarkedProperties) {
			var element = $('OID_' + this.bookmarkedProperties[bookmark]);
			if (element) {
				element.checked = true;
			}
		}
	}
}

PortalApplication.prototype.bookmarkProperty = function(e, orderid, callBack) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkProperty
		# DESCR:*		Update the bookmarkCount, Display, highlight popup and right column tool
		# :*			and add the OrderID to the bookmarked cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.bookmarkProperty(e, orderid);
		# :*			Used in the Search Results display and the corresponding check box for each
		# :*			property displayed.
		# :*			e: event
		# :*			orderID: OrderID of property to bookmark
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	e = (e) ? e : window.event;
	if (!e) { return; }

	var targ = (e.target) ? e.target : (e.srcElement) ? e.srcElement : '';
	if (!targ || !orderid) { return; }

	// Save the target checkbox and orderid - we first need to do some checks for member centre
	this.bookmarkTarget = targ;
	this.bookmarkOrderID = orderid;
	this.bookmarkCallBack = callBack;

	// add or removed if checked or not
	if (targ.checked) {
		// Adding to shortlist - for Residential view we need to prompt if they are not logged in
		if (this.isResidential && !(this.userID || this.savedSettings.readCookie('bookmarkLoginCheck'))) {
			// Not logged in and haven't already acknowledged the prompt - ask them if they want to login/register
			this.bookmarkPropertyConfirm();
		} else {
			// Not residential or they are logged in (or have already been prompted) - just bookmark it
			this.bookmarkContinue();
		}
	} else {
		// Removing from shortlist - for Residential we need to prompt if they are logged in
		if (this.isResidential && this.userID) {
			// They are a logged in user, prompt them each time if OK to remove the listing
			this.bookmarkPropertyConfirm();
		} else {
			// Not residential or not logged in - just remove it
			this.bookmarkContinue();
		}
	}
}

PortalApplication.prototype.bookmarkPropertyConfirm = function() {

	/* 	# %PUBLIC%
		# NAME:*		bookmarkPropertyConfirm
		# DESCR:*		Display an alert box asking user to confirm their bookmark request (add or remove).
		# USAGE:*		this.bookmarkPropertyConfirm();
		# RETURNS:*		false. 
		# %ENDPUBLIC% */

	var targ = this.bookmarkTarget;
	if (!targ) { return; }

	var msgString = '';
	if (targ.checked) {
		msgString += '<p>Simplify your search process by saving properties you are interested in to your shortlist. ';
		msgString += 'To access these across all computers and devices we recommend you <a href="/myview">sign in</a> or <a href="/register">register for myVIEW</a>.</p>';
		msgString += '<p>To continue without signing in, <a href="javascript:hideMyViewAlertBox();PortalApp.bookmarkContinue(1);">click here</a>.</p>';
	} else {
		msgString += '<p>Press <a href="javascript:hideMyViewAlertBox();PortalApp.bookmarkContinue();">continue</a> to confirm you wish to remove this listing from your shortlist.</p>';	
		msgString += '<p>Press <a href="javascript:hideMyViewAlertBox();PortalApp.bookmarkCancel();">cancel</a> to keep this listing in your shortlist.</p>';	
	}

	var extraCloseJS = 'PortalApp.bookmarkCancel();';

	showMyViewAlertBox('My Shortlist', msgString, extraCloseJS);

	return false;
}

PortalApplication.prototype.bookmarkContinue = function(ack) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkContinue
		# DESCR:*		Continue with bookmark propery operation (add or remove) after user prompt.
		# :*			Update the bookmarkCount, Display, highlight popup and right column tool
		# :*			and add the OrderID to the bookmarked cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.bookmarkContinue([0/1]);
		# :*			Used in the Search Results display and the corresponding check box for each
		# :*			property displayed.
		# :*			ack: set to true if user has selected to continue without logging in.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	var targ = this.bookmarkTarget;
	var orderid = this.bookmarkOrderID;
	if (!targ || !orderid) { return; }

	// add or remove if checked or not
	if (targ.checked) {
		// Add to shortlist
		this.bookmarkedProperties[orderid] = new BookmarkedProperties(orderid);
		this.savedSettings.createCookie(this.bookmarkCookieName, this.bookmarkToString());
		this.bookmarkCount++;
		this.showHistoryCount(this.bookmarkCookieName);

		new Ajax.Request('/portal/shortlisthits?OID=' + orderid + '&portalview=' + this.portalView + '&ts=' + new Date().getTime(), {
			method: 'get',
			onSuccess: function(transport) { }
		});
		if (ack) {
			// They have acknowledged the login prompt - set the cookie so we don't prompt them again
			this.savedSettings.createCookie('bookmarkLoginCheck', '1');
		}
	} else {
		// Remove from shortlist
		if (this.userID) {
			var ts = '&ts=' + new Date().getTime();
			new Ajax.Request('/myview/shortlist?rm=delete&OID='+orderid+ts, {
				method: 'get',
				onSuccess: function(transport) { }
			});
		}
		this.bookmarkRemove(orderid);
	}

	if (this.bookmarkCallBack) {
		this.bookmarkCallBack(targ.checked);	// This completes processing on property page
	}

	var displayString = this.bookmarkCount + '<br>Shortlisted Properties' ;
	infoBox(displayString, 'oid_' + orderid + '_' + orderid);
}

PortalApplication.prototype.bookmarkCancel = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkCancel
		# DESCR:*		Cancel bookmark operation (add or remove) after user prompt.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.bookmarkCancel();
		# :*			Used in the Search Results display and the corresponding check box for each
		# :*			property displayed.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	var targ = this.bookmarkTarget;
	if (targ) {		// They canceled operation, so we need to restore checked status
		targ.checked = (targ.checked) ? false : true;	// This fixes up checkbox on results page
	}
	if (this.bookmarkCallBack) {
		this.bookmarkCallBack(targ.checked);	// This completes processing on property page
	}
}

PortalApplication.prototype.bookmarkRemove = function(orderid) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkRemove
		# DESCR:*		Remove the specified property from the bookmark list.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.bookmarkRemove(orderid);
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.bookmarkedProperties[orderid] = null;
	this.savedSettings.createCookie(this.bookmarkCookieName, this.bookmarkToString());
	this.bookmarkCount--;
	if (this.bookmarkCount < 0) {
		this.bookmarkCount = 0;
	}
	this.showHistoryCount(this.bookmarkCookieName);
}

PortalApplication.prototype.bookmarkToString = function(url) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkToString
		# DESCR:*		Turns bookmarks in to a string.
		# :*			Pass true for a url parameter string
		# :*			else return a comma seperated string
		# USAGE:*		Internal Function. Do Not Used.
		# RETURNS:*		String containg bookmarked properties (OrderID).
		# %ENDPUBLIC% */

	var BookmarkString = "";
 	for(bookmark in this.bookmarkedProperties) {
		if (this.bookmarkedProperties[bookmark] != null) {
			if (url) {
				// Create a url parameter string.
				BookmarkString += "&OID=" + this.bookmarkedProperties[bookmark].toString();
			} else {
				// Create a comma seperated string.
				BookmarkString += this.bookmarkedProperties[bookmark].toString() + ",";
			}
		}
	}

	return BookmarkString;
}

PortalApplication.prototype.loadViewedProperties = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.loadViewedProperties
		# DESCR:*		Loads the contents of the "viewedProperties"
		# :*			cookie and sets the display count of view properties
		# USAGE:*		Internal Function. Do Not Used.
		# RETURNS:*		Nothing
		# %ENDPUBLIC% */

	var orderIDs = new Array();		// Array to hold the list of orderids
	var savedString = this.savedSettings.readCookie(this.viewedCookieName);		// Get the cuurent list from cookie
	if (savedString != null) { 
		var viewedPropertiesArray = savedString.split(',');		// Convert cookie string to array of orderids
		var arrayLength = viewedPropertiesArray.length;
		var arrayLimit = this.viewedPropertiesLimit;
		var j = 0;
		for (var i = 0; i < arrayLength && j < arrayLimit; i++) {
			var id = viewedPropertiesArray[i];
			if ((id != '')) {
				orderIDs.push(id);
				j++;
			}
		}
	}
	this.viewedCount = orderIDs.length;

	this.showHistoryCount(this.viewedCookieName, 1);
}

PortalApplication.prototype.viewProperty = function(orderid) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.viewProperty
		# DESCR:*		Adds / removes a property to our viewedProperties cookie
		# :*			orderid: OrderID of the property being viewed.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.viewProperty(orderid);
		# RETURNS:*		Nothing.
		# %ENDPUBLIC% */

	var orderIDs = new Array();		// Array to hold the list of orderids
	var savedString = this.savedSettings.readCookie(this.viewedCookieName);		// Get the cuurent list from cookie
	if (savedString != null) { 
		var viewedPropertiesArray = savedString.split(',');		// Convert cookie string to array of orderids
		// Copy from cookie to array, but 1 less than limit so have room to add 'orderid'
		var arrayLength = viewedPropertiesArray.length;
		var arrayLimit = this.viewedPropertiesLimit - 1;
		var j = 0;
		for (var i = 0; i < arrayLength && j < arrayLimit; i++) {
			var id = viewedPropertiesArray[i];
			if ((id != '') && (id != orderid)) {
				orderIDs.push(id);
				j++;
			}
		}
	}
	orderIDs.unshift(orderid);		// Add this orderid - goes at the beginning so most recent is first
	this.viewedCount = orderIDs.length;

	// Save our viewed properties to the cookie.
	this.savedSettings.createCookie(this.viewedCookieName, orderIDs.toString());
}

PortalApplication.prototype.viewedToString = function() {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.viewedToString
		# DESCR:*		Turns viewed properties into a comma seperated string.
		# USAGE:*		Internal Function. Do Not Use.
		# RETURNS:*		Nothing.
		# %ENDPUBLIC% */

	// If we have a cookie, just return that
	var savedString = this.savedSettings.readCookie(this.viewedCookieName);		// Get the cuurent list from cookie
	if (savedString != null) { 
		return savedString;
	} else {
		return '';
	}
}

PortalApplication.prototype.updateOIDcookie = function(e, cookieName, orderid) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.updateOIDcookie
		# DESCR:*		Removes a property OrderID from the cookie name passed
		# :*			and displays an information overlay box.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.updateOIDcookie(e, 'bookMarked', orderid);
		# :*			e: event
		# :*			cookieName: Name of cookie to update. Valid cookie names - 'viewedProperties', 'bookMarked'
		# :*			orderid: OrderID to remove
		# RETURNS:*		True if it was removed, false otherwise.
		# %ENDPUBLIC% */

	var removed = false;

	if (cookieName && orderid) {

		var saveString = '';
		var text = '';
		if (this.portalView) {
			cookieName = this.portalView + '.' + cookieName;
		}

		switch (cookieName) {
			case this.viewedCookieName:
				removed = true;
				var orderIDs = new Array();		// Array to hold the list of orderids
				var savedString = this.savedSettings.readCookie(this.viewedCookieName);		// Get the cuurent list from cookie
				if (savedString != null) { 
					var viewedPropertiesArray = savedString.split(',');		// Convert cookie string to array of orderids
					// Copy from cookie to array, but don't include 'orderid'
					var arrayLength = viewedPropertiesArray.length;
					for (var i = 0; i < arrayLength; i++) {
						var id = viewedPropertiesArray[i];
						if ((id != '') && (id != orderid)) {
							orderIDs.push(id);
						}
					}
				}
				this.viewedCount = orderIDs.length;
				saveString = orderIDs.toString();
				text = 'My Last View';
				break;

			case this.bookmarkCookieName:
				removed = true;
		 		this.bookmarkedProperties[orderid] = null;
				this.bookmarkCount--;
				saveString = this.bookmarkToString();
				text = 'Shortlist';
				break;

			default:
				cookieName = '';
				break;
		}

		if (removed) {
			if (cookieName) {
				this.savedSettings.createCookie(cookieName, saveString);
				this.showHistoryCount(cookieName);
			}
			infoBox('Property removed from ' + text);
		}
	}

	return removed;
}

PortalApplication.prototype.clearHistory = function(cookieName, noHighlight) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.clearHistory
		# DESCR:*		Removes the cookie contents form the cookie name passed and updates the PortalApp
		# :*			object to set the Count associated with the cookie name to zero.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.clearHistory('bookMarked' [, 1]);
		# :*			cookieName: Name of cookie to update. Valid cookie names - 'viewedProperties', 'BookMarked'
		# RETURNS:*		Nothing.
		# %ENDPUBLIC% */

	var displayString = '';
	if (cookieName) {
		if (this.portalView) {
			cookieName = this.portalView + '.' + cookieName;
		}
		switch (cookieName) {
			case this.viewedCookieName:
				this.viewedCount = 0;
				displayString = 'My Last View History cleared';
				break;
			case this.bookmarkCookieName:
				// De-Select the approprite checkboxes if they exist on the page.
				if (document.forms['propertyResults']) {
					for (bookmark in this.bookmarkedProperties) {
						var elem = $('OID_' + bookmark);
						if (elem && (elem.checked == true)) {
							elem.checked = false;
						}
					}
				}
		 		this.bookmarkedProperties = new Object();;
				this.bookmarkCount = 0;
				displayString = 'Shortlisted Property history cleared';
				break;
			default:
				cookieName = '';
				break;
		}
	}
	if (cookieName) {
		this.savedSettings.eraseCookie(cookieName);
		this.showHistoryCount(cookieName, noHighlight);
	}
	if (displayString && !noHighlight) {
		infoBox(displayString);
	}
}

PortalApplication.prototype.showHistoryCount = function(cookieName, noHighlight) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.showHistoryCount
		# DESCR:*		Update the page element(s) that are showing the bokmarked or last viewed counts.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.showHistoryCount(PortalApp.bookmarkCookieName [, 1]);
		# :*			Page elements identified by having class="bookmark-count" or class="viewed-count"
		# RETURNS:*		Nothing.
		# %ENDPUBLIC% */

	if (cookieName) {
		var count;
		var elements;
		switch (cookieName) {
			case this.viewedCookieName:
				count = this.viewedCount;
				elements = $$('.viewed-count');
				break;
			case this.bookmarkCookieName:
				count = this.bookmarkCount;
				elements = $$('.bookmark-count');
				break;
		}
		if (elements) {
			count = count + '';
			elements.each(function(element) { element.innerHTML = count; });
		}
		if (!noHighlight && $('bookmarkHighlight')) {
			new Effect.Highlight('bookmarkHighlight',{startcolor:'#333333', queue: {scope: 'highlight', position: 'end'}});
		}
	}
}

/* SavedSettings Object / Class */

function SavedSettings(portalView, noCookie) {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings
		# DESCR:*		SavedSettings Object constructor.
		# :*			Loads Portal users settings from cookies.
		# :*			Sets up storage for Portal users settings.
		# USAGE:*		this.savedSettings = new SavedSettings([noCookie]);
		# :*			portalView: The portalview of the page we are on (from PortalApp).
		# :*			noCookie: Flag - if true, don't load values from cookie (just initialise savedSettings)'.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.lastSearchCookieName = ((portalView) ? portalView + '.' : '') + 'lastSearch';

	// last search storage
	this.kw = ""; 				// Keyword
	this.pt = new Array();		// Property Type
	this.cs = new Array();		// CityState location
	this.rg = new Array();		// Area regions
	this.sub = "";				// Suburb Name / Post Code / ID
	this.mun = 0;				// Municipality
	this.street = "";			// Street name
	this.sur = "";				// surrounding suburbs
	this.bel = 0;				// Bedroom Low
	this.beh = 0;				// Bedroom High
	this.bal = 0;				// Bathroom Low
	this.bah = 0;				// Bathroom High
	this.prl = 0;				// Price Low
	this.prh = 0;				// Price High
	this.pal = 0;				// Parking Low
	this.pah = 0;				// Parking High
	this.rprl = 0;				// Rent Price Low
	this.rprh = 0;				// Rent Price High
	this.sor = "";				// Sorting
	this.CID = 0;				// ClientID for Agent
	this.GID = 0;				// GroupID for Agent
	this.ybl = 0;				// Year Built Low
	this.ybh = 0;				// Year Built High
	this.lal = 0;				// Land Area Low
	this.lah = 0;				// Land Area High
	this.fal = 0;				// Floor Area Low
	this.fah = 0;				// Floor Area High
	this.con = "";				// Contract Type
	this.ptr = "r";				// Propert Type range
	this.rgr = "";				// Region Range
	this.portalview = "residential";	// Portal View
	this.portalsection = "buy";			// Portal Section.
	this.cat = 0; 				// Business Category
	this.subcat = new Array();			// Business Sub Category 
    
    //for quick search
    this.quicksearch = 0;
    
	// Options that appear on the advanced search pages.
	this.fur = 0;				// Furnished listings
	this.incsold = 0;			// Include Sold listings
	this.exsold = 0;			// Exclude Sold listings
	this.exauct = 0;			// Exclude Auction Listings
	this.exsale = 0;			// Exclude Sale Listings (auction only)
	this.exCID = 0;				// Exclude CID's
	this.ofi = 0;				// Exclude Listings without OFI times (ofi only)
	this.ls = 0;				// Life Style
	this.grl = 0;				// Golf and Resort Living
	this.ac = 0;				// Aged care

	// Options that appear on the Rental advanced search page
	this.stl = 0;				// Properties with Short Term Lease

	// Green options that appear on the advanced search pages.
	this.green = 0;			// green search
	this.OF70 = 0;			// Passive Climate Design
	this.OF71 = 0;			// Solar Power
	this.OF72 = 0;			// Double Glazing
	this.OF73 = 0;			// Eco Materials
	this.OF74 = 0;			// Wind Power
	this.OF75 = 0;			// Grey Water
	this.OF76 = 0;			// Water Tanks
	this.OF77 = 0;			// Solar Hot Water
	this.OF78 = 0;			// Energy Rated Appliances
	this.OF79 = 0;			// Alternative Energy
	this.OF80 = 0;			// Organic Building Materials
	this.OF81 = 0;			// High Insulation Rating

	// Unless the noCookie parameter was given, grab the cookie settings
	if (!noCookie) {
		this.loadSettings();
	}
}

SavedSettings.prototype.loadSettings = function() {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.loadSettings
		# DESCR:*		load our settings from thier respective cookies
		# USAGE:*		Internal Function. Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Load the last search the user did
	var str = this.readCookie(this.lastSearchCookieName);
	if (str != null) {
		this.fromURLString(str);
	}

}

SavedSettings.prototype.saveSettings = function() {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.saveSettings
		# DESCR:*		Save our settings to thier respective cookies
		# USAGE:*		Internal Function. Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.createCookie(this.lastSearchCookieName, this.toURLString(), 365);
}

SavedSettings.prototype.toURLString = function() {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.toURLString
		# DESCR:*		returns a URL string of search parameters
		# USAGE:*		Internal Function. Do Not Use.
		# RETURNS:*		String containing the Search URL Parameters. 
		# %ENDPUBLIC% */

 	var urlString = "kw=" + encodeURIComponent(this.kw) + "&sub=" + encodeURIComponent(this.sub) +
 					"&street=" + encodeURIComponent(this.street) + "&sur=" + encodeURIComponent(this.sur) +
					"&mun=" + this.mun + "&bel=" + this.bel + "&beh=" + this.beh + "&bal=" + this.bal + "&cat=" + this.cat +
					"&bah=" + this.bah + "&sor=" + encodeURIComponent(this.sor) + "&CID=" + this.CID +
					"&GID=" + this.GID + "&con=" + encodeURIComponent(this.con) + "&ybl=" + this.ybl + "&ybh=" + this.ybh + 
					"&lal=" + this.lal + "&lah=" + this.lah + "&fal=" + this.fal + "&fah=" + this.fah + "&ptr=" + this.ptr +
					"&pal=" + this.pal + "&pah=" + this.pah + "&rgr=" + this.rgr + 
					"&portalview=" + this.portalview + "&portalsection=" + this.portalsection +
					"&fur=" + this.fur + "&incsold=" + this.incsold + "&exsold=" + this.exsold + "&exauct=" + this.exauct + "&exsale=" + this.exsale + "&exCID=" + this.exCID + 
					"&ofi=" + this.ofi + "&ls=" + this.ls + "&grl=" + this.grl + "&ac=" + this.ac + "&stl=" + this.stl + 
					"&green=" + this.green + "&OF70=" + this.OF70 + "&OF71=" + this.OF71 + "&OF72=" + this.OF72 + 
					"&OF73=" + this.OF73 + "&OF74=" + this.OF74 + "&OF75=" + this.OF75 + "&OF76=" + this.OF76 + 
					"&OF77=" + this.OF77 + "&OF78=" + this.OF78 + "&OF79=" + this.OF79 + "&OF80=" + this.OF80 + 
					"&OF81=" + this.OF81;
                    
    if (this.quicksearch !=0) {
        urlString += "&quicksearch=1";
        urlString += "&bs=" + 50;
    }

	if (this.con == 'S') {
		urlString += "&prl=" + this.prl + "&prh=" + this.prh;
	} else {
		urlString += "&rprl=" + this.rprl + "&rprh=" + this.rprh;
	}

	for(var i = 0; i < this.pt.length; i++) {
 		urlString += "&pt=" + this.pt[i];
	}

	for(var i = 0; i < this.cs.length; i++) {
 		urlString += "&cs=" + this.cs[i];
	}

	for(var i = 0; i < this.rg.length; i++) {
 		urlString += "&rg=" + this.rg[i];
	}
	
	for(var i = 0; i < this.subcat.length; i++) {
 		urlString += "&subcat=" + this.subcat[i];
	}
	return urlString;
}

SavedSettings.prototype.fromURLString = function(URLString) {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.fromURLString
		# DESCR:*		Parses a URL search string and sets the
		# :*			SavedSettings Object Constants with the values
		# :*			passed. Used for decoding the 'lastSearch'
		# :*			cookie string.
		# USAGE:*		Internal Function. Do Not Use.
		# RETURNS:*		String containing the Search URL Parameters. 
		# %ENDPUBLIC% */

	var params = URLString.split('&');
	for(var i = 0; i < params.length; i++) {
		var str = params[i];
		var name = str.substring(0, str.indexOf('='));
		var value = str.substring(str.indexOf('=') + 1, str.length);
		if (value != '') {
        
			switch(name) {

				case 'kw':
					this.kw = decodeURIComponent(value);
					break;
                
                case 'quicksearch':
                    this.quicksearch = decodeURIComponent(value);
                    break;
                    
                case 'street':
					this.street = decodeURIComponent(value);
					break;

				case 'sub':
					this.sub = decodeURIComponent(value);
					break;

				case 'sur':
					this.sur = decodeURIComponent(value);
					break;

				case 'rgr':
					this.rgr = value;
					break;

				case 'mun':
					this.mun = value;
					break;

				case 'bel':
					this.bel = value;
					break;

				case 'beh':
					this.beh = value;
					break;

				case 'bal':
					this.bal = value;
					break;

				case 'bah':
					this.bah = value;
					break;

				case 'prl':
					this.prl = value;
					break;

				case 'prh':
					this.prh = value;
					break;

				case 'pal':
					this.pal = value;
					break;

				case 'pah':
					this.pah = value;
					break;

				case 'rprl':
					this.rprl = value;
					break;

				case 'rprh':
					this.rprh = value;
					break;

				case 'sor':
					this.sor = decodeURIComponent(value);
					break;

				case 'CID':
					this.CID = value;
					break;

				case 'GID':
					this.GID = value;
					break;
					
				case 'ybl':
					this.ybl = value;
					break;

				case 'ybh':
					this.ybh = value;
					break;
					
				case 'lal':
					this.lal = value;
					break;

				case 'lah':
					this.lah = value;
					break;

				case 'fal':
					this.fal = value;
					break;

				case 'fah':
					this.fah = value;
					break;

				case 'ptr':
					this.ptr = value;
					break;

				case 'pt':
					this.pt.push(value);
					break;

				case 'cs':
					this.cs.push(value);
					break;

				case 'rg':
					this.rg.push(value);
					break;

				case 'con':
					this.con = decodeURIComponent(value);
					break;

				case 'portalview':
					this.portalview = value;
					break;

				case 'portalsection':
					this.portalsection = value;
					break;

				case 'fur':
					this.fur = value;
					break;

				case 'incsold':
					this.incsold = value;
					break;

				case 'exsold':
					this.exsold = value;
					break;

				case 'exauct':
					this.exauct = value;
					break;
					
				case 'exsale':
					this.exsale = value;
					break;
					
				case 'exCID':
					this.exCID = value;
					break;
					
				case 'ofi':
					this.ofi = value;
					break;

				case 'ls':
					this.ls = value;
					break;

				case 'grl':
					this.grl = value;
					break;

				case 'ac':
					this.ac = value;
					break;

				case 'stl':
					this.stl = value;
					break;

				case 'green':
					this.green = value;
					break;

				case 'OF70':
					this.OF70 = value;
					break;

				case 'OF71':
					this.OF71 = value;
					break;

				case 'OF72':
					this.OF72 = value;
					break;

				case 'OF73':
					this.OF73 = value;
					break;

				case 'OF74':
					this.OF74 = value;
					break;

				case 'OF75':
					this.OF75 = value;
					break;

				case 'OF76':
					this.OF76 = value;
					break;

				case 'OF77':
					this.OF77 = value;
					break;

				case 'OF78':
					this.OF78 = value;
					break;

				case 'OF79':
					this.OF79 = value;
					break;

				case 'OF80':
					this.OF80 = value;
					break;

				case 'OF81':
					this.OF81 = value;
					break;
					
				case 'cat':
					this.cat = value;
					break;
					
				case 'subcat':
					this.subcat.push(value);
					break;
						
				default:
					break;
			}
		}
	}
}

/* SavedSettings cookie helpers */

SavedSettings.prototype.createCookie = function(name, value, expiredays) {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.createCookie
		# DESCR:*		Create a Cookie with the values supplied.
		# USAGE:*		this.savedSettings = new SavedSettings();
		# :*			this.createCookie('lastSearch', urlstring, ExpireDays);
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	if (expiredays) {
		var date = new Date();
		date.setTime(date.getTime() + (expiredays * 24 * 60 * 60 * 1000));
		var expires = "; expires=" + date.toGMTString();
	} else {
		var expires = "";
	}
	document.cookie = name + "=" + escape(value) + expires + "; path=/";
}

SavedSettings.prototype.readCookie = function(name) {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.readCookie
		# DESCR:*		Read the contents of the named cookie
		# USAGE:*		this.savedSettings = new SavedSettings();
		# :*			var somestring = this.readCookie('lastSearch');
		# RETURNS:*		null or contents of the Cookie. 
		# %ENDPUBLIC% */

	var nameEQ = name + "=";
	var CookieArray = document.cookie.split(';');

	for(var i=0; i < CookieArray.length; i++) {
		var c = CookieArray[i];
		while (c.charAt(0) == ' ') c = c.substring(1, c.length);
		if (c.indexOf(nameEQ) == 0) { 
			return unescape(c.substring(nameEQ.length, c.length));
		}
	}

	return null;
}

SavedSettings.prototype.eraseCookie = function(name) {

	/* 	# %PUBLIC%
		# NAME:*		SavedSettings.prototype.eraseCookie
		# DESCR:*		Erase A Cookie. 
		# :*			name - name of the cookie to erase.
		# USAGE:*		this.savedSettings = new SavedSettings();
		# :*			this.eraseCookie('lastSearch');
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.createCookie(name, "", -1);
}


/* BookmarkedProperties Object / Class */

function BookmarkedProperties(orderid) {

	/* 	# %PUBLIC%
		# NAME:*		BookmarkedProperties
		# DESCR:*		Class object for storing a bookmarked property (OrderID) 
		# USAGE:*		Internal Function. Do Not Used.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.PropertyID = orderid;
}

BookmarkedProperties.prototype.toString = function() {

	/* 	# %PUBLIC%
		# NAME:*		BookmarkedProperties.prototype.toString
		# DESCR:*		Returns saved bookemarked property (OrderID).
		# USAGE:*		Internal Function. Do Not Used.
		# RETURNS:*		OrderID or Array of OrderIDs. 
		# %ENDPUBLIC% */

	return this.PropertyID;
}

BookmarkedProperties.prototype.fromString = function(theString) {

	/* 	# %PUBLIC%
		# NAME:*		BookmarkedProperties.prototype.fromString
		# DESCR:*		Stores a string of saved bookemarked properties (OrderID).
		# USAGE:*		Internal Function. Do Not Used.
		# RETURNS:*		Nothing
		# %ENDPUBLIC% */

	this.PropertyID = theString;	
}


/* General non Class / object Functions */

function showHideSelectControls(hide) {

	/* 	# %PUBLIC%
		# NAME:*		showHideSelectControls()
		# DESCR:*		Make the select controls on the Page visible / invisible.
		# :*			IE 6 select controls sit above every other z-index.
		# :*			Sometimes we need to hide them so other things show on top.
		# :*			This function will show by default. If hide is true, then
		# :*			make the selects invisible.
		# USAGE:*		showHideSelectControls(hide);
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	var selectControls = document.getElementsByTagName("select");

	if (hide == true) {
		// Hide the select controls.
		for (i = 0; i != selectControls.length; i++) {
			selectControls[i].style.visibility = "hidden";
		}

	} else {
		// Show the select controls.
		for (i = 0; i != selectControls.length; i++) {
			selectControls[i].style.visibility = "visible";
		}
	}
}

function obtainPageSize() {
	
	/* 	# %PUBLIC%
		# NAME:*		obtainPageSize()
		# DESCR:*		Return an array containg the page and window size 
		# :*			of the borwser.
		# USAGE:*		var arrayPageSize = obtainPageSize();
		# RETURNS:*		Array containing the page and window sizes.
		# :*			arrayPageSize[0] = pageWidth
		# :*			arrayPageSize[1] = pageHeight
		# :*			arrayPageSize[2] = windowWidth
		# :*			arrayPageSize[3] = windowHeight
		# %ENDPUBLIC% */


	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight) {
		// all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else {
		// Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;

	if (self.innerHeight) {
		// all except Explorer
		if (document.documentElement.clientWidth) {
			windowWidth = document.documentElement.clientWidth; 
		} else {
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) {
		// Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) {
		// other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// For small pages with total height less than the height of the viewport
	if (yScroll < windowHeight) {
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// For small pages with total width less than the width of the viewport
	if (xScroll < windowWidth) {	
		pageWidth = xScroll;		
	} else {
		pageWidth = windowWidth;
	}

	arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight);
	return arrayPageSize;
}

function obtainDocumentScrollTop() {

	/* 	# %PUBLIC%
		# NAME:*		obtainDocumentScrollTop
		# DESCR:*		Obtain the document scroll top offset.
		# USAGE:*		my Offset = obtainDocumentScrollTop();
		# RETURNS:*		Integer for the Document Scoll Top offset. 
		# %ENDPUBLIC% */

	var scrollY = 0;

	if (document.documentElement && document.documentElement.scrollTop) {
		scrollY = document.documentElement.scrollTop;
	} else if (document.body && document.body.scrollTop) {
		scrollY = document.body.scrollTop;
	} else if (window.pageYOffset) {
		scrollY = window.pageYOffset;
	} else if (window.scrollY) {
		scrollY = window.scrollY;
	}

	return scrollY;
}

function infoBox(displayString, OrderIDElement) {

	/* 	# %PUBLIC%
		# NAME:*		infoBox
		# DESCR:*		Display an overlayed information box, centred on the screen
		# :*			with the message passed. Used with History / bookmarking tools.
		# USAGE:*		infoBox("Some Message");
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// If we have a string to display, display the info box
	// else do nothing. Useless to display a blank box.
	if (displayString != "" || displayString != null) {
		var infoBoxElement = $('infoBox');
		// If the infoBox element exists, first remove it as we create it here
		if (infoBoxElement != undefined) {
			infoBoxElement.parentNode.removeChild(infoBoxElement);
		}
		//create div and set attributes
		infoBoxElement = document.createElement('div');
		infoBoxElement.setAttribute('id','infoBox');
		// Assign the contenets
		infoBoxElement.innerHTML = "<div><div class='infoBoxContents'>" + displayString + "</div></div>";
		// If OrderIDElement exists, locate the display there, else centre it on the screen
		var parent;
		if (OrderIDElement && $(OrderIDElement)) {
			parent = $(OrderIDElement);
			parent.insertBefore(infoBoxElement, parent.firstChild);
			infoBoxElement.style.left = "30%";
		} else {
			parent = document.getElementsByTagName('body').item(0);
			parent.insertBefore(infoBoxElement, parent.firstChild);
			new Effect.Centre('infoBox');
		}
		// make it appear for a short while
		new Effect.Appear('infoBox', {queue: 'front'});
		new Effect.Fade('infoBox', {duration: 1.0, queue: 'end'});
	}
}

function setRadioGroupValue(formName, radioGroupName, newValue) {

	/* 	# %PUBLIC%
		# NAME:*		setRadioGroupValue
		# DESCR:*		Given a form name, radio button group name
		# :*			and a radio button group value, Set the
		# :*			with the paramaters passed.
		# USAGE:*		setRadioGroupValue('nameOfForm', 'nameOfRadioGroup', 'someValue');
		# RETURNS:*		True if the value was found and checked in the radio button group,
		# :*			false if the value is not in the radio buttton group. 
		# %ENDPUBLIC% */

	if (!radioGroupName && !formName && !newValue) {
		return false;
	}

	var radioGroup = document.forms[formName].elements[radioGroupName];
	var radioOptionFound = false;

	for(var i = 0; i < radioGroup.length; i++) {
		radioGroup[i].checked = false;
		if (radioGroup[i].value == newValue.toString()) {
			radioGroup[i].checked = true;
			radioOptionFound = true;
		}
	}

	return radioOptionFound;
}

function obtainRadioGroupValue(formName, radioGroupName) {

	/* 	# %PUBLIC%
		# NAME:*		obtainRadioGroupValue
		# DESCR:*		Given a form name, radio button group name, obtain the
		# :*			value of the selected Radio button.			
		# USAGE:*		obtainRadioGroupValue('nameOfForm', 'nameOfRadioGroup');
		# RETURNS:*		zero(0) no form name and radio group name is passed or
		# :*			the value of the selected button in radio buttton group is returned. 
		# %ENDPUBLIC% */

	if (!radioGroupName && !formName) {
		return 0;
	}

	var radioGroup = document.forms[formName].elements[radioGroupName];

	var radioGroupValue = "";
	for(var i = 0; i < radioGroup.length; i++) {

		if (radioGroup[i].checked) {
			radioGroupValue = radioGroup[i].value
		}
	}

	return radioGroupValue;
}

function testEmailAddress(emailAddress) {
	/* 	# %PUBLIC%
		# NAME:*		testEmailAddress
		# DESCR:*		Given an email address, test to see if it is valid.			
		# USAGE:*		var ValidEmailAddress = testEmailAddress(emailAddress);
		# RETURNS:*		True for valid email address or False for invalid email address. 
		# %ENDPUBLIC% */

		var filter=/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;

		if (!filter.test(emailAddress)) {
			return false;
		}

		return true
}

function removeTextFromTextField(FieldID) {
	/* 	# %PUBLIC%
		# NAME:*		removeTextFromTextField
		# DESCR:*		Given an ID of a text input field, makes it value blank.			
		# USAGE:*		removeTextFromTextField(FieldID);
		# RETURNS:*		Nothing. If the FieldID is not null / blank it's value will become "". 
		# %ENDPUBLIC% */

	if (FieldID) {
		$(FieldID).value = "";
	}

}

function callInProgress(xmlhttp) {

	/*	# %PRIVATE%
		# NAME:*		callInProgress
		# DESCR:*		Determine if an AJAX call is in progress or not. 
		# USAGE:*		Internal Function. Do not use.
		# RETURNS:*		Returns True if an AJAX call is in progress, False if not.
		# %ENDPRIVATE% */

	if (xmlhttp == null) {
		return false;
	}

	switch (xmlhttp.readyState) {
		case 1: case 2: case 3:
			return true;
			break;

		// Case 4 and 0
		default:
			return false;
			break;
	}
}

function findNodeById(id, nodeArray){

	/*	# %PUBLIC%
		# NAME:*		findNodeById
		# DESCR:*		search in an array of nodes for the one with the passed id 
		# USAGE:*		var results = findNodeById('results', nodes);
		# :*			id : string, the id of the node to find
		# :*			nodeArray : array of nodes
		# RETURNS:*		Returns node if found or false if not
		# %ENDPUBLIC% */

	for(var i = 0; i < nodeArray.length; i++) {
		
			if (nodeArray[i].id == id) {
				return nodeArray[i];
			}
	}

	return false;
}

function alertBox(errorHeaderString, errorString) {	

	/* 	# %PUBLIC%
		# NAME:*		alertBox
		# DESCR:*		Display a 21st century javascript alert box,
		# :*			with the paramaters passed.
		# USAGE:*		alertBox("Some Header", "Some Message");
		# RETURNS:*		false. 
		# %ENDPUBLIC% */

	var buttonHtml = '<br><div class="largebutton"><button type="submit" onclick="_hideAlertBox();return false;">Close</button></div>';

	if (errorHeaderString == "") {
		errorHeaderString = "An Error has occured!";
	}

	if (errorString == "") {
		errorString = "There has been an unknown error.<br>";
	}

	var topCloseButtonHtml = '<div class="closebutton" style="float:right;"><button type="submit" onclick="_hideAlertBox();return false;">&nbsp;</button></div>';

	errorHeaderString = '<b style="float:left;">' + errorHeaderString + '</b>' + topCloseButtonHtml + '<div class="clear"></div>';
	
	$('alertboxdialog').innerHTML = "<div id='alertboxMessage'><h4>" + errorHeaderString + "</h4><p>" + errorString + "</p><p style='margin-top:-20px;'>" + buttonHtml + "</p></div>";

	_showAlertBox();

	return false;
}

function _ToggleAlertBox() {

	/* 	# %PRIVATE%
		# NAME:*		_ToggleAlertBox
		# DESCR:*		No longer used here - but kept as referenced in other files
		# USAGE:*		Do Not Use
		# RETURNS:*		Nothing
		# %ENDPRIVATE% */

	if ($('alertbox').style.display == "block") {
		_hideAlertBox();
	} else {
		_showAlertBox();
	}
}

function _showAlertBox() {
	/* 	# %PRIVATE%
		# NAME:*		_showAlertBox
		# DESCR:*		Internal Subroutine used by the alertBox() function
		# USAGE:*		Do Not Use
		# RETURNS:*		Nothing
		# %ENDPRIVATE% */

	// Adjust alert box background for page size
	var arrayPageSize = obtainPageSize();
	$('alertbox').style.width = arrayPageSize[2] + "px";
	$('alertbox').style.height = arrayPageSize[3] + "px";

	// Show the AlertBox
	showHideSelectControls(true);
	$('alertbox').style.display = "block";
}

function _hideAlertBox() {
	/* 	# %PRIVATE%
		# NAME:*		_hideAlertBox
		# DESCR:*		Internal Subroutine used by the alertBox() function
		# USAGE:*		Do Not Use
		# RETURNS:*		Nothing
		# %ENDPRIVATE% */

	// Hide the AlertBox
	$('alertbox').style.display = "none";
	showHideSelectControls();
}

function showInOverlay(href, title, width, height, noscroll) {	

	/* 	# %PUBLIC%
		# NAME:*		showInOverlay
		# DESCR:*		Create a lightwindow overlay using the given href
		# USAGE:*		showInOverlay(href, title, width, height);
		# RETURNS:*		True if overlay created, else false. 
		# %ENDPUBLIC% */

	if (myLightWindow && href) {
		title = (title) ? title : 'RealestateView';
		width = (width) ? width : 360;
		height = (height) ? height : 450;
		myLightWindow.activateWindow({
		    href: href, 
		    title: title, 
		    width: width,
    		height: height
		});
		if (noscroll && $('lightwindow_iframe')) {
			$('lightwindow_iframe').setAttribute('scrolling', 'no');
		}
		return true;
	}
	return false;
}

function showContactNumbers(oid, gaTracker, portalview) {

	/* 	# %PUBLIC%
		# NAME:*		showContactNumbers
		# DESCR:*		Given an OID of a listing, displays all hidden phone numbers
		# :*			and increments the PTH hit counter.
		# :*			When we are in the live server, we will also track this
		# :*			event using Google Analytic's pageTracker.
		# USAGE:*		showContactNumbers('1234567');
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	if (oid) {		
		var ts = '&ts=' + new Date().getTime();
		new Ajax.Request('/portal/phonehits?OID='+oid+ts, {
			method: 'get',
  			onSuccess: function(transport) {
      		// Hide links and show contact numbers
				$$('.shownumbers').invoke('hide');
				$$('.contactnumbers').invoke('show');
				//DoubleClick Floodlight Tag (called via floodlightTracker):
				//Activity name of this tag: Phone Agent
				//Creation Date: 02/16/2011
				floodlightTracker.track('http://fls.doubleclick.net/activityi;src=2845269;type=conve936;cat=phone872');
				if (typeof gaTracker != "undefined") {
					gaTracker.push(['_trackPageview', '/contact/phone']);
				}
				Effect.multiple($$('.highlight'),Effect.Highlight,{ speed: 0 });
  			}
		});
	}
}


function returnBusinessSubCategory(	update_field_number, category_id, sub_category_id,
									select_name, include_all, multiple, size, width, 
									disabled ) {

	/* 	# %PUBLIC%
		# NAME:*		returnBusinessSubCategory
		# DESCR:*		Generate and return a business subcategories select control 
		# :*			based on the given category id. 
		# USAGE:*		updateBusinessSubCategory(1, 11);
		# :*			updateBusinessSubCategory(1, 11, 101); # where sub category id 101
		# :*												   # will be selected
		# RETURNS:*		Nothing but updates HTML element named 
		# :*			'SubCategory'+update_field_number with HTML code 
		# :*			containing a select control.
		# %ENDPUBLIC% */
		
	if (category_id && update_field_number) {		
		var params = 'select_id='+ update_field_number +'&bus_cat=' + category_id + 
					 '&bus_sub_cat=' + sub_category_id + 
					 
					 // select control attributes
					 '&include_all=' + include_all + 
					 '&multiple=' + multiple + '&size=' + size + '&width=' + width + 
					 '&disabled=' + disabled;
		if (select_name) 
			params += '&select_name=' + select_name;	

		new Ajax.Request('/portal/returnbusinesssubcategories?' + params, {
			method: 'get',
  			onSuccess: function(transport) {
  				var UpdatingHTMLName = 'SubCategory' + update_field_number;
  				$(UpdatingHTMLName).update(transport.responseText);
  			}
		});
	}
}

PortalApplication.prototype.loadBookmarkedPropertiesAgency = function(agency) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.loadBookmarkedProperties
		# DESCR:*		Loads the bookmark cookie and selects the approprate property checkboxes
		# USAGE:*		Internal Function: Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Read the bookMarked cookie
	var savedString = this.savedSettings.readCookie('bookMarkedAgency');

	if(savedString != null) {
		// If there is a cookie 

		this.bookmarkedProperties = new Object();
		this.bookmarkCount = 0;
		var BookmarkedArray = savedString.split(',');//split cookie string in to array

		for(var i = 0; i < BookmarkedArray.length; i++) {

			if(BookmarkedArray[i]!="" && BookmarkedArray[i].endsWith('_' + agency)) {
				// if a value, create a new bookmark
				this.bookmarkedProperties[BookmarkedArray[i]] = new BookmarkedProperties(BookmarkedArray[i]);
				// Increment count
				this.bookmarkCount++;
			}
		}
		// Select the approprite checkboxes if they exist on the page.
		this.selectBookmarkedPropertiesAgency(agency);
	}
}

PortalApplication.prototype.selectBookmarkedPropertiesAgency = function(agency) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.selectBookmarkedProperties
		# DESCR:*		Selects the appropriate property checkboxes in the bookmarkedProperties object.
		# USAGE:*		Internal Function: Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Select the approprite checkboxes if they exist on the page.
	for(bookmark in this.bookmarkedProperties) {
		var element = $('OID_' + this.bookmarkedProperties[bookmark]);
		if (element) {
           	element.checked = true;
		}
	}
}

PortalApplication.prototype.numberBookMarkedPropertiesAgency = function(agency) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.selectBookmarkedProperties
		# DESCR:*		Selects the appropriate property checkboxes in the bookmarkedProperties object.
		# USAGE:*		Internal Function: Do Not Use.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	// Select the approprite checkboxes if they exist on the page.
    var count = 0;
	for(bookmark in this.bookmarkedProperties) {
        count++;	
	}
    return count;
}

PortalApplication.prototype.bookmarkPropertyAgency = function(e, orderid, agency) {

	/* 	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.bookmarkProperty
		# DESCR:*		Update the bookmarkCount, Display, highlight popup and right column tool
		# :*			and add the OrderID to the bookmarked cookie.
		# USAGE:*		PortalApp = new PortalApplication(); PortalApp.bookmarkProperty(e, orderid);
		# :*			Used in the Search Results display and the corresponding check box for each
		# :*			property displayed.
		# :*			e: event
		# :*			orderID: OrderID of property to bookmark
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */


	var displayString = "";
	var targ;
	if (!e) {
		var e = window.event;
	}

	if (e.target) {
		targ = e.target;
	} else if (e.srcElement) {
		targ = e.srcElement;
	}
    
	// add or removed if checked or not
	if(targ.checked) {
		this.bookmarkedProperties[orderid + '_' + agency] = new BookmarkedProperties(orderid + '_' + agency);
		this.bookmarkCount++;
	} else {
        //alert('orderid = ' + orderid);
		this.bookmarkedProperties[orderid + '_' + agency] = null;
		this.bookmarkCount--;
		if (this.bookmarkCount < 0) {
			this.bookmarkCount = 0;
		}
	}

	var saveString = this.bookmarkToString();
    this.savedSettings.createCookie('bookMarkedAgency', saveString);
}

PortalApplication.prototype.competition_setting = function() {

	/*	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.competition_setting
		# DESCR:*		Public funtion used to change the setting for the competition.
		# USAGE:*		PortalApp.autofitBg();
		# RETURNS:*		Returns nothing.
		# %ENDPUBLIC% */

	var contentHeight = $("contentContainer").offsetHeight;
	var primaryExists = $("competitionleft");
	if(primaryExists) {	
		var primaryHeight = $("competitionleft").offsetHeight + 195;
	}
	var secondaryExists = $("competitionright");
	if(secondaryExists) {	
		var secondaryHeight = $("competitionright").offsetHeight + 195;
	}
	var contentHeightTemp = contentHeight;
	
	if(primaryExists) {	
		if (contentHeightTemp < primaryHeight) {
			contentHeightTemp = primaryHeight;
		}
	}
	
	if(secondaryExists) {	
		if (contentHeightTemp < secondaryHeight) {
			contentHeightTemp = secondaryHeight;
		}
	}
	if (contentHeightTemp > contentHeight) {
		$("contentContainer").style.height = contentHeightTemp + "px";
	}
	
}

PortalApplication.prototype.ajaxLogout = function() {

	/*	# %PUBLIC%
		# NAME:*		PortalApplication.prototype.ajaxLogout
		# DESCR:*		Public funtion used to log a user out via ajax call.
		# USAGE:*		PortalApp.ajaxLogout();
		# RETURNS:*		Returns nothing.
		# %ENDPUBLIC% */

	var ts = new Date().getTime();
	var url = '/logout';
	var app = this;
	new Ajax.Request(url, {
		method: 'post',
		parameters: {rm: 'ajaxlogout', ts: ts},
			onSuccess: function() {
				setMyViewHeader(0);
				app.userID = 0;
				app.clearHistory('bookMarked', 1);
			}
	});
}

var alertBoxObj;
function alertBoxApplication(alertBoxDivID) {
	this.alertBoxDiv = $(alertBoxDivID);
	this.alertBoxDialogDiv = $(alertBoxDivID + 'dialog');
}

alertBoxApplication.prototype.show = function(heading, content, extraCloseJS) {

	if (!heading) { heading = 'An Error has occured!'; }
	if (!content) { content = 'There has been an unknown error.'; }

	var closeJS = 'alertBoxObj.hide();';
	if (extraCloseJS) {
		closeJS += extraCloseJS + ';';
	}
	closeJS += 'return false;';
	var topCloseButtonHtml = '<div class="closebutton" style="float:right;"><button type="submit" onclick="' + closeJS + '">&nbsp;</button></div>';
	var closeButtonHtml = '';

	this.alertBoxDialogDiv.innerHTML = '<div id="alertboxMessage"><h4 style="float:left;">' + heading + '</h4>' + topCloseButtonHtml + '<div class="clear"></div><p>' + content + '</p>' + closeButtonHtml + '</div>';

	// Adjust alert box background for page size
	var arrayPageSize = obtainPageSize();
	this.alertBoxDiv.style.width = arrayPageSize[2] + "px";
	this.alertBoxDiv.style.height = arrayPageSize[3] + "px";

	// Show the AlertBox
	showHideSelectControls(true);
	this.alertBoxDiv.style.display = "block";
	return false;
}

alertBoxApplication.prototype.hide = function() {

	// Hide the AlertBox
	this.alertBoxDiv.style.display = "none";
	showHideSelectControls();
	return false;
}

function showMyViewAlertBox(heading, content, extraCloseJS) {
	if (!alertBoxObj) {
		alertBoxObj = new alertBoxApplication('myviewalertbox');
	}
	alertBoxObj.show(heading, content, extraCloseJS);
}

function hideMyViewAlertBox() {
	if (alertBoxObj) {
		alertBoxObj.hide();
	}
}

// MyView Header Events
var menuTimeout;	// Timeout used so menu does not disappear when moving mouse to drop down list
function clearMyViewMenuTimer() {
	if (menuTimeout) {
		clearTimeout(menuTimeout);
	}
}
function setMyViewMenuTimer() {
	clearMyViewMenuTimer()
	menuTimeout = setTimeout("hideMyViewMenu()", 300);
}
function showMyViewMenu() {
	clearMyViewMenuTimer();
	$('myview-header-menu').style.display = 'block';
	$('myview-header-menu-state').removeClassName('myview-header-menu-closed');
	$('myview-header-menu-state').addClassName('myview-header-menu-open');
	$('myview-header-menu-link').addClassName('myview-header-link-selected');
}
function hideMyViewMenu() {
	clearMyViewMenuTimer();
	$('myview-header-menu').style.display = 'none';
	$('myview-header-menu-state').removeClassName('myview-header-menu-open');
	$('myview-header-menu-state').addClassName('myview-header-menu-closed');
	$('myview-header-menu-link').removeClassName('myview-header-link-selected');
}

// Assign events to MyView header
function setMyViewHeader(member) {
	if (!$('myview-header-links')) { return; }

	$$('#myview-header-links div.myview-header-link').each(function(div) {
		div.onmouseover = function() {
			this.addClassName('myview-header-link-selected');
			if (this.id == 'myview-header-menu-link') {
				showMyViewMenu();
			}
		}
		div.onmouseout = function() {
			this.removeClassName('myview-header-link-selected');
			if (this.id == 'myview-header-menu-link') {
				setMyViewMenuTimer();
			}
		}
	});
	var toHide = (member) ? $$('#myview-header-links div.public-link', '#myview-header-menu div.public-link') : $$('#myview-header-links div.member-link', '#myview-header-menu div.member-link');
	var toShow = (member) ? $$('#myview-header-links div.member-link', '#myview-header-menu div.member-link') : $$('#myview-header-links div.public-link', '#myview-header-menu div.public-link');
	toHide.each(function(div) { div.style.display = 'none'} );
	toShow.each(function(div) { div.style.display = 'block'} );

	$$('#myview-header-menu div.myview-menu-link').each(function(div) {
		div.onmouseover = function() {
			this.addClassName('myview-menu-link-selected');
			showMyViewMenu();
		}
		div.onmouseout = function() {
			this.removeClassName('myview-menu-link-selected');
			setMyViewMenuTimer();
		}
	});
}

function setMyViewCount(elements, count) {
	// Update individual element on the page with new count value (eg number of saved searches)
	if (elements && (count != undefined) && (count == 0 || count != '')) {
		count = count + '';
		elements.each(function(element) { element.innerHTML = count; });
	}
}

function setMyViewCounts(savedSearchCount, emailAlertsCount, shortlistCount) {
	// Set the on page counts of the member centre fields (eg number of saved searches)
	setMyViewCount($$('#myview-header-menu .searches-count', '#right-column-myview-links .searches-count'), savedSearchCount);
	setMyViewCount($$('#myview-header-menu .alerts-count', '#right-column-myview-links .alerts-count'), emailAlertsCount);
	setMyViewCount($$('.bookmark-count'), shortlistCount);
}

// Transforms all labels with class "inside", so they will appear inside the
// input field which they're for.
function transformInsideLabels() {
  $$('label.inside').each(function(label) {
    // get the element which this label is for
    var input = $(label.readAttribute('for'));
    if (input && ((input.tagName.toLowerCase() == 'input' && input.readAttribute('type').toLowerCase() == 'text') || input.tagName.toLowerCase() == 'textarea')) {
      
      if (input.labelValue == undefined) {
        input.labelValue = label.textContent || label.innerHTML; // textContent as of DOM 3
        input.styleInsideLabel = styleInsideLabel;
        input.styleInsideLabelWithFocus = styleInsideLabelWithFocus;
        
		input.styleInsideLabel();
        label.hide();

        input.observe('focus', input.styleInsideLabelWithFocus);
        input.observe('blur', input.styleInsideLabel);
      }
    }
  });

  $$('form').each(function(form) {
    if (!form.clearInsideLabelsTemporarly) {
      form.clearInsideLabelsTemporarly = clearInsideLabelsTemporarly;
      form.observe('submit', form.clearInsideLabelsTemporarly);

      // Change this form's serialize method to the one we define below
      form.serialize = Form.serialize.methodize()
    }
  });
}

// Assigns the correct css class and value to an input field with inside label
function styleInsideLabel() {
  this.removeClassName('focused');
  if (this.value) {
    this.addClassName('active');
    this.removeClassName('inactive');
  } else {
    this.addClassName('inactive');
    this.removeClassName('active');
    this.value = this.labelValue;
  }
}

// Assigns the correct css class and value to an input field with inside label which is focused
function styleInsideLabelWithFocus() {
  // Apply the correct css class
  this.addClassName('focused');
  this.removeClassName('active');
  this.removeClassName('inactive');
  if (this.value == this.labelValue) this.value = "";
}

// Clears all input field with inside labels, so they do not have the wrong value on submit
function clearInsideLabelsTemporarly() {
  this.descendants().each(function(input) {
    if (input.labelValue) {
      // This is an input field with inside label
      if (input.value == input.labelValue) {
        input.value = "";
        // reset value after a short while
        setTimeout(function() {
          input.styleInsideLabel();
        }, 10);
      }
    }
  });
}

// Serializes a form, but clears all inside labels before doing so
Form.Methods.serializeWithInsideLabelsRemoved = function(form, options) {
  if (form.clearInsideLabelsTemporarly) form.clearInsideLabelsTemporarly();
  return Form.serializeWithoutInsideLabelsRemoved(form, options);
};

// Alias method chain for the above
Form.Methods.serializeWithoutInsideLabelsRemoved = Form.Methods.serialize;
Form.Methods.serialize = Form.Methods.serializeWithInsideLabelsRemoved;
Object.extend(Form, Form.Methods);

function submit_login_data_in_ajax(portal_view) {

	var ts = new Date().getTime();
	var user_name = $('username').value;
	var password = $('password').value;
	var run_module = document.getElementById('run_module').value;
	var path = $('path').value;
	if (!user_name) {
		if (portal_view == 'property') {
			propertydata_alert_box("Error", "Please Enter username");
		} else {
			alertBox("Error", "Please Enter username");
		}
		return false;
	} else {
		if (!testEmailAddress(user_name)) {
			if (portal_view == 'property') {
				propertydata_alert_box("Error", "Please Enter a valid email address as a user name");
			} else {
				alertBox("Error", "Please Enter a valid email address as a user name");
			}
			return false;
		}
	}
	if (!password) {
		if (portal_view == 'property') {
			propertydata_alert_box("Error", "Please Enter passowrd");
		} else {
				alertBox("Error", "Please Enter passowrd");
		}	
		return false;
	}	
	var url = "/portal/" + path; 
	new Ajax.Request(url, {
			method: 'post',
			parameters: {authen_username: user_name, authen_password: password, rm: run_module, ts: ts},
  			onSuccess: function(transport) {
  				$('login').innerHTML = transport.responseText;
  			}
		});
}

function submit_logout_in_ajax() {
	var ts = new Date().getTime();
	var url = "/portal/propertydata";
	new Ajax.Request(url, {
			method: 'post',
			parameters: {rm: 'propertydata_logout', ts: ts},
  			onSuccess: function(transport) {
  				$('login').innerHTML = transport.responseText;
  				setMyViewHeader(0);
  			}
		});
}

/* PropertyData Popup Forms */
window.size = function()
{
	var w = 0;
	var h = 0;
	//IE
	if(!window.innerWidth)
	{
		//strict mode
		if(!(document.documentElement.clientWidth == 0))
		{
			w = document.documentElement.clientWidth;
			h = document.documentElement.clientHeight;
		}
		//quirks mode
		else
		{
			w = document.body.clientWidth;
			h = document.body.clientHeight;
		}
	}
	//w3c
	else
	{
		w = window.innerWidth;
		h = window.innerHeight;
	}
	return {width:w,height:h};
}
window.center = function()
{
	var hWnd = (arguments[0] != null) ? arguments[0] : {width:0,height:0};
	var _x = 0;
	var _y = 0;
	var offsetX = 0;
	var offsetY = 0;
	//IE
	if(!window.pageYOffset)
	{
		//strict mode
		if(!(document.documentElement.scrollTop == 0))
		{
			offsetY = document.documentElement.scrollTop;
			offsetX = document.documentElement.scrollLeft;
		}
		//quirks mode
		else
		{
			offsetY = document.body.scrollTop;
			offsetX = document.body.scrollLeft;
		}
	}
	//w3c
	else
	{
		offsetX = window.pageXOffset;
		offsetY = window.pageYOffset;
	}
	_x = ((this.size().width-hWnd.width)/2)+offsetX;
	_y = ((this.size().height-hWnd.height)/2)+offsetY;
	return {x:_x,y:_y};
}

function popup_report_form() {
	createPopUp();
	$('suburb_report_wrapper').innerHTML =  arguments[0];
	PortalApp.propertyDataSuburbAutocomplete('propertydatasub');
	$('suburb_report_container').setStyle({
		left: -(329/2)+'px',
		top: -(300/2)+'px'
	});

  		$('suburb_report_container').setStyle({
		height: '329px',
		width: '330px'
	});
	$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $('suburb_report_container').style.display = 'block';	
    $('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility =  $('suburb_report_container').style.visibility = 'visible';
    transformInsideLabels();
}

function enter_button_submit(report_type,e) {
	if (e.which==13) {
		return checkForm(report_type);
	}
}

function setStreetTypeFlag(streetElement, e) {
	var flag = $('propertydatastreettypeflag');
	if (flag) {
		var streetLength =  $(streetElement).value.strip().length;
		if (e.which == 8 || e.which == 46 ) { //if delete or backspace is pressed delete charater by 1
			streetLength--;
		} else {
			streetLength++;
		}
		flag.style.display = (streetLength > 0) ? 'inline' : 'none';
	}
}		

function createPopUp() {
	var D = document;
	viewportHeight =  Math.max(
		Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
		Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
		Math.max(D.body.clientHeight, D.documentElement.clientHeight) );
	viewportWidth =  Math.max(
		Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),
		Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),
		Math.max(D.body.clientWidth, D.documentElement.clientWidth) );

	var overlay = Element.extend(document.createElement('div'));
	overlay.setAttribute('id', 'suburb_report_overlay');		
	if (Prototype.Browser.Gecko) {
		overlay.setStyle({
			backgroundImage: 'url("/portalimages/alertbox/bg.png")',
			backgroundRepeat: 'repeat',
			height: viewportHeight+'px'
		});			
	} else {
		overlay.setStyle({
			opacity: '0.8',
			backgroundImage: 'url("/portalimages/alertbox/bg.png")',
			backgroundRepeat: 'repeat',
			height: viewportHeight+'px'
		});
	}
	var reportWindow = document.createElement('div');
	reportWindow.setAttribute('id', 'suburb_report_wrapper');
	var body = document.getElementsByTagName('body')[0];
	body.appendChild(overlay);
	body.appendChild(reportWindow);
	point = window.center({width:300,height:329})
	$('suburb_report_wrapper').setStyle({
		top: point.y  +'px',
		left: viewportWidth/2+'px'
	});	
}

function closePopUp() {
	$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $('suburb_report_container').style.display = 'none';	
    $('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility =  $('suburb_report_container').style.visibility = 'hidden';
}

function checkForm(report_type) {
	//$('error').innerHTML = "";
	var i = 0;
	var count = 0;
	var selected_suburb	 = '';
	var postcode = '';
	var need_an_error_check = '';
	var duplicate_suburb = $('duplicate_suburbs');
	var misspelt_suburb = $('misspelt_suburbs');

	// duplicate suburbs
	if (duplicate_suburb) {
		need_an_error_check = 1;
		selected_suburb = obtainRadioGroupValue('cart', 'duplicate_suburb');
	}

	// misspelt suburbs
	if (misspelt_suburb) {
		need_an_error_check = 1;
		selected_suburb = obtainRadioGroupValue('cart', 'misspelt_suburb');	 
	}

	if (selected_suburb) {
		//Separating postcode, state and suburb
		postcode = selected_suburb.match(/\d+/i);
		var suburb_state = selected_suburb.replace(/\d+$/i,'');
		var state_name = suburb_state.match(/nsw|tas|vic|sa|qld|act|nt|wa/i);
		var trimmed_suburb_state = suburb_state.replace(/\s+$/i,'');
		var suburb = trimmed_suburb_state.replace(/nsw|tas|vic|sa|qld|act|nt|wa$/i,'');
		$('propertydatasub').value = suburb;
		for (i=0; i < $('propertydatastate').length; i++) {
			if ($('propertydatastate')[i].value.toUpperCase() == state_name) {
				$('propertydatastate').selectedIndex = i;
			}
		}
	} else {
		if (need_an_error_check) {
			alert('Please select one suburb from the given options.');
			return false;
		}
	}

	var regex = /free|suburb|street|detailed/;
	if (regex.test(report_type)) {
		var suburb = $('propertydatasub').value.strip();
		if (!suburb || suburb == 'Insert Suburb') {
			alert('Please supply suburb.');
			return false;
		} else {
			var suburbs_list = suburb.split(",");
			if (suburbs_list.length > 1) {
				alert("Please enter only one suburb.");
				return false;
			}
			else if (isNumeric(suburb)) {
				alert("Please supply suburb name, not post code.");
				return false;
			}
		} 
		if (!$('propertydatastate').value ) {
			alert('Please select a state.');
			return false;
		}

		var regex2 = /free|suburb/;
		if (regex2.test(report_type)) {
			submit_report_form(['propertydatasub', 'propertydatastate', 'report_type', 'postcode__' + postcode,'NO_CACHE' ],[get_form_return]);
			$('pd-ajax-loading').style.visibility = 'visible';
			return true;
		}
	}

	regex = /street/;
	if (regex.test(report_type)) {
		if (!$('propertydatastreet').value ) {
			alert('Please supply street.');
			return false;
		}

		if ($('propertydatastreettype').value == 'select'|| $('propertydatastreettype').value == 'nothing') {
			alert('Please select street type.');
			return false;
		}				
		submit_report_form(['propertydatasub', 'propertydatastate', 'propertydatastreet', 'propertydatastreettype',
		                    'report_type', 'postcode__' + postcode, 'NO_CACHE'],[get_form_return]);
		$('pd-ajax-loading').style.visibility = 'visible';
		return true;
	}

	regex = /detailed/;
	if (regex.test(report_type)) {
		var property_type = document.cart.propertydatapropertytype;
		var total_property_types = property_type.length;

		var CheckBoxArrayValue = PortalApp.getCheckBoxInputArray('cart', 'propertydatapropertytype');
		//alert(CheckBoxArrayValue);
		$('propertydatapropertytypestr').value = CheckBoxArrayValue.join(',');
		//alert($('propertydatapropertytypestr').value);

		if ($('propertydatastreet').value && ($('propertydatastreettype').value == 'select'|| $('propertydatastreettype').value == 'nothing')) {
			alert('Please select street type.');
			return false;
		}

		/*
		for (i=0; i <= total_property_types -1; i++) {
			if (property_type[i].checked) {
				property_checked_flag = 1;
			}
		}

		if (!property_checked_flag) {
			alert('Please select at least one property type.');
			return false;
		}
		*/
		submit_report_form(['propertydatasub', 'propertydatastate', 'propertydatastreet', 'propertydatastreettype', 'propertydatapropertytypestr',
		                    'minbedrms' , 'maxbedrms', 'report_type', 'postcode__' + postcode, 'NO_CACHE'], [get_form_return]);

		$('pd-ajax-loading').style.visibility = 'visible';
		return true;
	}
}

function get_form_return() {

	var result = arguments[0];
	switch(result) {
		case 'step1':
			location.href = "/portal/shoppingcart?rm=viewcart";
			location.href;
			break;
		case 'nodata' :
			$('error').innerHTML = "Unfortunately we are unable to find any records<br>which match your search criteria below.<br>Please try modifying your search.";
			$('magic_div').style.visibility='visible';
			break;
		case 'duplicate':
			$('error').innerHTML = "Below selection criteria exists in your shopping cart.";
			$('magic_div').style.visibility='visible';
			break;
		default:
			$('error').innerHTML = result;
			$('magic_div').style.visibility='hidden';
	}

	$('pd-ajax-loading').style.visibility = 'hidden';
}
		
function forgot_password_popup() {

	var ts = new Date().getTime();
	createPopUp();
	
	new Ajax.Request('/login', {
			method: 'post',
			parameters: {rm: 'password_recovery', portalview: 'property',ts: ts},
  			onSuccess: function(transport) {
  				$('suburb_report_wrapper').innerHTML =  transport.responseText;
  				$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $('password_recover').style.display = 'block';	
				$('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = $('password_recover').style.visibility = 'visible';
  				
		
  			}
		});
}
function close_password_popup() {
	$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $('password_recover').style.display = 'none';	
    $('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = $('password_recover').style.visibility = 'hidden';
}
function password_request() {					// Organise send to Server
	var ts = new Date().getTime();
	var email = $('pwd_recovery_email').value.strip();
	var portal_view = $('portalview').value;
	if (!email) {
		alert('Please enter your email address');
	} else if (!testEmailAddress(email)) {
		alert('Your email address is not valid');
	} else {							// Stop rapid repeat clicks
		$('Message').style.color = '#606060';
		$('Message').innerHTML = 'Processing your request. Please wait..';	// Clear out any previous message

		new Ajax.Request('/login', {
			method: 'post',
			parameters: {rm: 'password_request', Email: email, portalview: portal_view, ts: ts},
  			onSuccess: function(transport) {
  			 	password_response(transport.responseText);		
  			}
		});
	}
	return false;
	}

function password_response(message) {		// Process results from Server - any 'message' is an error
	var color;
	if (message) {
		color = 'red';
	} else {
		message = 'Email sent successfully';
		color = 'green';
		new Effect.Fade('submit_button', { duration: 0 });
	}
	$('Message').style.color = color;
	$('Message').innerHTML = message;	// Display the message returned
}
		
function RestrictUserPopup() {
	/* 	# %PUBLIC%
		# NAME:*		RestrictUserPopup
		# DESCR:*		This popup restrict user to communicating with the webpage.
		# USAGE:*		RestrictUserPopup();
		# RETURNS:*		false. 
		# %ENDPUBLIC% */
		createPopUp();
		$('suburb_report_wrapper').appendChild($('pd-restrict-page'));
		error_handling_popup_open('pd-restrict-page');
}

function check_check_boxes(check_box_id,calling_check_box_id) {

	var check_box_group = document.getElementsByName(check_box_id);
	if ($(calling_check_box_id).checked) {
		for (i = 0; i < check_box_group.length; i++)
			check_box_group[i].checked = true ;
	} else {
		for (i = 0; i < check_box_group.length; i++)
			check_box_group[i].checked = false ;
	}		
}

function ucheck_check_boxes(check_box_id,calling_check_box_id) {
	var check_box_group = document.getElementsByName(check_box_id);
	var is_unchecked = 0;
	for (i = 0; i < check_box_group.length; i++) {
		if (check_box_group[i].checked == false) {
			is_unchecked = 1;
		}	
	}
	if (is_unchecked) {
		$(calling_check_box_id).checked = false;
	} else {
		$(calling_check_box_id).checked = true;
	}	
}

function error_handling_popup_open(error_div_id,ajax_return) {
	
	if (ajax_return) {
		$('suburb_report_wrapper').innerHTML =  ajax_return;
	}
	var left_value = $('suburb_report_wrapper').style.left;
	//remove px for value
	var filtered_left_value = left_value.replace(/px/,'');
	$('suburb_report_wrapper').style.left = (filtered_left_value - 100) + 'px';  
	
	if (error_div_id) {
		$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $(error_div_id).style.display = 'block';	
		$('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = $(error_div_id).style.visibility = 'visible';
	} else {
		$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = 'block';	
		$('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = 'visible';
	}
}

function error_handling_popup_close(error_div_id) {

	if (error_div_id) {
		$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = $(error_div_id).style.display = 'none';	
		$('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = $(error_div_id).style.visibility = 'hidden';
	} else {
		$('suburb_report_overlay').style.display = $('suburb_report_wrapper').style.display = 'none';	
		$('suburb_report_overlay').style.visibility = $('suburb_report_wrapper').style.visibility = 'hidden';
	}
}

function propertydata_alert_box(heading,message) {
	createPopUp();
	$('suburb_report_wrapper').appendChild($('error_handling'));
	error_handling_popup_open('error_handling');
	$('error_header').innerHTML = heading;
	$('error_description').innerHTML = message + '.';
}

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

// DoubleClick Floodlight Tag processing
function floodlightTrackerApplication(testServer) {

	/* 	# %PUBLIC%
		# NAME:*		floodlightTrackerApplication
		# DESCR:*		Floodlight Tracker Application constructor.
		# :*			Sets up the Javascript Floodlight Tracking Object,
		# USAGE:*		var floodlightTracker = new floodlightTrackerApplication(<tmpl_if LiveServerCheck>0<tmpl_else>1</tmpl_if>);
		# :*			Used in the portal page wrap template.
		# RETURNS:*		Nothing. 
		# %ENDPUBLIC% */

	this.testServer = (testServer) ? 1 : 0;
	this.baseDivID = 'floodlight_tracking';
	this.trackID = 0;
}

floodlightTrackerApplication.prototype.track = function(trackingURL, pageLoad) {

	/*	# %PUBLIC%
		# NAME:*		floodlightTrackerApplication.prototype.track
		# DESCR:*		Public funtion to action the tracking request.
		# USAGE:*		<a href="<destination url>" onClick="floodlightTracker.track(<tracking url> [,1]);">Link text</a>
		# :*			trackingURL - the url to use, pageLoad - true if called as part of page load
		# RETURNS:*		Returns true always.
		# %ENDPUBLIC% */

	// Floodlight tag urls use 'ord' param set to a random number to overcome caching
	// Given url may be complete and already include this - if not, add it
	if (!(/ord\=/.test(trackingURL))) {
		trackingURL += ';ord=' + (Math.random() * 10000000000000) + '?';
	}
	// If on a test server, change url to point to the test server
	if (this.testServer) {
		var file = (/ad\.au\.doubleclick/.test(trackingURL)) ? 'floodlight_tracking_image.gif' : 'floodlight_tracking_iframe.htm';
		trackingURL = '/test-tracking/' + file + '?url=' + trackingURL;
	}
	var divContent;
	// If url is of the form ad.au.doubleclick.net, we expect an image, else a page
	if (/ad\.au\.doubleclick/.test(trackingURL)) {
		divContent = '<img src="' +  trackingURL + '" width="1" height="1" alt="">';
	} else {
		divContent = '<iframe src="' +  trackingURL + '" width="1" height="1" frameborder="0" style="display:none"></iframe>';
	}
	// If page is loading, write a new element, else update an existing one (possibly creating it first)
	try {
		if (pageLoad) {
			document.write('<div style="display:none">' + divContent + '</div');
		} else {
			// Create the div to use with the tracking (unless it already exists) 
			var trackingDivID = this.baseDivID + '_' + this.trackID;
			this.trackID++;		// Don't use the same one twice
			if (!$(trackingDivID)) {
				var div = Element.extend(document.createElement('div'));
				div.setAttribute('id', trackingDivID);
				div.setStyle({display:'none'});
				var body = document.getElementsByTagName('body')[0];
				body.appendChild(div);
			}
			$(trackingDivID).update(divContent);
		}
	} catch(e) {}
	return true;
}

function shareHit(oid, type) {
	// Count a hit for social network share
	new Ajax.Request('/portal/sharehits', {
		method: 'GET',
		parameters: {OID:oid, type:type, ts:new Date().getTime()},
		onSuccess: function(){}
	});
}

