function implementsInterface(obj) {
	var prototypeObj={};
	for (var i=0; i<arguments.length; i++) {
		for (var method in arguments[i]) {
			prototypeObj[method]=arguments[i][method];
		}	
	}
	return prototypeObj;
}

function addObjectMethods(targetClass, methodObject) {
	for (var method in methodObject) {
		targetClass.prototype[method]=methodObject[method];
	}
}

//////////////////////////
// Interface Observable //
//////////////////////////

Observable = {
	addListener : function(listenerObj) {
		if (typeof this.listeners == 'undefined') {
			this.listeners=[];
		}
		for (var i=0; i<this.listeners.length; i++) {
			if (this.listeners[i]==listenerObj) return;
		}
		this.listeners[this.listeners.length]=listenerObj;
	},

	removeListener : function(listenerObj) {
		for (var i=0; i<this.listeners.length; i++) {
			if (this.listeners[i]==listenerObj) {
				this.listeners.splice(i,1);
				return;
			}
		}
	},
	
	notifyListeners : function (eventName,eventObj) {
		if (typeof this.listeners == 'undefined') return;
		for (var i=0; i< this.listeners.length; i++) {
			if (typeof this.listeners[i][eventName]!="undefined") {
				this.listeners[i][eventName](eventObj);
			}
		}
	}
};

////////////////
// Contstants //
////////////////


URLs = {
	HOME : "/",
	RESULTS : "/pregled",
	COMPARE : "/usporedjivac",
	FULL_SPECS : "/opis",
	NEW_PROJECTS : "/novi_projekti",
	AGENCIES : "/agencije",
	FAVORITES : "/favoriti",
	PERSONAL_ADS : "/moji_oglasi",
	STATIC_IMAGES_FOLDER: "/static/images/ui/icons/",
	
	storeReferrer: function (modifiedSearchString) {
		for (var key in this) {
			if (typeof this[key] == "string" && this[key]==window.location.pathname) {
				Cookies.store("historyPathName",key);
				if (typeof modifiedSearchString == "undefined") {
					Cookies.store("historySearchString",encodeURIComponent(window.location.search));
				} else {
					Cookies.store("historySearchString",encodeURIComponent(modifiedSearchString));
				}
			}
		}
	},
	
	getReferrer: function () {
		var searchString=(decodeURIComponent(Cookies.getValue("historySearchString"))=="undefined")? "":decodeURIComponent(Cookies.getValue("historySearchString")); 
		if (this.getReferrerKey()!==false) return this[this.getReferrerKey()]+searchString;
		return false;
	},
	
	getReferrerKey: function () {
		return Cookies.getValue("historyPathName");
	},
	
	clearSearchString : function () {
		Cookies.store("historySearchString","");
	},
	
	setSearchString : function (searchString) {
		Cookies.store("historySearchString",searchString);
	}
};

Regions = {
	HRVATSKA: {id:0, name: "Hrvatska"},
	ZAGREB : {id:1, name: "Zagreb i okolica"},
	SLAVONIJA : {id:2, name: "Slavonija"},
	ISTRA : {id:3, name: "Istra"},
	KVARNER : {id:4, name: "Kvarner"},
	DALMACIJA_ZD : {id:5, name: "Dalmacija - Zadar"},
	DALMACIJA_SI : {id:6, name: "Dalmacija - Å ibenik"},
	DALMACIJA_ST : {id:7, name: "Dalmacija - Split"},
	DALMACIJA_DU : {id:8, name: "Dalmacija - Dubrovnik"},
	SREDNJA_HR : {id:9, name: "Srednja Hrvatska"},
	
	getRegionNameById: function (id) {
		for (var key in this) {
			if (typeof this[key].id!= "undefined" && this[key].id==id) return this[key].name;
		}
		return false;
	}
};

RealEstateCategories = {
	ss: {name: "stan"}, sk: {name: "kuÄ‡a"}, sg: {name: "garaÅ¾a"}, 
	pu: {name: "ured / ordinacija"}, pl: {name: "lokal"}, pr: {name: "restoran"}, ps: {name: "skladiÅ¡te"}, ph: {name: "hotel"},
	zg: {name: "graÄ‘evinsko zemljiÅ¡te"}, zp: {name: "poljoprivredno zemljiÅ¡te"}
};

URLParameters= {
	init: function () {
		var parameterValueString, parameterValueArray;
		this.parameterObject={};
		parameterValueString=window.location.search.substring(1).split("&");
		for (var i=0; i<parameterValueString.length; i++) {
			parameterValueArray=parameterValueString[i].split("=");
			this.parameterObject[parameterValueArray[0]]=parameterValueArray[1];
		}
	},
	
	getValue: function (parameterName) {
		if (typeof this.parameterObject =="undefined") this.init();
		if (typeof this.parameterObject[parameterName] =="undefined") {
			return false;
		} else {
			return this.parameterObject[parameterName];
		}
	}
};


////////////////////////////
// Class FinderParameters //
////////////////////////////

/* broadcasts events:
onAdTypeChange - if at attribute has changed
onLocationChange - if r or l or k attribute has changed
onRealEstateTypeChange - if t attribute has changed
onPriceChange - if p attributte has changed
onRealEstateSizeChange - if s attributte has changed
onMapViewChange - if latn or lats or lngw or lnge have/has changed
onResultsPageChange - if pg has changed
onResultsOrderChange - if o has changed
onRoomNumberChange - if nr has changed
onAgencyChange - if a has changed
onAnyChange - if any of parameters has changed
*/

function FinderParameters(parameters) {
	this.parameters={};
	this.locationParameters=new Array("r","l","k","latn","lats","lngw","lnge");
	this.parameterChangeHandlers={at:"onAdTypeChange", r:"onLocationChange", l:"onLocationChange", k:"onLocationChange", t:"onRealEstateTypeChange", p:"onPriceChange", s:"onRealEstateSizeChange", latn: "onMapViewChange", lats: "onMapViewChange", lngw: "onMapViewChange", lnge: "onMapViewChange", pg: "onResultsPageChange", o:"onResultsOrderChange", nr:"onRoomNumberChange", a:"onAgencyChange"};
	if (arguments.length>0) {
		this.initParameters(parameters);
	}
}

FinderParameters.prototype=implementsInterface(Observable);

// private

FinderParameters.prototype.getParameterObject = function (urlString) {
	var parameterObject,parameterValueString, parameterValueArray;
	parameterObject={};
	parameterValueString=urlString.split("&");
	for (var i=0; i<parameterValueString.length; i++) {
		parameterValueArray=parameterValueString[i].split("=");
		parameterObject[parameterValueArray[0]]=parameterValueArray[1];
	}
	return parameterObject;
};

// parameters - parameterObject or urlString 

FinderParameters.prototype.initParameters=function(parameters) {
	var parameterObject;
	if (typeof parameters == "string") {
		parameterObject=this.getParameterObject(parameters);
	} else {
		parameterObject=parameters;
	}
	for (var parameter in parameterObject) {
		this.parameters[parameter]=parameterObject[parameter];
	}
	SearchPreferences.storeParametersURLString(this.getURLString());
};

/* 
parameterList - Array which contains property names of interest
oldParameterValues - Object, {parameter1: oldValue, parameter2: oldValue,...}
newParameterValues - Object, {parameter1: newValue, parameter2: newValue,...}

returns eventObject - {lastParameter: boolean, parameter1 : {oldValue: p1OldValue, newValue: p1NewValue},... }
parameter1, parameter2 are from parameterList
*/

FinderParameters.prototype.getEventObject=function (parameterList, oldParameterValues, sourceObject) {
	var parameterValuePair;
	var parameter;
	var eventObject={};
	for (var i=0; i<parameterList.length; i++) {
		parameter=parameterList[i];
		parameterValuePair= {};
		if (typeof oldParameterValues[parameter] == "undefined") {
			parameterValuePair.oldValue="";
		} else {
			parameterValuePair.oldValue=oldParameterValues[parameter];
		}
		if (typeof this.parameters[parameter] == "undefined") {
			parameterValuePair.newValue="";
		} else {
			parameterValuePair.newValue=this.parameters[parameter];
		}
		eventObject[parameter]=parameterValuePair;
	}
	eventObject.source=sourceObject;
	return eventObject;
};

FinderParameters.prototype.isInArray=function (array,arrayElement) {
	for (var i=0; i<array.length; i++) {
		if (array[i]==arrayElement) return true;
	}
	return false;
};

FinderParameters.prototype.storeHandler=function (eventHandlerList, parameter) {
	if (typeof this.parameterChangeHandlers[parameter]!="undefined" && !this.isInArray(eventHandlerList,this.parameterChangeHandlers[parameter])) {
		eventHandlerList.push(this.parameterChangeHandlers[parameter]);
	}
	return eventHandlerList;
};

FinderParameters.prototype.storeParameterValue=function (parametersValues, parameter) {
	if (typeof this.parameters[parameter] != "undefined") {
		parametersValues[parameter]=this.parameters[parameter];
	}
	return parametersValues;
};

FinderParameters.prototype.isLocationParameter=function (parameter) {
	return this.isInArray(this.locationParameters,parameter);
};

FinderParameters.prototype.getLocationParametersObject=function() {
	var locationParametersObject={};
	if (typeof this.parameters["latn"] != "undefined") {
		locationParametersObject["latn"]=this.parameters["latn"];
		locationParametersObject["lats"]=this.parameters["lats"];
		locationParametersObject["lngw"]=this.parameters["lngw"];
		locationParametersObject["lnge"]=this.parameters["lnge"];
	} else if (typeof this.parameters["k"] != "undefined") {
		locationParametersObject["k"]=this.parameters["k"];
	} else if (typeof this.parameters["l"] != "undefined") {
		locationParametersObject["l"]=this.parameters["l"];
	} else {
		locationParametersObject["r"]=this.parameters["r"];
	}
	return locationParametersObject;
};

// end of private

/* setParametersList - {parameter:value,...}
unsetParametersList - [parameter1, parameter2]
*/

FinderParameters.prototype.setParameters=function (sourceObject,setParametersList,unsetParametersList) {
	var eventObject;
	var deleteParametersList;
	var eventHandlerList=[];
	var parameterList=[]; // list of changing parameters
	var oldParametersValues={};
	if (arguments.length>2) {
		deleteParametersList=unsetParametersList;
	} else {
		deleteParametersList=[];
	}
		
	if ((typeof setParametersList.r !="undefined") || (typeof setParametersList.l !="undefined") || (typeof setParametersList.k !="undefined")) {
		deleteParametersList=deleteParametersList.concat(new Array("latn","lats","lngw","lnge"));
	}
	
	for (var parameter in setParametersList) {
		if (!this.isInArray(parameterList,parameter)) parameterList.push(parameter);	
		eventHandlerList=this.storeHandler(eventHandlerList, parameter);
		oldParametersValues=this.storeParameterValue(oldParametersValues, parameter);
		this.parameters[parameter]=setParametersList[parameter];		
	}

	for (var i=0; i<deleteParametersList.length; i++) {
		var parameter=deleteParametersList[i];
		if (!this.isInArray(parameterList,parameter)) parameterList.push(parameter);
		eventHandlerList=this.storeHandler(eventHandlerList, parameter);
		oldParametersValues=this.storeParameterValue(oldParametersValues, parameter);
		if (typeof this.parameters[parameter]!="undefined") {
			delete this.parameters[parameter];
		}
	}		
	SearchPreferences.storeParametersURLString(this.getURLString());
	eventObject=this.getEventObject(parameterList,oldParametersValues,sourceObject);
	
	//eventObject.lastParameter=false;
	for (var i=0; i<eventHandlerList.length; i++) {
		//if (i==eventHandlerList.length-1) eventObject.lastParameter=true;
		this.notifyListeners(eventHandlerList[i],eventObject);
	}
	this.notifyListeners("onAnyChange",eventObject);
};

FinderParameters.prototype.getParameterValue=function(parameter) {
	return (typeof this.parameters[parameter] != "undefined") ? this.parameters[parameter] : false;
};

// parameterList - optional array of parameters

FinderParameters.prototype.getURLString=function(parameterList) {
	var locationParametersObject = {};
	var parametersObject={};
	var parameterValuePairs=[];
	var locationParamatersAreSet=false;
	
	if (typeof parameterList== "undefined") {
		parametersObject=this.parameters;
	} else {
		for (var i=0; i<parameterList.length; i++) {
			if (!this.isLocationParameter(parameterList[i])) {
				if (typeof this.parameters[parameterList[i]]!="undefined") {
					parametersObject[parameterList[i]]=this.parameters[parameterList[i]];
				}
			} else {
				if (!locationParamatersAreSet) {
					locationParametersObject=this.getLocationParametersObject();
					for (var locParameters in locationParametersObject) {
						parametersObject[locParameters]=locationParametersObject[locParameters];
					}
					locationParamatersAreSet=true;
				}
			}
		}
	}
	for (var parameter in parametersObject) {
		parameterValuePairs.push(parameter+"="+encodeURIComponent(parametersObject[parameter]));
	}
	return parameterValuePairs.join("&");
};

/////////////////////////////
// Class SearchPreferences //
/////////////////////////////

var SearchPreferences={};

SearchPreferences.retrieveMapSize=function() {
	return Cookies.getValue("mapsize");
};

SearchPreferences.storeMapSize=function(mapSize) {
	Cookies.store("mapsize",mapSize);
};

SearchPreferences.retrieveMapType=function() {
	var value=Cookies.getValue("maptype");
	if (value===false) {
		return value;
	} else {
		return parseInt(value);
	}
};

SearchPreferences.storeMapType=function(mapType) {
	Cookies.store("maptype",mapType);
};

SearchPreferences.retrieveParametersURLString=function() {
	return Cookies.getValue("fparam");
};

SearchPreferences.storeParametersURLString=function(URLString) {
	Cookies.store("fparam",URLString);
};

SearchPreferences.retrieveCityName=function() {
	return Cookies.getValue("city_name");
};

SearchPreferences.storeCityName=function(cityName) {
	Cookies.store("city_name",cityName);
};

//////////////////////////////////
// Interface RangeFieldsBuilder //
//////////////////////////////////

/* initValue: string "lowerValue-upperValue" */

RangeFieldsBuilder= {
	
	makeRangeFields : function (lowerInputElement,upperInputElement,initValue,parameter,finderParametersObj) {
		
		var obj=this;
		
		this.setRangeFieldsValue(lowerInputElement,upperInputElement,initValue);
		
		var onChangeHandler=function() {
			var setParameterList={};
			var unsetParameterList=[];
			var fixedValues=obj.fixRangeFieldsValues(lowerInputElement,upperInputElement);
			
			if (fixedValues!="") {
				setParameterList[parameter]=fixedValues;
				finderParametersObj.setParameters(obj,setParameterList);
			} else {
				unsetParameterList.push(parameter);
				finderParametersObj.setParameters(obj,{},unsetParameterList);
			}
		}
		DOMEvent.addDomListener(lowerInputElement,"change", onChangeHandler);
		DOMEvent.addDomListener(upperInputElement,"change", onChangeHandler);
	},

	setRangeFieldsValue : function (lowerInputElement,upperInputElement,initValue) {
		var lowerFieldValue,upperFieldValue,valueArray;
		valueArray=initValue.split("-");
		lowerFieldValue=valueArray[0];
		if (valueArray.length>1) {
			upperFieldValue=valueArray[1];
		} else {
			upperFieldValue="";
		}
		lowerInputElement.value=lowerFieldValue;
		upperInputElement.value=upperFieldValue;
	},
	
	fixRangeFieldsValues : function (lowerInputElement,upperInputElement) {
		var lowerValue, upperValue, fixedValue;
		lowerValue=isNaN(parseInt(lowerInputElement.value))? "" :parseInt(lowerInputElement.value);
		upperValue=isNaN(parseInt(upperInputElement.value))? "" :parseInt(upperInputElement.value);
		if (typeof lowerValue !="string" && typeof upperValue !="string") {
			fixedValue=Math.min(lowerValue,upperValue)+"-"+Math.max(lowerValue,upperValue);
		} else if (typeof lowerValue !="string" || typeof upperValue !="string"){
			fixedValue=lowerValue+"-"+upperValue;
		} else {
			fixedValue="";
		}
		this.setRangeFieldsValue(lowerInputElement,upperInputElement,fixedValue);
		return fixedValue;
	}
};


////////////////////////////////
// Interface DropDownSelector //
////////////////////////////////

DropDownSelector = {
	setSelected : function (selectionElement, selectedValue) {
		if (selectedValue) {
			for (var i=0; i<selectionElement.length; i++) {
				if (selectionElement.options[i].value==selectedValue) {
					selectionElement.options[i].selected=true;
					return true;
				}
			}
		}
	},
	
	getSelectedValue : function (selectionElement) {
		var selectedIndex;
		selectedIndex=selectionElement.selectedIndex;
		if (selectedIndex == -1) return false;
		return selectionElement.options[selectedIndex].value;
	},
	
	addOption : function (selectionElement, optionLabel, optionValue) {
		var newOptionElement;
		newOptionElement=document.createElement("option");
		newOptionElement.appendChild(document.createTextNode(optionLabel));
		newOptionElement.value=optionValue;
		selectionElement.appendChild(newOptionElement);
	},
	
	clearOptions : function (selectionElement) {
		while(selectionElement.hasChildNodes()) {
			selectionElement.removeChild(selectionElement.firstChild);
		}
	}
};

//////////////////////////////
// Class RealEstateTypeMenu //
//////////////////////////////

function RealEstateTypeMenu(selectorElement,initValue,finderParametersObj) {
	var obj=this;
	this.setSelected(selectorElement,initValue);
	DOMEvent.addDomListener(selectorElement,"change", function () {
		var parameterObject={};
		parameterObject["t"]=selectorElement.value;
		finderParametersObj.setParameters(obj,parameterObject);	
	});
}

RealEstateTypeMenu.prototype=implementsInterface(DropDownSelector);

//////////////////////
// Class FinderMenu //
//////////////////////

/* FinderMenu conventions: 
- use unordered list as menu container
- li elements ids naming convention: [ul element id][value]

ulContainerElement parameter - ul element or array of ul elements
onSelectHandler (previousValue,currentValue, ulContainerElement) - executes if one of elements is clicked

*/

function FinderMenu(ulContainerElement, initValue, onSelectHandler) {
	this.onSelectHandler=onSelectHandler;
	this.listItems=[]; 
	// listitem = {element: [li element], value: [value], container: [ul element that holds li], mouseOverHandler: [handler], mouseOutHandler: [handler], clickHandler: [handler]}
	this.selectedItem=null;
	this.init(ulContainerElement,initValue);
}

FinderMenu.prototype.init=function (ulContainerElement,initValue) {
	var currentListItem,currentContainer,containers,listItemId,containerId;
	if (ulContainerElement.constructor==Array) {
		containers=ulContainerElement;
	} else {
		containers=[];
		containers.push(ulContainerElement);
	}
	for (var j=0; j<containers.length; j++) {
		currentContainer=containers[j];
		containerId=currentContainer.getAttribute("id");
		for (var i=0; i<currentContainer.childNodes.length; i++) {
			if (currentContainer.childNodes[i].nodeType==1) {
				if (currentContainer.childNodes[i].nodeName=="LI") {
					currentListItem={};
					currentListItem.element=currentContainer.childNodes[i];
					listItemId=currentListItem.element.getAttribute("id");
					currentListItem.value=listItemId.slice(containerId.length);
					currentListItem.container=currentContainer;
					currentListItem.mouseOverHandler=null;
					currentListItem.mouseOutHandler=null;
					currentListItem.clickHandler=null;
					this.listItems.push(currentListItem);				
					if (currentListItem.value==initValue) {
						this.setSelected(currentListItem);
					}
				}
			}
		}
	}
	this.initListHandlers();
};

FinderMenu.prototype.initListHandlers=function() {
	var obj=this;
	for (var i=0; i<this.listItems.length;i++) {
		(function () {
			var j=i;
			obj.initListItemHandlers(obj.listItems[j]);
		}
		)();
	}
};

FinderMenu.prototype.initListItemHandlers=function (listItem) {
	var obj=this;
	if (listItem.mouseOverHandler===null) {
		listItem.mouseOverHandler=DOMEvent.addDomListener(listItem.element,"mouseover", function(e) {
			obj.displaySelected(listItem);
		});
	}
	if (listItem.mouseOutHandler===null) {
		listItem.mouseOutHandler=DOMEvent.addDomListener(listItem.element,"mouseout", function(e) {
			if (listItem!=obj.selectedItem) {
				obj.displayNotSelected(listItem);
			}
		});
	}
	if (listItem.clickHandler===null) {
		listItem.clickHandler=DOMEvent.addDomListener(listItem.element,"click", function(e) {
			var previousSelectedValue=null;
			if (obj.selectedItem!==null) {
				previousSelectedValue=obj.selectedItem.value;
				obj.displayNotSelected(obj.selectedItem);
			}			
			obj.setSelected(listItem);
			if (typeof obj.onSelectHandler!="undefined") {
				obj.onSelectHandler(previousSelectedValue,listItem.value,listItem.container);
			}
		});		
	}	
};

FinderMenu.prototype.getListItem=function (value) {
	for (var i=0; i<this.listItems.length; i++) {
		if (this.listItems[i].value==value) {
			return this.listItems[i];
		}
	}
	return false;
};

FinderMenu.prototype.refresh=function (value) {
	var listItem;
	listItem=this.getListItem(value);
	if (listItem!==false && this.selectedItem!==null) {
		this.displayNotSelected(this.selectedItem);
		this.setSelected(listItem);
	}
};

FinderMenu.prototype.deleteAllListItemHandlers=function() {
	for (var i=0; i<this.listItems.length; i++) {
		this.deleteListItemHandlers(this.listItems[i]);
	}
};

FinderMenu.prototype.deleteListItemHandlers=function (listItem) {
	if (listItem.mouseOverHandler!==null && listItem.mouseOutHandler!==null && listItem.clickHandler!==null) {
		DOMEvent.removeListener(listItem.mouseOverHandler);
		listItem.mouseOverHandler=null;
		DOMEvent.removeListener(listItem.mouseOutHandler);
		listItem.mouseOutHandler=null;
		DOMEvent.removeListener(listItem.clickHandler);
		listItem.clickHandler=null;
	}
};

FinderMenu.prototype.getSelectedValue=function() {
	if (this.selectedItem!==null) return this.selectedItem.value;
	return false;
};

FinderMenu.prototype.setSelected=function (listItem) {
	this.selectedItem=listItem;
	this.displaySelected(listItem);
};

FinderMenu.prototype.unselectAll=function() {
	if (this.selectedItem==null) return;
	this.displayNotSelected(this.selectedItem);
	this.selectedItem=null;
	this.deleteAllListItemHandlers();
	this.initListHandlers();
};

FinderMenu.prototype.displaySelected=function (listItem) {
	DHTMLApi.CSS.setClass(listItem.element,new Array("selected"),[]);
};

FinderMenu.prototype.displayNotSelected=function (listItem) {
	DHTMLApi.CSS.setClass(listItem.element,[],new Array("selected"));
};

FinderMenu.prototype.clearItems=function(ulContainerElement) {
	this.deleteAllListItemHandlers();
	while(ulContainerElement.hasChildNodes()) {
		ulContainerElement.removeChild(ulContainerElement.firstChild);
	}
	this.listItems=[];
};

FinderMenu.prototype.addItem=function(ulContainerElement,itemLabel,value) {
	var itemElement,newListItem;
	itemElement=document.createElement("li");
	itemElement.appendChild(document.createTextNode(itemLabel));
	ulContainerElement.appendChild(itemElement);
	newListItem={};
	newListItem.element=itemElement;
	newListItem.value=value;
	newListItem.container=ulContainerElement;
	newListItem.mouseOverHandler=null;
	newListItem.mouseOutHandler=null;
	newListItem.clickHandler=null;
	this.listItems.push(newListItem);
	this.initListItemHandlers(newListItem);
};

/////////////////////
// Class QuickLink //
/////////////////////

function QuickLink(element,destURL,finderParametersObj,setParametersObject,unsetParametersArray) {
	var obj=this;
	DOMEvent.addDomListener(element,"click", function(e) {
		if (typeof unsetParametersArray == "undefined") unsetParametersArray=[];
		finderParametersObj.setParameters(obj,setParametersObject,unsetParametersArray);
		window.location.href=destURL;
		DOMEvent.preventDefault(e);
	});	
}

/////////////////////////////
// Class AutoCompleteField //
/////////////////////////////

/* parameters: 

HTMLElements = {inputFieldContainer : Node, inputField : Node}
CSSClasses = {sugestionContainerClassName : string, suggestionListClassName: string, suggestionItemSelectedClassName: string}
options = {minChars: int, numOfSuggestionsDisplayed: int, caseSensitive: boolean, defaultValue: string}
handlers = {onSelectSuggestion: function (suggestionObject), onUnselectSuggestion: function (), getRequestParamString: function () }

suggestionObject= {inp : string, val : Object}

*/	

function AutoCompleteField(HTMLElements, CSSClasses, suggestionsDataUrl , handlers, options) {
	this.inputFieldContainer=HTMLElements.inputFieldContainer;
	this.inputField=HTMLElements.inputField;
	if (typeof options.defaultValue!= "undefined" ) this.inputField.value=options.defaultValue;
	this.suggestionContainer=null;
	this.suggestionList=null;
	this.CSSClasses=CSSClasses;
	this.suggestionsDataUrl=suggestionsDataUrl;
	this.onSelectSuggestion=handlers.onSelectSuggestion || function(suggestionObject) {};
	this.onUnselectSuggestion=handlers.onUnselectSuggestion || function() {};
	this.getRequestParamString=handlers.getRequestParamString || function() { return "";};
	this.requestingData=false;
	this.allSuggestions=null;
	this.filteredSuggestions=null;
	this.requestString=null;
	this.suggestionIsChosen=false;
	this.suggestionNumSelected=0;
	this.minChars=options.minChars || 2;
	this.caseSensitive=options.caseSensitive || false;
	this.numOfSuggestionsDisplayed=options.numOfSuggestionsDisplayed || 5;
	this.makeSuggestionList(CSSClasses.sugestionContainerClassName,CSSClasses.suggestionListClassName);
	this.init();
}

AutoCompleteField.prototype.init=function() {
	var obj=this;
	var matchSuggestionObject;
	
	DOMEvent.addDomListener(this.inputField,"keydown",function (e) {
		
		// up key
		
		if (e.keyCode == 38) {
			if (obj.suggestionNumSelected==0 || obj.suggestionNumSelected==1) {
				obj.suggestionNumSelected=1;
			} else {
				obj.suggestionNumSelected--;
			}
			obj.onKeySelection(obj.suggestionNumSelected);
		} else 
		
		// down key
		
		if (e.keyCode == 40) {
			if (obj.suggestionNumSelected==0) {
				obj.suggestionNumSelected=1;
			} else if (obj.filteredSuggestions.length!=obj.suggestionNumSelected) {
				obj.suggestionNumSelected++;
			}
			obj.onKeySelection(obj.suggestionNumSelected);
		} else
		
		// enter key
		
		if (e.keyCode == 13) {
			if (obj.suggestionNumSelected!=0) {
				var suggestNum=obj.filteredSuggestions[obj.suggestionNumSelected-1];
				obj.chooseSuggestion(obj.allSuggestions[suggestNum]);
			} else {
				if (obj.filteredSuggestions.length==1) {
					var suggestNum=obj.filteredSuggestions[0];
					obj.chooseSuggestion(obj.allSuggestions[suggestNum]);
				} else if (obj.filteredSuggestions.length>1) {
					var suggestionObject=obj.getMatchedSuggestionObject(obj.inputField.value);
					if (suggestionObject !== false) {
						obj.chooseSuggestion(suggestionObject);
					}
				}
				obj.hideSuggestionList();
			}
		}
	});
		
	DOMEvent.addDomListener(this.inputField,"keyup",function (e) {																
		
		if (e.keyCode == 38 || e.keyCode == 40) return;
		
		obj.hasTyped=true;
		
		if (obj.inputField.value.length<obj.minChars) {
			obj.suggestionIsChosen=false;
			obj.clearSuggestions();
			obj.hideSuggestionList();
			obj.onUnselectSuggestion();
		} else {
			obj.suggestionIsChosen=false;
			if (obj.allSuggestions===null) {
				if (!obj.requestingData) {
					obj.requestData(obj.inputField.value);
				}
			} else {
				if (obj.hasRequestStringChanged(obj.inputField.value)) {
					obj.requestData(obj.inputField.value);
				} else {
					obj.filteredSuggestions=obj.getFilteredSuggestions(obj.inputField.value);
					obj.displaySuggestionList();
					obj.onUnselectSuggestion();
					matchSuggestionObject=obj.getMatchedSuggestionObject(obj.inputField.value);
						if (matchSuggestionObject!==false && obj.filteredSuggestions.length==1) {
						obj.onSelectSuggestion(matchSuggestionObject);
						obj.hideSuggestionList();
					}
				}
			}
		}
	});
	
	DOMEvent.addDomListener(this.inputField,"click",function (e) {
		obj.hideSuggestionList();
	});
	
	if (this.inputField.value.length>=this.minChars) {
		this.requestData(this.inputField.value);
	}
};

AutoCompleteField.prototype.setValue=function (textValue) {
	this.inputField.value=textValue;
	if (this.inputField.value.length>=this.minChars) {
		this.requestData(this.inputField.value);
	}
};

AutoCompleteField.prototype.makeSuggestionList=function (sugestionContainerClassName,suggestionListClassName) {
	this.suggestionContainer=document.createElement("DIV");	
	this.suggestionList=document.createElement("UL");
	this.suggestionContainer.appendChild(this.suggestionList);
	this.inputFieldContainer.appendChild(this.suggestionContainer);
	DHTMLApi.CSS.setClass(this.suggestionContainer, new Array(sugestionContainerClassName),[]);
	DHTMLApi.CSS.setClass(this.suggestionList,new Array(suggestionListClassName),[]);
	DHTMLApi.Visibility.hide(this.suggestionContainer);
};

AutoCompleteField.prototype.getListElement=function(suggestionObject) {
	var obj=this;
	var listEntryElement=document.createElement("LI");	
	listEntryElement.appendChild(document.createTextNode(suggestionObject.inp));
	DOMEvent.addDomListener(listEntryElement,"click",function () {
		obj.chooseSuggestion(suggestionObject);
	});
	DOMEvent.addDomListener(listEntryElement,"mouseover",function () {
		DHTMLApi.CSS.setClass(listEntryElement,new Array(obj.CSSClasses.suggestionItemSelectedClassName),[]);});
	DOMEvent.addDomListener(listEntryElement,"mouseout",function () {
		DHTMLApi.CSS.setClass(listEntryElement,[],new Array(obj.CSSClasses.suggestionItemSelectedClassName));});
	return listEntryElement;
};

AutoCompleteField.prototype.displaySuggestionList=function() {
	var numOfSuggestions,suggestionEntryHeight;
	this.suggestionNumSelected=0;
	while(this.suggestionList.hasChildNodes()) this.suggestionList.removeChild(this.suggestionList.firstChild);
	numOfSuggestions=this.filteredSuggestions.length;
	if (numOfSuggestions==0) {
		DHTMLApi.Visibility.hide(this.suggestionContainer);
	} else {
		for (var i=0; i<numOfSuggestions; i++) {
			this.suggestionList.appendChild(this.getListElement(this.allSuggestions[this.filteredSuggestions[i]]));
		}
		DHTMLApi.Visibility.show(this.suggestionContainer);
		suggestionEntryHeight=DHTMLApi.Size.getElementHeight(this.suggestionList.getElementsByTagName("LI")[0]);		
		if (numOfSuggestions>this.numOfSuggestionsDisplayed) {	
			this.suggestionContainer.style.height=suggestionEntryHeight*this.numOfSuggestionsDisplayed+"px";
		} else {
			this.suggestionContainer.style.height=suggestionEntryHeight*numOfSuggestions+"px";
		}
	}
};

AutoCompleteField.prototype.onKeySelection=function (itemListNum) {
	var selectedItem=this.suggestionList.getElementsByTagName("LI")[itemListNum-1];
	DHTMLApi.CSS.setClass(selectedItem,new Array(this.CSSClasses.suggestionItemSelectedClassName),[]	);
	if (selectedItem.nextSibling!==null) {
		DHTMLApi.CSS.setClass(selectedItem.nextSibling,[],new Array(this.CSSClasses.suggestionItemSelectedClassName));
	}
	if (selectedItem.previousSibling!==null) {
		DHTMLApi.CSS.setClass(selectedItem.previousSibling,[],new Array(this.CSSClasses.suggestionItemSelectedClassName));
	}
};

AutoCompleteField.prototype.chooseSuggestion=function(suggestionObject) {
	this.suggestionIsChosen=true;
	if (this.hasRequestStringChanged(suggestionObject.inp)) {
		this.requestData(suggestionObject.inp);
	}
	this.inputField.value=suggestionObject.inp;
	this.inputField.blur();
	this.onSelectSuggestion(suggestionObject);
	this.hideSuggestionList();
};

AutoCompleteField.prototype.hideSuggestionList=function() {
	DHTMLApi.Visibility.hide(this.suggestionContainer);
};

AutoCompleteField.prototype.clearSuggestions=function() {
	this.allSuggestions=null;
	this.filteredSuggestions=null;
	this.requestingData=false;
};

AutoCompleteField.prototype.getFilteredSuggestions=function(filterString) {
	var suggestionInput;
	var filteredSuggestionsArray=[];
	if (!this.caseSensitive) filterString=filterString.toLowerCase();
	for (var i=0; i<this.allSuggestions.length; i++) {
		suggestionInput=this.caseSensitive ? this.allSuggestions[i].inp : this.allSuggestions[i].inp.toLowerCase();
		if (suggestionInput.indexOf(filterString)==0 || suggestionInput.indexOf(" "+filterString)>0) {
			filteredSuggestionsArray.push(i);
		}
	}
	return filteredSuggestionsArray;
};

AutoCompleteField.prototype.getMatchedSuggestionObject=function(matchString) {
	var suggestionInput;
	if (!this.caseSensitive) matchString=matchString.toLowerCase();
	for (var i=0; i<this.filteredSuggestions.length; i++) {
		suggestionInput=this.caseSensitive ? this.allSuggestions[this.filteredSuggestions[i]].inp : this.allSuggestions[this.filteredSuggestions[i]].inp.toLowerCase();
		if (suggestionInput.indexOf(matchString)==0 && suggestionInput.length==matchString.length) {
			return this.allSuggestions[this.filteredSuggestions[i]];
		}
	}
	return false;
};

AutoCompleteField.prototype.hasRequestStringChanged=function(targetString) {
	if (this.caseSensitive) {
		return targetString.indexOf(this.requestString)!=0 ? true : false;
	} else {
		return targetString.toLowerCase().indexOf(this.requestString.toLowerCase())!=0 ? true : false;
	}
};

AutoCompleteField.prototype.requestData=function(targetString) {
	var obj=this;
	var xmlHttpRequestObject;
	var timeoutLength=5000;
	this.requestingData=true;
	this.requestString=targetString.slice(0, this.minChars);
	window.setTimeout(function() {obj.requestingData=false;xmlHttpRequestObject=null},timeoutLength);
	xmlHttpRequestObject=Ajax.getXMLHttpRequest();
	xmlHttpRequestObject.open("GET",this.getRequestURL(this.requestString),true);
	xmlHttpRequestObject.onreadystatechange=function() {
		if (xmlHttpRequestObject.readyState==4 && obj.requestingData) {
			if (Ajax.isSuccess(xmlHttpRequestObject)) {
				obj.allSuggestions=Ajax.getResponseData(xmlHttpRequestObject,"json");
				obj.filteredSuggestions=obj.getFilteredSuggestions(targetString);
				if (obj.isInSuggestionList(targetString)!==false) {
					obj.chooseSuggestion(obj.allSuggestions[obj.isInSuggestionList(targetString)]);
				} else {
					if (!obj.suggestionIsChosen) obj.displaySuggestionList();
				}
			}
			obj.requestingData=false;
			xmlHttpRequestObject=null;
		}
	}
	xmlHttpRequestObject.send(null);
};

AutoCompleteField.prototype.isInSuggestionList=function (targetString) {
	for (var i=0; i<this.filteredSuggestions.length; i++) {
		if (this.caseSensitive) {
			if (this.allSuggestions[this.filteredSuggestions[i]].inp.toLowerCase()==targetString.toLowerCase()) return this.filteredSuggestions[i];
		} else {
			if (this.allSuggestions[this.filteredSuggestions[i]].inp==targetString) return this.filteredSuggestions[i];
		}
	}
	return false;
};

AutoCompleteField.prototype.getRequestURL=function(requestString) {
	var reqURL=this.suggestionsDataUrl+"?ac="+encodeURIComponent(requestString);
	var reqParamString=this.getRequestParamString();
	return reqParamString ? reqURL+"&"+reqParamString : reqURL;
};

/*******************************************************************************************************************/
/*                                                Home Page Classes                                                */
/*******************************************************************************************************************/

//////////////////////////
// Class HomePageFinder //
//////////////////////////

/* requestUrl= {locationRequestURL: string, citiesDataRequestUrl: string  
*/

function HomePageFinder(finderParametersObject, requestUrls) {
	var obj=this;
	//this.currentCityName="";
	this.finderParametersObject=finderParametersObject;
	this.parameterFinder=new ParameterFinder(finderParametersObject, requestUrls.locationRequestURL, this);
	this.locationPopupFinder=new LocationPopUpFinder(document.getElementById("select_location_parameters_pane"),finderParametersObject,this);
	this.selectLocationMap=new SelectLocationMap (document.getElementById("select_location_gmap_pane"), requestUrls.citiesDataRequestUrl,finderParametersObject,this);
	this.selectRegionPane=new SelectRegionPane(document.getElementById("select_location_regions_pane"), finderParametersObject, this);
	
	this.locationMapHistoryMenu=new MapSearchHistoryMenu(document.getElementById("location_history_menu_container"),{buttonClass: "locationhistorybutton"});
	
	this.tabbedMenu=new TabbedMenu({rollover:"" , selected:"selected"});
	//this.tabbedMenu.add("parameter_search_tab","parameter_search_container",function () {obj.parameterFinder.setLocation(obj.getCityName())});
	this.tabbedMenu.add("parameter_search_tab","parameter_search_container",function () {obj.parameterFinder.setLocation(SearchPreferences.retrieveCityName())});
	this.tabbedMenu.add("map_search_tab","map_search_container",function () {obj.locationPopupFinder.hide();obj.showRegionSelectPane();obj.locationMapHistoryMenu.clear();});
	this.tabbedMenu.add("free_search_tab","free_search_container",function () {});
	this.tabbedMenu.select("parameter_search_tab");
}
/*
HomePageFinder.prototype.getCityName=function () {
	return this.currentCityName;
};

HomePageFinder.prototype.setCityName=function (cityName) {
	this.currentCityName=cityName;
};
*/
HomePageFinder.prototype.displayPopUpFinder=function (label) {
	var obj=this;
	if (!this.locationPopupFinder.isShown()) {
		this.locationPopupFinder.show();
		this.locationMapHistoryMenu.addButton(Regions.getRegionNameById(this.finderParametersObject.getParameterValue("r")),new Array(function () {obj.hidePopUpFinder();obj.showRegionSelectPane()}, function () {obj.hidePopUpFinder();}));
	}
	this.locationPopupFinder.displayLocationLabel(label);
	this.selectLocationMap.displayRegionSmall(this.finderParametersObject.getParameterValue("r"));
};

HomePageFinder.prototype.hidePopUpFinder=function () {
	this.selectLocationMap.displayRegionLarge(this.finderParametersObject.getParameterValue("r"));
	this.locationPopupFinder.hide();
};

HomePageFinder.prototype.showRegionSelectPane=function () {
	this.selectLocationMap.displayRegionLarge(0);
	this.selectLocationMap.removeCityMarkers();
	this.selectRegionPane.show();
};

HomePageFinder.prototype.showRegionCities=function (regionId) {
	var obj=this;
	//this.setCityName("");
	SearchPreferences.storeCityName("");
	this.selectRegionPane.hide();
	this.selectLocationMap.displayRegionLarge(regionId);
	this.selectLocationMap.displayRegionCities(regionId);
	this.locationMapHistoryMenu.addButton("Hrvatska",new Array(function () {obj.showRegionSelectPane()}));
};

HomePageFinder.prototype.removeRegionHistoryButton=function () {
	this.locationMapHistoryMenu.removeButton(1);
};

///////////////////////////
// Class ParameterFinder //
///////////////////////////

function ParameterFinder(finderParametersObject, locationRequestURL, homePageFinder) {
	var obj=this;
	this.finderParametersObject=finderParametersObject;
	this.homePageFinder=homePageFinder;
	
	this.retypeFinderMenu=new FinderMenu(new Array(document.getElementById("s_parameter_finder_menu"),document.getElementById("p_parameter_finder_menu"),document.getElementById("z_parameter_finder_menu"), document.getElementById("n_parameter_finder_menu")), this.finderParametersObject.getParameterValue("t"), function(previousValue,currentValue) {
		if(previousValue!=currentValue) {
			var parameterObject={};
			parameterObject["t"]=currentValue;
			obj.finderParametersObject.setParameters(obj,parameterObject);
			if (currentValue=='n') {
				obj.hidePriceSize();
			} else {
				obj.showPriceSize();
			}
		}
	});
	
	this.retypeFinderMenu.onRealEstateTypeChange=function (eventObj) {
		this.refresh(eventObj.t.newValue);
	}
	
	this.finderParametersObject.addListener(this.retypeFinderMenu);	
	
	this.locationInputField=new HomePageLocationInputField(document.getElementById("acfield"), document.getElementById("acfieldcontainer"),locationRequestURL,this.finderParametersObject/*,this.homePageFinder*/);
	
	this.rePriceRangeFields=new HomePagePriceRangeFields(document.getElementById("parameter_pricelow"),document.getElementById("parameter_priceup"),"",this.finderParametersObject);
	
	this.reSizeRangeFields=new HomePageSizeRangeFields(document.getElementById("parameter_sizelow"),document.getElementById("parameter_sizeup"),"",this.finderParametersObject);
	
	this.priceSizeContainer=document.getElementById("price_size_holder");
		
	DOMEvent.addDomListener(document.getElementById("parameter_search_submit"),"click",function () {
		if (obj.finderParametersObject.getParameterValue("t")=="n") {
			window.location.href=URLs.NEW_PROJECTS;
		} else {
			window.location.href=URLs.RESULTS;
		}
	});
}

ParameterFinder.prototype.setLocation=function(locationName) {
	this.locationInputField.locationInput.setValue(locationName);
};

ParameterFinder.prototype.showPriceSize=function () {
	DHTMLApi.Visibility.show(this.priceSizeContainer);
}

ParameterFinder.prototype.hidePriceSize=function () {
	DHTMLApi.Visibility.hide(this.priceSizeContainer);
}

///////////////////////////////
// Class LocationPopUpFinder //
///////////////////////////////

function LocationPopUpFinder(containerElement,finderParametersObject, homePageFinder) {
	var obj=this;
	this.containerElement=containerElement;
	this.finderParametersObject=finderParametersObject;
	this.homePageFinder=homePageFinder;
	this._isShown=false;
	
	this.retypeFinderMenu=new FinderMenu(new Array(document.getElementById("s_location_popup_finder_menu"),document.getElementById("p_location_popup_finder_menu"),document.getElementById("z_location_popup_finder_menu"), document.getElementById("n_location_popup_finder_menu")), this.finderParametersObject.getParameterValue("t"), function(previousValue,currentValue) {
		if(previousValue!=currentValue) {
			var parameterObject={};
			parameterObject["t"]=currentValue;
			obj.finderParametersObject.setParameters(obj,parameterObject);
			if (currentValue=='n') {
				obj.hidePriceSize();
			} else {
				obj.showPriceSize();
			}
		}
	});
	
	this.retypeFinderMenu.onRealEstateTypeChange=function (eventObj) {
		this.refresh(eventObj.t.newValue);
	}
	
	this.finderParametersObject.addListener(this.retypeFinderMenu);	
	
	this.rePriceRangeFields=new HomePagePriceRangeFields(document.getElementById("location_popup_pricelow"),document.getElementById("location_popup_priceup"),"",this.finderParametersObject);
	
	this.reSizeRangeFields=new HomePageSizeRangeFields(document.getElementById("location_popup_sizelow"),document.getElementById("location_popup_sizeup"),"",this.finderParametersObject);
	
	this.labelElement=document.getElementById("selected_location");
	
	this.closeButton=document.getElementById("map_parameters_interface_tab");
	DOMEvent.addDomListener(this.closeButton,"click",function () {obj.homePageFinder.hidePopUpFinder();obj.homePageFinder.removeRegionHistoryButton();});
	
	this.priceSizeContainer=document.getElementById("map_price_size_holder");
		
	DOMEvent.addDomListener(document.getElementById("map_parameter_search_submit"),"click",function () {
		if (obj.finderParametersObject.getParameterValue("t")=="n") {
			window.location.href=URLs.NEW_PROJECTS;
		} else {
			window.location.href=URLs.RESULTS;
		}
	});	
}

LocationPopUpFinder.prototype.displayLocationLabel=function (locationString) {
	var locationNode;
	while (this.labelElement.childNodes.length>0) {
		this.labelElement.removeChild(this.labelElement.firstChild);
	}
	this.labelElement.appendChild(document.createTextNode("PodruÄje pretrage: "));
	locationNode=document.createElement("STRONG");
	locationNode.appendChild(document.createTextNode(locationString));
	this.labelElement.appendChild(locationNode);
};

LocationPopUpFinder.prototype.hide=function() {
	DHTMLApi.Visibility.hide(this.containerElement);
	this._isShown=false;
};

LocationPopUpFinder.prototype.show=function() {	
	DHTMLApi.Visibility.show(this.containerElement);
	this._isShown=true;
};

LocationPopUpFinder.prototype.isShown=function() {
	return this._isShown;
};

LocationPopUpFinder.prototype.showPriceSize=function () {
	DHTMLApi.Visibility.show(this.priceSizeContainer);
}

LocationPopUpFinder.prototype.hidePriceSize=function () {
	DHTMLApi.Visibility.hide(this.priceSizeContainer);
}

//////////////////////////////////////
// Class HomePageLocationInputField //
//////////////////////////////////////

function HomePageLocationInputField(inputFieldElement, inputFieldContainerElement,locationRequestURL,finderParameters/*,cityNameSaver*/) {
	var achandlers;
	var obj=this;
	
	this.locationACField=inputFieldElement;
	this.locationACFieldContainer=inputFieldContainerElement;
	this.finderParameters=finderParameters;
	this.finderParameters.addListener(this);
	//this.cityNameSaver=cityNameSaver;
	
	achandlers={onSelectSuggestion : function(suggestionObject) {
		if (finderParameters.getParameterValue("l")!==suggestionObject.val.zip && finderParameters.getParameterValue("k")!==suggestionObject.val.k) {
			var parameterObject={};
			parameterObject["l"]=suggestionObject.val.zip;
			parameterObject["r"]=suggestionObject.val.reg;
			if (suggestionObject.val.k!==0) {
				parameterObject["k"]=suggestionObject.val.k;
			}
			finderParameters.setParameters(obj, parameterObject);
			//obj.cityNameSaver.setCityName(suggestionObject.inp);
			SearchPreferences.storeCityName(suggestionObject.inp);
		}
	}, onUnselectSuggestion : function() {
		if (finderParameters.getParameterValue("l")!==false) {
			finderParameters.setParameters(obj, {r: 0}, new Array("l", "k"));
		}
	}, getRequestParamString: function () {
		return "cmd=getlocpart";
	}};
	
	this.locationInput=new AutoCompleteField({inputFieldContainer : this.locationACFieldContainer, inputField : this.locationACField},{sugestionContainerClassName: "acsuggestionscont", suggestionListClassName: "acsuggestions", suggestionItemSelectedClassName: "suggestionselected"},locationRequestURL, achandlers, {minChars:2, numOfSuggestionsDisplayed: 10});
	
	DOMEvent.addDomListener(document.getElementById("locqlink1"),"click",function (e) {
		obj.locationInput.setValue("Zagreb");
		//obj.cityNameSaver.setCityName("Zagreb");
		SearchPreferences.storeCityName("Zagreb");
	});
	
	DOMEvent.addDomListener(document.getElementById("locqlink2"),"click",function (e) {
		obj.locationInput.setValue("Split");
		//obj.cityNameSaver.setCityName("Split");
		SearchPreferences.storeCityName("Split");
	});

	DOMEvent.addDomListener(document.getElementById("locqlink3"),"click",function (e) {
		obj.locationInput.setValue("Rijeka");
		//obj.cityNameSaver.setCityName("Rijeka");
		SearchPreferences.storeCityName("Rijeka");
	});

	DOMEvent.addDomListener(document.getElementById("locqlink4"),"click",function (e) {
		obj.locationInput.setValue("Dubrovnik");
		//obj.cityNameSaver.setCityName("Dubrovnik");
		SearchPreferences.storeCityName("Dubrovnik");
	});
}


////////////////////////////////////
// Class HomePagePriceRangeFields //
////////////////////////////////////

function HomePagePriceRangeFields(lowerInputElement,upperInputElement,initValue,finderParametersObj) {
	this.lowerInputElement=lowerInputElement;
	this.upperInputElement=upperInputElement;
	this.makeRangeFields(lowerInputElement,upperInputElement,initValue,"p",finderParametersObj);
	this.setRangeFieldsValue(lowerInputElement,upperInputElement,initValue);
	finderParametersObj.addListener(this);
}

HomePagePriceRangeFields.prototype=implementsInterface(RangeFieldsBuilder);

HomePagePriceRangeFields.prototype.onPriceChange=function(eventObj) {
	this.setRangeFieldsValue(this.lowerInputElement,this.upperInputElement,eventObj.p.newValue);
};

///////////////////////////////////
// Class HomePageSizeRangeFields //
///////////////////////////////////

function HomePageSizeRangeFields(lowerInputElement,upperInputElement,initValue,finderParametersObj) {
	this.lowerInputElement=lowerInputElement;
	this.upperInputElement=upperInputElement;
	this.makeRangeFields(lowerInputElement,upperInputElement,initValue,"s",finderParametersObj);
	this.setRangeFieldsValue(lowerInputElement,upperInputElement,initValue);
	finderParametersObj.addListener(this);
}

HomePageSizeRangeFields.prototype=implementsInterface(RangeFieldsBuilder);

HomePageSizeRangeFields.prototype.onRealEstateSizeChange=function(eventObj) {
	this.setRangeFieldsValue(this.lowerInputElement,this.upperInputElement,eventObj.s.newValue);
};

////////////////////////////
// Class SelectRegionPane //
////////////////////////////

function SelectRegionPane(containerElement, finderParametersObject, homePageFinder) {
	this.container=containerElement;
	this.visible=false;
	this.homePageFinder=homePageFinder;
	this.finderParametersObject=finderParametersObject;
	this.regions=[];
	this.init();
}

SelectRegionPane.prototype.addRegion=function (regionObject) {
	this.regions.push(regionObject);
};

SelectRegionPane.prototype.show=function() {
	DHTMLApi.Visibility.show(this.container);
	this.visible=true;
};

SelectRegionPane.prototype.hide=function() {
	this.visible=false;
	for (var i=0; i<this.regions.length; i++) {
		this.regions[i].hide();
	}
	DHTMLApi.Visibility.hide(this.container);
};

SelectRegionPane.prototype.addAllCroRegions=function () {
	this.addRegion(new MapRegion({regionImage: document.getElementById("dalmacija_du_img"), mapArea : document.getElementById("dalmacija_du_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_dalmacija_du")}, "regiontag" ,Regions.DALMACIJA_DU));
	this.addRegion(new MapRegion({regionImage: document.getElementById("dalmacija_st_img"), mapArea : document.getElementById("dalmacija_st_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_dalmacija_st")}, "regiontag", Regions.DALMACIJA_ST));
	this.addRegion(new MapRegion({regionImage: document.getElementById("dalmacija_si_img"), mapArea : document.getElementById("dalmacija_si_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_dalmacija_si")}, "regiontag", Regions.DALMACIJA_SI));
	this.addRegion(new MapRegion({regionImage: document.getElementById("dalmacija_zd_img"), mapArea : document.getElementById("dalmacija_zd_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_dalmacija_zd")}, "regiontag", Regions.DALMACIJA_ZD));
	this.addRegion(new MapRegion({regionImage: document.getElementById("kvarner_img"), mapArea : document.getElementById("kvarner_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_kvarner")}, "regiontag", Regions.KVARNER));
	this.addRegion(new MapRegion({regionImage: document.getElementById("istra_img"), mapArea : document.getElementById("istra_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_istra")}, "regiontag", Regions.ISTRA));
	this.addRegion(new MapRegion({regionImage: document.getElementById("zagreb_img"), mapArea : document.getElementById("zagreb_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_zagreb")}, "regiontag", Regions.ZAGREB));
	this.addRegion(new MapRegion({regionImage: document.getElementById("slavonija_img"), mapArea : document.getElementById("slavonija_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_slavonija")}, "regiontag", Regions.SLAVONIJA));
	this.addRegion(new MapRegion({regionImage: document.getElementById("sredisnja_hrvatska_img"), mapArea : document.getElementById("sredisnja_hrvatska_map"), regionTagPane: document.getElementById("select_location_selection_display_pane"), selectedMarker: document.getElementById("selected_region_marker_sredisnja_hrvatska")}, "regiontag", Regions.SREDNJA_HR));
};

SelectRegionPane.prototype.init=function () {	
	var obj=this;
	this.addAllCroRegions();
	for (var i=0; i<this.regions.length; i++) {
		(function() {
		var j=i;
		obj.regions[i].init();
		DOMEvent.addDomListener(obj.regions[i].getMapAreaObject(),"click",function (e) {
			obj.finderParametersObject.setParameters(obj,{r: obj.regions[j].regionData.id},new Array("l","k"));
			obj.homePageFinder.showRegionCities(obj.regions[j].regionData.id);
		});
		})();
	}
};

SelectRegionPane.prototype.getRegionObjectById=function (regionId) {
	for (var i=0; i<this.regions.length; i++) {
		if (this.regions[i].getRegionId()==regionId) {
			return (this.regions[i]);
		}
	}
};


/////////////////////////////
// Class SelectLocationMap //
/////////////////////////////

function SelectLocationMap (mapContainerElement,citiesDataRequestUrl, finderParametersObject, homePageFinder) {
	this.citiesDataRequestUrl=citiesDataRequestUrl
	this.homePageFinder=homePageFinder;
	this.finderParametersObject=finderParametersObject;
	this.xmlHttpRequestObject=null;
	this.largeMapData={};
	this.largeMapData[Regions.HRVATSKA.id]={lat: 44.55133484083592, lng: 16.495546875, zoom: 7};
	this.largeMapData[Regions.ZAGREB.id]={lat: 45.79529713006589, lng: 16.0015869140625, zoom: 10};
	this.largeMapData[Regions.SLAVONIJA.id]={lat: 45.42929873257377, lng: 17.9571533203125, zoom: 8};
	this.largeMapData[Regions.ISTRA.id]={lat: 45.15686396890044, lng: 13.94439697265625, zoom: 9};
	this.largeMapData[Regions.KVARNER.id]={lat: 44.972570682240615, lng: 15.0732421875, zoom: 8};
	this.largeMapData[Regions.DALMACIJA_ZD.id]={lat: 44.13097085672744, lng: 15.54290771484375, zoom: 9};
	this.largeMapData[Regions.DALMACIJA_SI.id]={lat: 43.82660134505382, lng: 16.0894775390625, zoom: 9};
	this.largeMapData[Regions.DALMACIJA_ST.id]={lat: 43.389081939117496, lng: 16.798095703125, zoom: 9};
	this.largeMapData[Regions.DALMACIJA_DU.id]={lat: 42.67435857693381, lng: 17.56539306640625, zoom: 9};
	this.largeMapData[Regions.SREDNJA_HR.id]={lat: 45.71768635790717, lng: 16.3421630859375, zoom: 8};
	this.smallMapData={};
	this.smallMapData[Regions.HRVATSKA.id]={lat: 44.55133484083592, lng: 16.495546875, zoom: 7};
	this.smallMapData[Regions.ZAGREB.id]={lat: 45.50057194157226, lng: 16.01531982421875, zoom: 9};
	this.smallMapData[Regions.SLAVONIJA.id]={lat: 44.15856343854312, lng: 17.25952148475, zoom: 7};
	this.smallMapData[Regions.ISTRA.id]={lat: 44.48866833139464, lng: 13.963623046875, zoom: 8};
	this.smallMapData[Regions.KVARNER.id]={lat: 43.57243174740972, lng: 14.93042, zoom: 7};
	this.smallMapData[Regions.DALMACIJA_ZD.id]={lat: 43.48481212891603, lng: 15.281982421875, zoom: 8};
	this.smallMapData[Regions.DALMACIJA_SI.id]={lat: 43.06487470411881, lng: 15.8203125, zoom: 8};
	this.smallMapData[Regions.DALMACIJA_ST.id]={lat: 42.65416193033991, lng: 16.4300537109375, zoom: 8};
	this.smallMapData[Regions.DALMACIJA_DU.id]={lat: 42.09414637092276, lng: 17.5396728515625, zoom: 8};
	this.smallMapData[Regions.SREDNJA_HR.id]={lat: 44.34742225636393, lng: 15.985107421875, zoom: 7};
	
	this.markerClick=false;
	this.cityMarkers=[];
	if (GBrowserIsCompatible()) {
		this.gMap=new GMap2(mapContainerElement);
		this.displayCroatia();
		this.init();
	}
}

SelectLocationMap.prototype.displayCroatia=function () {
	var obj=this;
	this.gMap.setMapType(G_PHYSICAL_MAP);
	this.displayRegionLarge(Regions.HRVATSKA.id);
	this.gMap.disableDragging();
	this.gMap.checkResize();
};

SelectLocationMap.prototype.init=function () {
	var obj=this;
	GEvent.addListener(this.gMap,"click",function() {
		if (!obj.markerClick) {
			var regionId;
			regionId=obj.finderParametersObject.getParameterValue("r");
			for (var region in Regions) {
				if (Regions[region].id==regionId) {
					obj.homePageFinder.displayPopUpFinder(Regions[region].name);
				}
			}
		}
		obj.markerClick=false;
	});
};

SelectLocationMap.prototype.displayRegionLarge=function (regionId) {
	this.gMap.checkResize();
	this.gMap.setMapType(G_PHYSICAL_MAP);
	this.gMap.setCenter(new GLatLng(this.largeMapData[regionId].lat,this.largeMapData[regionId].lng), this.largeMapData[regionId].zoom);
};

SelectLocationMap.prototype.displayRegionSmall=function (regionId) {
	this.gMap.setMapType(G_PHYSICAL_MAP);
	this.gMap.setCenter(new GLatLng(this.smallMapData[regionId].lat,this.smallMapData[regionId].lng), this.smallMapData[regionId].zoom);
};

SelectLocationMap.prototype.addCityMarkers=function (cityData) {
	var cityMarker;
	var obj=this;
	for (var i=0; i<cityData.length; i++) {
		(function () {
			var j=i;
			var rolloverText;
			if (cityData[j].ads.toString().charAt(cityData[j].ads.toString().length-1)=="1") {
				rolloverText="<strong>"+cityData[j].name+"</strong>, "+cityData[j].ads+" oglas";
			} else {
				rolloverText="<strong>"+cityData[j].name+"</strong>, "+cityData[j].ads+" oglasa";
			}
			cityMarker=new CityMapMarker(cityData[j].zip,cityData[j].lat,cityData[j].lng,rolloverText,obj,function () {
				obj.markerClick=true;
				//obj.homePageFinder.setCityName(cityData[j].name);
				SearchPreferences.storeCityName(cityData[j].name);
				obj.finderParametersObject.setParameters(obj,{l: cityData[j].zip},[]);
				obj.homePageFinder.displayPopUpFinder(cityData[j].name);
			}
		);
		})();
		obj.cityMarkers.push(cityMarker);
		obj.gMap.addOverlay(cityMarker.getGMarkerObject());
	}
};

SelectLocationMap.prototype.removeCityMarkers=function () {
	for (var i=0; i< this.cityMarkers.length; i++) {
		this.cityMarkers[i].removeHandlers();
	}
	this.gMap.clearOverlays();
	this.cityMarkers=[];
};

SelectLocationMap.prototype.displayRegionCities=function (regionId) {
	var obj=this;
	var timeoutLength=5000;
	window.setTimeout(function() {this.xmlHttpRequestObject=null},timeoutLength);
	this.xmlHttpRequestObject=Ajax.getXMLHttpRequest();
	this.xmlHttpRequestObject.open("GET",this.citiesDataRequestUrl+"?cmd=getcities&r="+regionId,true);
	this.xmlHttpRequestObject.onreadystatechange=function() {
		var adDataObject,jsonResponseObject;
		if (obj.xmlHttpRequestObject.readyState==4) {
			if (Ajax.isSuccess(obj.xmlHttpRequestObject)) {
				jsonResponseObject=Ajax.getResponseData(obj.xmlHttpRequestObject,"json");
				obj.addCityMarkers(jsonResponseObject);
			}
			obj.xmlHttpRequestObject=null;
		}
	}
	this.xmlHttpRequestObject.send(null);
};

/////////////////////
// Class MapRegion //
/////////////////////

/* parameters: 

HTMLElements = {regionImage : Node, mapArea : Node, regionTagPane: Node, selectedMarker: Node}
regionTagClassName = string
regionData = object from regions {id: int, name: str}

*/

function MapRegion(HTMLElements,regionTagClassName,regionData) {
	this.regionImageElement=HTMLElements.regionImage;
	this.mapArea=HTMLElements.mapArea;
	this.regionTagPane=HTMLElements.regionTagPane;
	this.selectedMarker=HTMLElements.selectedMarker;
	this.regionData=regionData;
	this.regionTagClassName=regionTagClassName;
	this.regionNameTag=null;
	this.onMouseOverHandler=this.onMouseOutHandler=null;	
}

MapRegion.prototype.init=function() {
	var obj=this;
	this.onMouseOverHandler=DOMEvent.addDomListener(this.mapArea,"mouseover",function (e) {
		obj.show();
	});
	this.onMouseOutHandler=DOMEvent.addDomListener(this.mapArea,"mouseout",function (e) {
		obj.hide();
	});
};
// redundant method - to be deleted
MapRegion.prototype.setSelected=function() {
	DOMEvent.removeListener(this.onMouseOverHandler);
	DOMEvent.removeListener(this.onMouseOutHandler);
	this.onMouseOverHandler=this.onMouseOutHandler=null;
};

MapRegion.prototype.displayRegionNameTag=function() {
	var tagPosX,tagPosY;
	if (this.regionNameTag===null) {
		this.regionNameTag=document.createElement("DIV");
		this.regionNameTag.appendChild(document.createTextNode(this.regionData.name));
		this.regionTagPane.appendChild(this.regionNameTag);
		DHTMLApi.CSS.setClass(this.regionNameTag,new Array(this.regionTagClassName),[]);
		tagPosX=Math.ceil(DHTMLApi.Position.getXPosInElement(this.regionImageElement,this.regionImageElement.parentNode)+DHTMLApi.Size.getElementWidth(this.regionImageElement)/2-DHTMLApi.Size.getElementWidth(this.regionNameTag)/2);
		tagPosY=Math.ceil(DHTMLApi.Position.getYPosInElement(this.regionImageElement,this.regionImageElement.parentNode)+DHTMLApi.Size.getElementHeight(this.regionImageElement)/2-DHTMLApi.Size.getElementHeight(this.regionNameTag)/2)+24;
		DHTMLApi.CSS.setProperties(this.regionNameTag,{position: "absolute", left: tagPosX+"px", top: tagPosY+"px"});
	}
};

MapRegion.prototype.displayRegionMarker=function() {
	DHTMLApi.Visibility.show(this.selectedMarker);
};

MapRegion.prototype.hideRegionMarker=function() {
	DHTMLApi.Visibility.hide(this.selectedMarker);
};

MapRegion.prototype.hideRegionNameTag=function() {
	if (this.regionNameTag!==null) {
		this.regionTagPane.removeChild(this.regionNameTag);
		this.regionNameTag=null;
	}
};

MapRegion.prototype.show=function() {
	DHTMLApi.Visibility.show(this.regionImageElement);
	DHTMLApi.Visibility.setOpacity(this.regionImageElement,50);
	this.displayRegionNameTag();
	this.displayRegionMarker();
};

MapRegion.prototype.hide=function() {
	this.hideRegionNameTag();
	this.hideRegionMarker();
	DHTMLApi.Visibility.hide(this.regionImageElement);
};

MapRegion.prototype.getMapAreaObject=function() {
	return this.mapArea;
};

MapRegion.prototype.getRegionId=function() {
	return this.regionData.id;
};


/*******************************************************************************************************************/
/*                                              Results Page Classes                                               */
/*******************************************************************************************************************/

//////////////////
// Class Finder //
//////////////////

/*
 requestURLs={locationsURL: string, cityPartsURL: string, rangesURL: string}
*/

function Finder(finderParametersObject, adDataLoaderObject, requestURLs) {
	var initParameterValue, realEstateType,initCityPartValue;
	var obj=this;
	this.finderParametersObject=finderParametersObject;
	this.finderParametersObject.addListener(this);
	this.adDataLoaderObject=adDataLoaderObject;
	this.adDataLoaderObject.addListener(this);
	this.requestURLs=requestURLs;
	this.xmlHttpRequestObject=null;
	
	initParameterValue=this.finderParametersObject.getParameterValue("r");
	if (initParameterValue===false) initParameterValue;
	this.onSelectRegion=function(previousValue,currentValue) {
		var parameterObject={};
		parameterObject["r"]=currentValue;
		obj.finderParametersObject.setParameters(obj,parameterObject, new Array("l","k","pg"));
		obj.locationInputField.locationInput.setValue("");
		SearchPreferences.storeCityName("");
		obj.cityPartSelector.hide();
	}
	this.regionFinderMenu=new FinderMenu(document.getElementById("r_finder_menu"), initParameterValue, this.onSelectRegion);	
	
	this.retypeFinderMenu=new RealEstateTypeFinderMenu (this.finderParametersObject.getParameterValue("t"), function(previousValue,currentValue,menuContainer) {
		if(previousValue!=currentValue) {
			var parameterObject={};
			parameterObject["t"]=currentValue;
			obj.finderParametersObject.setParameters(this,parameterObject,new Array("p","s","nr","pg"));
		}
	});
	
	initCityPartValue=(this.finderParametersObject.getParameterValue("k")===false) ? "": this.finderParametersObject.getParameterValue("k");
		
	this.cityPartSelector=new CityPartSelector(document.getElementById("neighbourhood"), document.getElementById("neighbourhood_select"), this.finderParametersObject, this.requestURLs.cityPartsURL,initCityPartValue);
	
	this.locationInputField=new FinderLocationInputField(document.getElementById("acfield"), document.getElementById("acfieldcontainer"),this.requestURLs.locationsURL,this.finderParametersObject, this.cityPartSelector);
	
	this.priceRangeInputField=new FinderRangeInputField(document.getElementById("lower_price"),document.getElementById("upper_price"),document.getElementById("price_container"),document.getElementById("all_prices"),document.getElementById("price_search"),"p",["s","pg"],this.finderParametersObject);
	
	this.sizeRangeInputField=new FinderRangeInputField(document.getElementById("lower_area"),document.getElementById("upper_area"),document.getElementById("size_container"),document.getElementById("all_areas"),document.getElementById("area_search"),"s",["pg"],this.finderParametersObject);
		
	this.roomsFinderMenu=new RoomNumberFinderMenu(document.getElementById("room_number_finder_container"), document.getElementById("rooms_container"), document.getElementById("all_rooms"), this.finderParametersObject);
	
	realEstateType=this.finderParametersObject.getParameterValue("t");
	
	if (realEstateType=="ss") {
		this.roomsFinderMenu.show();
	} else {
		this.roomsFinderMenu.hide();
	}
}

Finder.prototype.onPriceRangesLoad=function (eventObject) {
	this.priceRangeInputField.displayRangesMenu(eventObject);
};

Finder.prototype.onSizeRangesLoad=function (eventObject) {
	this.sizeRangeInputField.displayRangesMenu(eventObject);
};

Finder.prototype.onRealEstateTypeChange=function(eventObject) {
	if (eventObject.t.newValue=="ss") {
		this.roomsFinderMenu.show();
	} else {
		this.roomsFinderMenu.hide();
	}
};

Finder.prototype.onLocationChange=function(eventObject) {
	if (typeof eventObject.l == "undefined") return;
	if(eventObject.l.newValue=="") {
		this.cityPartSelector.hide();
	}
	if (eventObject.l.newValue!=eventObject.l.oldValue) {
		if (typeof eventObject.r!="undefined" && eventObject.r.newValue!="") {
			this.regionFinderMenu.unselectAll();
			this.regionFinderMenu.setSelected(this.regionFinderMenu.getListItem(eventObject.r.newValue));
		}
	}
};

Finder.prototype.onPriceChange=function(eventObject) {
	this.priceRangeInputField.setRangeFieldsValue(this.priceRangeInputField.lowerValueInputElement,this.priceRangeInputField.upperValueInputElement,eventObject.p.newValue);
};

Finder.prototype.onRealEstateSizeChange=function(eventObject) {
	this.sizeRangeInputField.setRangeFieldsValue(this.sizeRangeInputField.lowerValueInputElement,this.sizeRangeInputField.upperValueInputElement,eventObject.s.newValue);
};


////////////////////////////
// Class CityPartSelector //
////////////////////////////

function CityPartSelector(containerElement, selectorElement, finderParameters, cityPartsRequestURL, initSelectedValue) {
	this.container=containerElement;
	this.selector=selectorElement;
	this.finderParameters=finderParameters;
	this.cityPartsRequestURL=cityPartsRequestURL;
	this.xmlHttpRequestObject=null;
	this.onChangeHandler=null;
	this.selectedValue=(typeof initSelectedValue!="undefined") ? initSelectedValue: "";
}

CityPartSelector.prototype=implementsInterface(DropDownSelector);

/* cityPartsArray: [{id:1, name: "Centar"},] */

CityPartSelector.prototype.display=function (cityPartsArray) {
	this.clearOptions(this.selector);
	this.addOption(this.selector, "svi kvartovi", "");
	for (var i=0; i<cityPartsArray.length; i++) {
		this.addOption(this.selector, cityPartsArray[i].name, cityPartsArray[i].id);
	}
	this.init();
	DHTMLApi.Visibility.show(this.container);
};

CityPartSelector.prototype.init=function () {
	var obj=this;
	this.setSelected(this.selector, this.selectedValue);
	if (this.onChangeHandler!==null) DOMEvent.removeListener(this.onChangeHandler);
	this.onChangeHandler=DOMEvent.addDomListener(this.selector, "change", function() {
		obj.selectedValue=obj.getSelectedValue(obj.selector);
		if (obj.selectedValue=="") {
			obj.finderParameters.setParameters(obj, {},new Array("k","pg"));
		} else {
			obj.finderParameters.setParameters(obj, {k: obj.selectedValue},["pg"]);
		}
	});
};

CityPartSelector.prototype.requestCityParts=function (locationId) {
	var obj=this;
	var timeoutLength=5000;
	
	window.setTimeout(function() {this.xmlHttpRequestObject=null},timeoutLength);
	this.xmlHttpRequestObject=Ajax.getXMLHttpRequest();
	this.xmlHttpRequestObject.open("GET",this.cityPartsRequestURL+"?cmd=getcityparts&l="+locationId,true);
	this.xmlHttpRequestObject.onreadystatechange=function() {
		var jsonResponseObject;
		if (obj.xmlHttpRequestObject.readyState==4) {
			if (Ajax.isSuccess(obj.xmlHttpRequestObject)) {
				jsonResponseObject=Ajax.getResponseData(obj.xmlHttpRequestObject,"json");
				if (jsonResponseObject.length==0) {
					return false;
				}
				obj.display(jsonResponseObject);
			}
			obj.xmlHttpRequestObject=null;
		}
	}
	this.xmlHttpRequestObject.send(null);
};

CityPartSelector.prototype.hide=function() {
	DHTMLApi.Visibility.hide(this.container);
};

////////////////////////////////////
// Class FinderLocationInputField //
////////////////////////////////////

function FinderLocationInputField(inputFieldElement, inputFieldContainerElement,locationRequestURL,finderParameters, cityPartSelector) {
	var achandlers;
	var obj=this;
	
	this.locationACField=inputFieldElement;
	this.locationACFieldContainer=inputFieldContainerElement;
	this.locationACFieldInit=true;
	this.finderParameters=finderParameters;
	this.cityPartSelector=cityPartSelector;
	
	DOMEvent.addDomListener(this.locationACField,"keyup",function () {obj.locationACFieldInit=false;});
	
	achandlers={onSelectSuggestion : function(suggestionObject) {
		/*if (finderParameters.getParameterValue("l")!==suggestionObject.val.zip) {
			var parameterObject={};
			parameterObject["l"]=suggestionObject.val.zip;
			parameterObject["r"]=suggestionObject.val.reg;
			finderParameters.setParameters(obj, parameterObject,["pg"]);
			if (suggestionObject.val.dist == 1) {
				obj.cityPartSelector.requestCityParts(suggestionObject.val.zip);
			} else {
				obj.cityPartSelector.hide();
			}
			SearchPreferences.storeCityName(suggestionObject.inp);
		}*/
		
		if (finderParameters.getParameterValue("l")!==suggestionObject.val.zip) {
			if (obj.locationACFieldInit)  {
				obj.locationACFieldInit=false;
			} else {
				var parameterObject={};
				parameterObject["l"]=suggestionObject.val.zip;
				parameterObject["r"]=suggestionObject.val.reg;
				finderParameters.setParameters(obj, parameterObject,["pg"]);
				SearchPreferences.storeCityName(suggestionObject.inp);
			}				
			if (suggestionObject.val.dist == 1) {
				obj.cityPartSelector.requestCityParts(suggestionObject.val.zip);
			} else {
				obj.cityPartSelector.hide();
			}
		}
		
	}, onUnselectSuggestion : function() {
		if (finderParameters.getParameterValue("l")!==false && finderParameters.getParameterValue("k")!==false) {
			finderParameters.setParameters(obj, {},new Array("l","k","pg"));
		}
		if (finderParameters.getParameterValue("l")!==false) {
			finderParameters.setParameters(obj, {},new Array("l","pg"));
		}
		SearchPreferences.storeCityName("");
	}, getRequestParamString: function () {
		return "cmd=getloc";
	}};
	
	var defaultCityName=(this.finderParameters.getParameterValue("l")!==false) ? SearchPreferences.retrieveCityName(): "";
	
	this.locationInput=new AutoCompleteField({inputFieldContainer : this.locationACFieldContainer, inputField : this.locationACField},{sugestionContainerClassName: "acsuggestionscont", suggestionListClassName: "acsuggestions", suggestionItemSelectedClassName: "suggestionselected"},locationRequestURL, achandlers, {minChars:2, numOfSuggestionsDisplayed: 10, defaultValue: defaultCityName});
	
	/*if (this.finderParameters.getParameterValue("l")!==false) {
		this.locationInput.setValue(SearchPreferences.retrieveCityName());	
	}*/
}

/////////////////////////////////
// Class FinderRangeInputField //
/////////////////////////////////

/*
handlers= {onSelectRange: handler executes on suggestion menu selection,
onEnterRange: handler executes when user enters
onClearParameter: handler executes when clearValuesButton is pressed }
*/

function FinderRangeInputField(lowerValueInputElement,upperValueInputElement,rangesMenuElement,clearValuesButton,searchButton,parameter,clearParametersArray,finderParametersObject) {
	var obj=this;
	this.lowerValueInputElement=lowerValueInputElement;
	this.upperValueInputElement=upperValueInputElement;
	this.clearValuesButton=clearValuesButton;
	this.searchButton=searchButton;
	this.rangesMenuElement=rangesMenuElement;
	this.parameter=parameter;
	this.clearParametersArray=clearParametersArray;
	this.finderParametersObject=finderParametersObject;
	this.onSelectRange=function(previousValue,currentValue) {
		var parameterObject={};
		parameterObject[obj.parameter]=currentValue;
		obj.finderParametersObject.setParameters(obj,parameterObject,obj.clearParametersArray);
	}
	this.rangesMenu=new FinderMenu(rangesMenuElement, "", this.onSelectRange);
	this.hideRangesMenu();
	this.init();
}

FinderRangeInputField.prototype=implementsInterface(RangeFieldsBuilder);

FinderRangeInputField.prototype.init=function() {
	var rangeInitValue;
	var obj=this;
	
	rangeInitValue=this.finderParametersObject.getParameterValue(this.parameter);
	if (rangeInitValue!==false) this.setRangeFieldsValue(this.lowerValueInputElement,this.upperValueInputElement,rangeInitValue);
	
	
	var onChangeInputValuesHandler=function() {
		obj.fixRangeFieldsValues(obj.lowerValueInputElement,obj.upperValueInputElement);
	}
	DOMEvent.addDomListener(this.lowerValueInputElement,"change", onChangeInputValuesHandler);
	DOMEvent.addDomListener(this.upperValueInputElement,"change", onChangeInputValuesHandler);
	
	DOMEvent.addDomListener(this.clearValuesButton,"click", function () {
		obj.setRangeFieldsValue(obj.lowerValueInputElement,obj.upperValueInputElement,"");
		if (obj.finderParametersObject.getParameterValue(obj.parameter)!==false) {
			obj.finderParametersObject.setParameters(obj,{},obj.clearParametersArray.concat(obj.parameter));
		}
	});
	
	DOMEvent.addDomListener(this.searchButton,"click", function () {
		var fieldsValue, parameterObject;
		fieldsValue=obj.lowerValueInputElement.value+"-"+obj.upperValueInputElement.value;
		parameterObject={};
		if (fieldsValue !="-") {
			parameterObject[obj.parameter]=fieldsValue;
			obj.finderParametersObject.setParameters(obj,parameterObject,obj.clearParametersArray);
		} else {
			obj.finderParametersObject.setParameters(obj,{},obj.clearParametersArray.concat(obj.parameter));
		}
	});
};

FinderRangeInputField.prototype.displayRangesMenu=function (itemListArray) {
	this.rangesMenu.clearItems(this.rangesMenuElement);
	for (var i=0; i<itemListArray.length; i++) {
		this.rangesMenu.addItem(this.rangesMenuElement,itemListArray[i].label,itemListArray[i].range);		
	}
	DHTMLApi.Visibility.show(this.rangesMenuElement);
};

FinderRangeInputField.prototype.hideRangesMenu=function () {
	DHTMLApi.Visibility.hide(this.rangesMenuElement);
};

////////////////////////////////////
// class RealEstateTypeFinderMenu //
////////////////////////////////////

/*
menusVisibility = array of booleans, true - menu visible, false - menu hidden 
*/

function RealEstateTypeFinderMenu (initParameterValue, onSelectReTypeHandler) {
	var obj=this;
	this.menuContainers=new Array(document.getElementById("s_finder_menu"),document.getElementById("p_finder_menu"),document.getElementById("z_finder_menu"));
	this.menusVisibility=this.getMenusVisibilityByParam(initParameterValue);
	this.menuContainersToggleButtons=new Array(document.getElementById("s_finder_menu_toggle"),document.getElementById("p_finder_menu_toggle"),document.getElementById("z_finder_menu_toggle"));
	this.menuContainersToggleArea=new Array(document.getElementById("s_finder_menu_toggle_area"),document.getElementById("p_finder_menu_toggle_area"),document.getElementById("z_finder_menu_toggle_area"));
	this.menuContainersToggleButtonsImages={visible: URLs.STATIC_IMAGES_FOLDER+"arrow_up.gif", hidden: URLs.STATIC_IMAGES_FOLDER+"arrow_down.gif"};
	this.finderMenu= new FinderMenu(this.menuContainers, initParameterValue, function (previousValue,currentValue,menuContainer) {
		onSelectReTypeHandler(previousValue,currentValue,menuContainer); 
		if(previousValue!=currentValue) {
			obj.display(obj.getMenusVisibility(obj.getMenuContainerIndex(menuContainer)));
		}
	});
	this.display(this.menusVisibility);
	this.initToggleButtons();
}

RealEstateTypeFinderMenu.prototype.display=function (menusVisibility) {
	for (var i=0; i<menusVisibility.length; i++) {
		if (menusVisibility[i]) {
			this.menuContainersToggleButtons[i].src=this.menuContainersToggleButtonsImages.visible;
			this.showMenu(this.menuContainers[i]);
			this.menusVisibility[i]=true;
		} else {
			this.menuContainersToggleButtons[i].src=this.menuContainersToggleButtonsImages.hidden;
			this.hideMenu(this.menuContainers[i]);
			this.menusVisibility[i]=false;
		}
	}
};

RealEstateTypeFinderMenu.prototype.initToggleButtons=function () {
	var obj=this;
	/*for (var i=0; i<this.menuContainersToggleButtons.length; i++) {
		(function () {
			var j=i;
			DOMEvent.addDomListener(obj.menuContainersToggleButtons[j],"click",function () {
				if (obj.menusVisibility[j]) {
					obj.menuContainersToggleButtons[j].src=obj.menuContainersToggleButtonsImages.hidden;
					obj.hideMenu(obj.menuContainers[j]);
					obj.menusVisibility[j]=false;
				} else {
					obj.menuContainersToggleButtons[j].src=obj.menuContainersToggleButtonsImages.visible;
					obj.showMenu(obj.menuContainers[j]);
					obj.menusVisibility[j]=true;
				}
			});
		})();
	}*/
	for (var i=0; i<this.menuContainersToggleArea.length; i++) {
		(function () {
			var j=i;
			DOMEvent.addDomListener(obj.menuContainersToggleArea[j],"click",function () {
				if (obj.menusVisibility[j]) {
					obj.menuContainersToggleButtons[j].src=obj.menuContainersToggleButtonsImages.hidden;
					obj.hideMenu(obj.menuContainers[j]);
					obj.menusVisibility[j]=false;
				} else {
					obj.menuContainersToggleButtons[j].src=obj.menuContainersToggleButtonsImages.visible;
					obj.showMenu(obj.menuContainers[j]);
					obj.menusVisibility[j]=true;
				}
			});
		})();
	}
};

RealEstateTypeFinderMenu.prototype.hideMenu=function (menuContainer) {
	DHTMLApi.Visibility.hide(menuContainer);
};

RealEstateTypeFinderMenu.prototype.showMenu=function (menuContainer) {
	DHTMLApi.Visibility.show(menuContainer);
};

RealEstateTypeFinderMenu.prototype.getMenuContainerIndex=function (menuContainer) {
	for (var i=0; i<this.menuContainers.length; i++) {
		if (this.menuContainers[i]===menuContainer) {
			return i;
		}		
	}
	return false;
};

RealEstateTypeFinderMenu.prototype.getMenusVisibility=function (visibleMenuIndex) {
	var menusVisibility=[];
	for (var i=0; i<this.menuContainers.length; i++) {
		if (i==visibleMenuIndex) {
			menusVisibility.push(true);
		} else {
			menusVisibility.push(false);
		}
	}
	return menusVisibility;
};

RealEstateTypeFinderMenu.prototype.getMenusVisibilityByParam=function (initParameterValue) {
	if (initParameterValue=="") return new Array(false,false,false);
	if (initParameterValue.charAt(0)=="s") return new Array(true,false,false);
	if (initParameterValue.charAt(0)=="p") return new Array(false,true,false);
	if (initParameterValue.charAt(0)=="z") return new Array(false,false,true);
};

RealEstateTypeFinderMenu.prototype.unselectAll=function() {
	this.finderMenu.unselectAll();
	this.display(new Array(false,false,false));
};

////////////////////////////////
// class RoomNumberFinderMenu //
////////////////////////////////

function RoomNumberFinderMenu(containerElement, optionsContainerElement, clearAllElement, finderParametersObject) {
	this.containerElement=containerElement;
	this.optionsContainerElement=optionsContainerElement;
	this.clearAllElement=clearAllElement;
	this.finderParametersObject=finderParametersObject;
	this.finderMenu=null
	this.init();
}

RoomNumberFinderMenu.prototype.init=function () {
	var initParameter;
	var obj=this;
	initParameter=(this.finderParametersObject.getParameterValue("nr")===false) ? "" : this.finderParametersObject.getParameterValue("nr");
	this.finderMenu=new FinderMenu(this.optionsContainerElement, initParameter, function (previousValue,currentValue) {
		obj.finderParametersObject.setParameters(obj,{nr: currentValue},["pg"]);
	});
	
	DOMEvent.addDomListener(this.clearAllElement, "click", function () {
		obj.finderMenu.unselectAll();
		obj.finderParametersObject.setParameters(obj,{},new Array("nr","pg"));
	});
};

RoomNumberFinderMenu.prototype.hide=function () {
	DHTMLApi.Visibility.hide(this.containerElement);
};

RoomNumberFinderMenu.prototype.show=function () {
	DHTMLApi.Visibility.show(this.containerElement);
};

/////////////////////////////
// Class ClearAgencyButton //
/////////////////////////////

function ClearAgencyButton(buttonElement, dataContainerElement, finderParametersObject) {
	DOMEvent.addDomListener(buttonElement,"click",function () {
		finderParametersObject.setParameters(this,{},new Array("a","pg"));
		window.location.href=window.location.pathname;
		//dataContainerElement.parentNode.removeChild(dataContainerElement);
		//URLs.storeReferrer("");
	});
}

/////////////////////////////
// Class NewProjectsFinder //
/////////////////////////////

/*
 requestURLs={locationsURL: string, cityPartsURL: string}
*/

function NewProjectsFinder(finderParametersObject, requestURLs) {
	var initParameterValue, realEstateType;
	var obj=this;
	this.finderParametersObject=finderParametersObject;
	this.finderParametersObject.addListener(this);
	this.requestURLs=requestURLs;
	this.xmlHttpRequestObject=null;
	
	initParameterValue=this.finderParametersObject.getParameterValue("r");
	if (initParameterValue===false) initParameterValue;
	this.onSelectRegion=function(previousValue,currentValue) {
		var parameterObject={};
		parameterObject["r"]=currentValue;
		obj.finderParametersObject.setParameters(obj,parameterObject, new Array("l","k","pg"));
		obj.locationInputField.locationInput.setValue("");
		obj.cityPartSelector.hide();
	}
	
	this.regionFinderMenu=new FinderMenu(document.getElementById("r_finder_menu"), initParameterValue, this.onSelectRegion);
	
	this.cityPartSelector=new CityPartSelector(document.getElementById("neighbourhood"), document.getElementById("neighbourhood_select"), this.finderParametersObject, this.requestURLs.cityPartsURL);
	
	this.locationInputField=new FinderLocationInputField(document.getElementById("acfield"), document.getElementById("acfieldcontainer"),this.requestURLs.locationsURL,this.finderParametersObject, this.cityPartSelector);
}

NewProjectsFinder.prototype.onLocationChange=function(eventObject) {
	if(eventObject.l.newValue=="") {
		this.cityPartSelector.hide();
	}
};

NewProjectsFinder.prototype.onLocationChange=function(eventObject) {
	if(eventObject.l.newValue=="") {
		this.cityPartSelector.hide();
	}
	if (eventObject.l.newValue!=eventObject.l.oldValue) {
		if (eventObject.r.newValue!="") {
			this.regionFinderMenu.unselectAll();
			this.regionFinderMenu.setSelected(this.regionFinderMenu.getListItem(eventObject.r.newValue));
		}
	}
};

/////////////////////////
// class FormValidator //
/////////////////////////

/*
formFields = {required: [id1, id2, ...], email: [id1, id2, ...], numeric: [id1, id2, ...], confirm: [[id1, id1a,...],[id2, id2a,...],]}
errorMessages = {required: string, email: string, numeric: string, confirm: string}
cssStyles = {invalidEntryField : string}
*/

function FormValidator(formElement,errorMsgContainerDiv,submitButtonElement,formFields,cssStyles,errorMessages,onSubmitCallBack) {
	this.formElement=formElement;
	this.errorMsgContainerDiv=errorMsgContainerDiv;
	this.cssStyles=cssStyles;
	if (typeof formFields.required !="undefined") {
		this.requiredFields=this.getElementsById(formFields.required);
	} else {
		this.requiredFields={};
	}
	if (typeof formFields.email !="undefined") {
		this.emailFields=this.getElementsById(formFields.email);
	} else {
		this.emailFields={};
	}
	if (typeof formFields.numeric !="undefined") {
		this.numericFields=this.getElementsById(formFields.numeric);
	} else {
		this.numericFields={};
	}
	if (typeof onSubmitCallBack !="undefined") {
		this.onSubmitCallBack=onSubmitCallBack;
	}
	this.confirmFields=[];
	if (typeof formFields.confirm !="undefined") {
		for (var i=0; i<formFields.confirm.length; i++) {
			if (formFields.confirm[i].length>1) {
				this.confirmFields[i]=this.getElementsById(formFields.confirm[i]);
			}
		}
	}
	this.submitButtonElement=submitButtonElement;
	this.errorMessages=errorMessages;
	this.init();
}

FormValidator.prototype.init=function () {
	var obj=this;
	DOMEvent.addDomListener(this.submitButtonElement,"click",function (eventObj) {
		DOMEvent.preventDefault(eventObj);
		obj.submit();
	});
};

FormValidator.prototype.getElementsById=function (elementIdArray) {
	var elements={};
	for (var i=0; i<elementIdArray.length; i++) {
		elements[elementIdArray[i]]=document.getElementById(elementIdArray[i]);
	}
	return elements;
};

FormValidator.prototype.checkRequiredField=function(inputElement) {
	return !((inputElement.value.search(/\w/)==-1) ? true : false);
};

FormValidator.prototype.checkEmailField=function(inputElement) {
	return (inputElement.value!="" && inputElement.value.search(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i)==-1) ? false : true;
};

FormValidator.prototype.checkNumericField=function(inputElement) {
	return (inputElement.value!="" && inputElement.value.search(/^[-+]?[0-9]*\.?[0-9]+$/)==-1) ? false : true;
};

FormValidator.prototype.checkConfirmField=function(inputElementObject) {
	var value;
	for (var id in inputElementObject) {
		value=inputElementObject[id].value;
		break;
	}
	for (var id in inputElementObject) {
		if (value!=inputElementObject[id].value) return false;
	}
	return true;
};

FormValidator.prototype.checkFields=function (inputFieldsObject,checkFunction) {
	var isOK=true;
	for (var id in inputFieldsObject) {
		if (checkFunction(inputFieldsObject[id])) {
			this.markFieldOK(inputFieldsObject[id]);
		} else {
			this.markFieldBad(inputFieldsObject[id]);
			isOK=false;
		}
	}
	return isOK;
};

FormValidator.prototype.markFieldOK=function (inputField) {
	DHTMLApi.CSS.setClass(inputField,[],new Array(this.cssStyles.invalidEntryField));
};

FormValidator.prototype.markFieldBad=function (inputField) {
	DHTMLApi.CSS.setClass(inputField,new Array(this.cssStyles.invalidEntryField),[]);
};

FormValidator.prototype.checkRequiredFields=function() {
	var okInput=this.checkFields(this.requiredFields,this.checkRequiredField);	
	if (!okInput) {
		this.displayErrorMessage(this.errorMessages.required);
		return false;
	} else {
		this.clearErrorMessage();
		return true;
	}
};

FormValidator.prototype.checkEmailFields=function() {
	var okInput=this.checkFields(this.emailFields,this.checkEmailField);	
	if (!okInput) {
		this.displayErrorMessage(this.errorMessages.email);
		return false;
	} else {
		this.clearErrorMessage();
		return true;
	}
};

FormValidator.prototype.checkNumericFields=function() {
	var okInput=this.checkFields(this.numericFields,this.checkNumericField);	
	if (!okInput) {
		this.displayErrorMessage(this.errorMessages.numeric);
		return false;
	} else {
		this.clearErrorMessage();
		return true;
	}
};

FormValidator.prototype.checkConfirmFields=function() {
	var okInput;
	for (var i=0; i<this.confirmFields.length; i++) {
		for (var id in this.confirmFields[i]) this.markFieldOK(this.confirmFields[i][id]);
	}
	this.clearErrorMessage();
	for (var i=0; i<this.confirmFields.length; i++) {
		okInput=this.checkConfirmField(this.confirmFields[i]);
		if (okInput===false) {
			for (var id in this.confirmFields[i]) this.markFieldBad(this.confirmFields[i][id]);
			this.displayErrorMessage(this.errorMessages.confirm);
			return false;
		} 
	}
};

FormValidator.prototype.displayErrorMessage=function(errorString) {
	this.errorMsgContainerDiv.innerHTML=errorString;
};

FormValidator.prototype.clearErrorMessage=function () {
	this.errorMsgContainerDiv.innerHTML="";
};

FormValidator.prototype.check=function() {
	if (this.checkRequiredFields()===false) {
		return false;
	}
	if (this.checkConfirmFields()===false) {
		return false;
	}
	if (this.checkEmailFields()===false) {
		return false;
	}
	if (this.checkNumericFields()===false) {
		return false;
	}
	return true;
};

FormValidator.prototype.submit=function() {
	if (this.check()) {
		if (typeof onSubmitCallBack !="undefined") {
			(this.onSubmitCallBack)();
		} 
		this.formElement.submit();
	}
};
