var toll = toll || {};
(function(){
	//Data from server:
	// Array of current search results for sequential processing
	var _communities=new Array();
	// Map of   search results for random access
	var _communitiesMap={};
	// Min/Max latitude/longitude
	var _latLngBounds={};
	//
	//User:
	var _selectedCommunities=new Array();
	//
	// Listeners/Subscribers to events broadcast by this:
	var _searchResultsListeners=new Array();
	var _searchResultsErrorListeners=new Array();
	var _searchResultsBeforeSendListeners=new Array();
	//
	var _selectedCommunitiesListeners=new Array();
	var _sortListeners=new Array();
	
	
	var _hasSearchResults=false;
	var _SEARCH_URL='/tollbrothers/search';

	var _jsonBaseURL="/homesearch/servlet/HomeSearch?app=search_JSON";
	// var _jsonBaseURL="http://172.16.20.197/~braddiver/TollSearchPage/test-json.txt";
	
	// Server JSON: {communities:[{number:"",..}],parameters:{s_state:["NJ"],app:["search_JSON"],callback:["myfunctioncallback"]}}
	var _jsonDataMap={
		communities:"communities",
		params:"parameters"
	}
	var _communityTOMap={
		communityNumber:"number",  // 8927
		communityName:"name", // "Bushkill Manor by Toll Brothers"
		county:"county", // "Northampton"
		state:"state", // "PA"
		city:"city",  // "Nazareth"
		email:"email",  // "bushkillmanor@tollbrothersinc.com"
		latitude:"latitude",   // 40.75555
		longitude:"longitude",   // -75.29583
		qdhTotal:"qdh",  // 0
		sqft:"avg_sqft",  // 3953	
		distance:"distance",  // -1.0
		comm_type:"comm_type",  /*[]*/
		home_type:"home_type",  /*[]*/
		image:"thumbnail",  // "/communities/8927/images/hampton_georgian_ban_sm.jpg"
		master_comm_id:"master_comm_id",  // 111	
		price:"price",  // 549975
		priceRange:"price_format"  // "Mid- $500,000s"
	};

	var _setSearchResults=function(jsonData/*{   communities:[{id:,name:,..}],
		 										parameters:{callback:[],app:[],s_state:[],}   }*/){
		
		var communities=jsonData[_jsonDataMap.communities];
		var params=jsonData[_jsonDataMap.params];
		
		
		if(communities != null)_hasSearchResults=true;
		_communities=communities;
		// 1. Initialize with community Array, mapBounds object
		for(var i=0;i<communities.length;i++){
			var com=communities[i];
			_communitiesMap[com[_communityTOMap.communityNumber]]=com;
		}
		//Notify listeners
		var s=_searchResultsListeners;
		for(var i=0,len=_searchResultsListeners.length; i<len; i++) {
			var listener=_searchResultsListeners[i];
			listener(communities, params);
		}
	};

	//Keys are added to _searchCriteria at runtime - they match keys in _paramMap, 
	//    and store values to be sent with ajax request
	var _searchCriteria={};
	
	var _paramMap={
		//  Use this map to access server parameter names
		//  "parameters":{ "s_county":[""], "sort":["COMM_NAME"], "f_type":[""], "app":["search_JSON"], "s_state":["TX"], "s_area":[""] }
		app:"app", //["search_JSON"] 
		callback:"callback", //[] 
		
		//Search criteria
		state:"s_state", //[]
		area:"s_area",
		zip:"s_zip",
		community_type:"f_type",
		county:"s_county", //[] 
		radius:"s_radius",// end brad
		home_type:"s_home",
		school_district:"s_school_district",
		price_min:"s_p_min",
		price_max:"s_p_max",
		sqft:"sq_ft",
		bedrooms:"s_beds",
		bathrooms:"s_bath",
		garages:"s_gar",
		stories:"s_stories",
		master_bedroom:"s_master_bedroom",
		
		//Sort
		sort:"sort", //[] sort by --> community name:"COMM_NAME", home type:"HTML_COMM_TYPE", "MIN_PRICE", "COUNTY", "AVG_SQFT"
		sort_order:"sortord" // 'd' if descending, otherwise ascending
	}
	
	toll.Model={
		
		
		// Search-criteria setters - for UI controlls giving user fine-grain search ability on page.
		setState:function(state){
			_searchCriteria.state=state;
		},
		setArea:function(area){
			_searchCriteria.area=area;
		},
		setZip:function(zip){
			_searchCriteria.zip=zip;
		},
		setCommunityType:function(communityType){
			_searchCriteria.communityType=communityType;
		},
		setCounty:function(county){
			_searchCriteria.county=county;
		},
		setRadius:function(radius){
			_searchCriteria.radius=radius;
		},
		setHomeType:function(homeType){
			_searchCriteria.homeType=homeType;
		},
		setSchoolDistrict:function(schoolDistrict){
			_searchCriteria.schoolDistrict=schoolDistrict;
		},
		setPriceMin:function(priceMin){
			_searchCriteria.priceMin=priceMin;
		},
		setPriceMax:function(priceMax){
			_searchCriteria.priceMax=priceMax;
		},
		setSQFT:function(sqft){
			_searchCriteria.sqft=sqft;
		},
		setBedrooms:function(bedrooms){
			_searchCriteria.bedrooms=bedrooms;
		},
		setBathrooms:function(bathrooms){
			_searchCriteria.bathrooms=bathrooms;
		},
		setGarages:function(garages){
			_searchCriteria.garages=garages;
		},
		setStories:function(stories){
			_searchCriteria.stories=stories;
		},
		setMasterBedroom:function(masterBedroom){
			_searchCriteria.masterBedroom=masterBedroom;
		},
		//  End search-criteria setters
		
		
		
		
		getCommunityTOMap:function(){
			return _communityTOMap;
		},
		getSearchParamMap:function(){
			return _paramMap;
		},
		
		hasSearchResults:function(){
			return _hasSearchResults;
		},
		
		getCommunities:function(){
			return 	_communities;		
		},
		
		getCommunitiesMap:function(){
			return _communitiesMap;
		},
	
		
		//  
		setSearchCriteriaFromQueryString:function(){
			function getURLQueryParamValue(key){
				// Lib:   jquery.query    (jQuery plugin)
				var val = $.query.get(key);
				//Library quirk: '$.query.get' returns true if the param is in the url but the value is empty
				return val==null || val==true ? '' : val;
			}
			_searchCriteria.state = getURLQueryParamValue(_paramMap.state);
			_searchCriteria.radius = getURLQueryParamValue(_paramMap.radius);
			_searchCriteria.zip = getURLQueryParamValue(_paramMap.zip);
			_searchCriteria.county = getURLQueryParamValue(_paramMap.county);
			_searchCriteria.area = getURLQueryParamValue(_paramMap.area);
			_searchCriteria.community_type = getURLQueryParamValue(_paramMap.community_type);
			_searchCriteria.home_type = getURLQueryParamValue(_paramMap.home_type);
			_searchCriteria.school_district = getURLQueryParamValue(_paramMap.school_district);
			_searchCriteria.price_min = getURLQueryParamValue(_paramMap.price_min);
			_searchCriteria.price_max = getURLQueryParamValue(_paramMap.price_max);
			_searchCriteria.sqft = getURLQueryParamValue(_paramMap.sqft);
			_searchCriteria.bedrooms = getURLQueryParamValue(_paramMap.bedrooms);
			_searchCriteria.bathrooms = getURLQueryParamValue(_paramMap.bathrooms);
			_searchCriteria.garages = getURLQueryParamValue(_paramMap.garages);
			_searchCriteria.stories = getURLQueryParamValue(_paramMap.stories);
			_searchCriteria.master_bedroom = getURLQueryParamValue(_paramMap.master_bedroom);
			
			_searchCriteria.sort = getURLQueryParamValue(_paramMap.sort);
			_searchCriteria.sort_order = getURLQueryParamValue(_paramMap.sort_order);
		},
	
	
		sortCommunities:function(communityProp/*'' (string)  -use getCommunityTOMap()[propName]*/, ascending){
			serverSortParamMap={// community name:"COMM_NAME", home type:"HTML_COMM_TYPE", "MIN_PRICE", "COUNTY", "AVG_SQFT"
				"name":"COMM_NAME", // "Bushkill Manor by Toll Brothers"
				"county":"COUNTY", // "Northampton"
				"avg_sqft":"AVG_SQFT",  // 3953	
				"home_type":"HTML_COMM_TYPE",  /*[]*/
				"price":"MIN_PRICE",  // 549975
				"city":"CITY"
			}
			
			
			
			_searchCriteria.sort=serverSortParamMap[communityProp];
			_searchCriteria.sort_order=ascending ? '' : 'd';
			
			/*  Sort data
			var isSorted=false;
			if(communityProp == _communityTOMap.communityName){
				_sortByAlpha(_communities,_communityTOMap.communityName, ascending);
				isSorted=true;
			}else if(communityProp == _communityTOMap.price){
				_sortByNumeric(_communities,_communityTOMap.price, ascending);
				isSorted=true;
			}else if(communityProp == _communityTOMap.sqft){
				_sortByNumeric(_communities,_communityTOMap.sqft, ascending);
				isSorted=true;
			}else if(communityProp == _communityTOMap.home_type){
				_sortByAlpha(_communities,_communityTOMap.home_type, ascending);
				isSorted=true;
			}else if(communityProp == _communityTOMap.county){
				_sortByAlpha(_communities,_communityTOMap.county, ascending);
				isSorted=true;
			}
			if(isSorted==false)return;
			*/
			
			
			//Notify listeners
			for(var i=0,len=_sortListeners.length; i<len; i++) {
				var listener=_sortListeners[i];
				//Broadcast sorted array (re-draw dom based on sorted array - slow in ie).
				//listener(_communities);
				//
				//Broadcast only sortby criteria (use jquery tinysort plugin to sort dom elements - fast in ie)
				listener(communityProp, ascending);
			}
		},


		// Subscribe to Model events
		addSearchResultsListener:function(listener/*function(communities:[{id:,name:,..}]*/){
			//Add subscriber to new search results loaded (via ajax) event. Array of all communities in search result will be passed to all subscribers.
			if(listener==null || typeof listener != 'function')throw new Error('SearchResults listener is not a function or is null!');
			_searchResultsListeners.push(listener);
		},
		
		addSearchResultsErrorListener:function(listener/*function(communities/*[{id:,name:,..}]*/){
			// Add subscriber to search result error (timeout or server error).
			if(listener==null || typeof listener != 'function')throw new Error('SearchResultsError listener is not a function or is null!');
			
			_searchResultsErrorListeners.push(listener);
		},
		
		addSearchResultsBeforeSendListener:function(listener/*function(communities/*[{id:,name:,..}]*/){
			// Add subscriber to search result error (timeout or server error).
			if(listener==null || typeof listener != 'function')throw new Error('SearchResultsBeforeSend listener is not a function or is null!');
			_searchResultsBeforeSendListeners.push(listener);
		},
		
		addSortListener:function(listener/*function(communities/*[{id:,name:,..}]*/){
			//Add subscriber to resort of community array event. Array of all communities (resorted) will be passed to subscribers.
			if(listener==null || typeof listener != 'function')throw new Error('listener is not a function or is null!');
			_sortListeners.push(listener);
		},
		addSelectedCommunitiesListener:function(listener/*function(selectedCommunities/*[{id:,name:,..}]*/){
			//Add subscriber to select/highlight communities event.  Array of selected communities in search result will be passed to all subscribers.
			if(listener==null || typeof listener != 'function')throw new Error('listener is not a function or is null!');
			_selectedCommunitiesListeners.push(listener);
		},

		// End  Subscribe to Model events
		

		getSearchResults:function(){
			//Hit the server for JSON data
			//Object to serialize into URL-encoded key-value pairs (request parameters) to send with ajax request,
			var qparams={};
			//
			//data = _searchCriteria;
			
			qparams[_paramMap.state]=_searchCriteria.state;
			qparams[_paramMap.radius]=_searchCriteria.radius;
			qparams[_paramMap.zip]=_searchCriteria.zip;
			qparams[_paramMap.county]=_searchCriteria.county;
			qparams[_paramMap.area]=_searchCriteria.area;
			qparams[_paramMap.community_type]=_searchCriteria.community_type;
			qparams[_paramMap.home_type]=_searchCriteria.home_type;
			qparams[_paramMap.school_district]=_searchCriteria.school_district;
			qparams[_paramMap.price_min]=_searchCriteria.price_min;
			qparams[_paramMap.price_max]=_searchCriteria.price_max;
			qparams[_paramMap.sqft]=_searchCriteria.sqft;
			qparams[_paramMap.bedrooms]=_searchCriteria.bedrooms;
			qparams[_paramMap.bathrooms]=_searchCriteria.bathrooms;
			qparams[_paramMap.garages]=_searchCriteria.garages;
			qparams[_paramMap.stories]=_searchCriteria.stories;
			qparams[_paramMap.master_bedroom]=_searchCriteria.master_bedroom;
			
			qparams[_paramMap.sort]=_searchCriteria.sort;
			qparams[_paramMap.sort_order]=_searchCriteria.sort_order;

			var _url_params = location.search;
			if(_url_params.indexOf("app=az") >= 0) _url_params = "&s_state=AZ";
			else if(_url_params.indexOf("app=ca") >= 0) _url_params = "&s_state=CA";
			else if(_url_params.indexOf("app=co") >= 0) _url_params = "&s_state=CO";
			else if(_url_params.indexOf("app=ct") >= 0) _url_params = "&s_state=CT";
			else if(_url_params.indexOf("app=de") >= 0) _url_params = "&s_state=DE";
			else if(_url_params.indexOf("app=fl") >= 0) _url_params = "&s_state=FL";
			else if(_url_params.indexOf("app=ga") >= 0) _url_params = "&s_state=GA";
			else if(_url_params.indexOf("app=il") >= 0) _url_params = "&s_state=IL";
			else if(_url_params.indexOf("app=md") >= 0) _url_params = "&s_state=MD";
			else if(_url_params.indexOf("app=ma") >= 0) _url_params = "&s_state=MA";
			else if(_url_params.indexOf("app=mi") >= 0) _url_params = "&s_state=MI";
			else if(_url_params.indexOf("app=mn") >= 0) _url_params = "&s_state=MN";
			else if(_url_params.indexOf("app=nv") >= 0) _url_params = "&s_state=NV";
			else if(_url_params.indexOf("app=nh") >= 0) _url_params = "&s_state=NH";
			else if(_url_params.indexOf("app=nj") >= 0) _url_params = "&s_state=NJ";
			else if(_url_params.indexOf("app=ny") >= 0) _url_params = "&s_state=NY";
			else if(_url_params.indexOf("app=nc") >= 0) _url_params = "&s_state=NC";
			else if(_url_params.indexOf("app=oh") >= 0) _url_params = "&s_state=OH";
			else if(_url_params.indexOf("app=pa") >= 0) _url_params = "&s_state=PA";
			else if(_url_params.indexOf("app=ri") >= 0) _url_params = "&s_state=RI";
			else if(_url_params.indexOf("app=sc") >= 0) _url_params = "&s_state=SC";
			else if(_url_params.indexOf("app=tx") >= 0) _url_params = "&s_state=TX";
			else if(_url_params.indexOf("app=va") >= 0) _url_params = "&s_state=VA";
			else if(_url_params.indexOf("app=ne") >= 0) _url_params = "&s_state=MA&s_state=RI&s_state=NH";
			else {
				_url_params = _url_params.replace(/app=[a-zA-Z0-9]*&/, "");
				_url_params = _url_params.replace(/\?/,"&");
			}

			/*adf*/
			
			// Determine whether to use cross-domain ajax method (jq timeout will not work) or standard ajax XHR (jq timeout works).
			var dataType='';
			var domainWindow=window.location.protocol+'//'+window.location.host;
			var isCrossDomain=_jsonBaseURL.indexOf(domainWindow)==-1;
			
			if(isCrossDomain){
				dataType='jsonp';
			}else{
				dataType='json';
			}
			
			for(var i=0;i<_searchResultsBeforeSendListeners.length;i++){
	    		_searchResultsBeforeSendListeners[i]();
	    	}

			$.ajax({
			 	type: "GET",
			 	cache: false,
//			    url: _jsonBaseURL,
//			    data: qparams,
url: _jsonBaseURL+_url_params,
			    async: true,
			    contentType: "application/x-www-form-urlencoded",
			   // beforeSend: function(XMLHttpRequest){
			    	
			    //},
			   // data: _searchCriteria,
			    dataType: dataType,
			    //Cross domain ajax   dataType:"jsonp"
			    //jsonp:'getCrossDomainSearchResults',
			    timeout: 6000,
			    success: function(data, textStatus){
					_setSearchResults(data);
			    },
			    error: function(XMLHttpRequest, textStatus, errorThrown){
			    	//$('div#loadstatus')[0].innerHTML='Error loading data';
			    	var errorMessage;
			    	for(var i=0;i<_searchResultsErrorListeners.length;i++){
			    		//XMLHttpRequest.
			    		if(textStatus == 'timeout'){
			    			errorMessage=('There was a time-out while attempting to load search results');
			    		}else{
			    			errorMessage=('There was an error loading search results');
			    			
			    		}
			    		_searchResultsErrorListeners[i](errorMessage);
			    	}
			    }
			 });
			
		},
		
		setSelectedCommunities:function(communityNumbers/*[""]*/){
			//Highlight a specific community or group of communities
			//Validate input
			var arr=new Array();
			for(var i=0; i<communityNumbers.length; i++) {
				var num=communityNumbers[i];
				var com=communitiesMap[num];
				if(com != null)arr.push(com);
			}
			if(arr.length==0)return;
			_selectedCommunities=arr;
			
			//Notify listeners
			for(var i=0,len=_selectedCommunitiesListeners.length; i<len; i++) {
				var listener=_selectedCommunitiesListeners[i];
				listener(_selectedCommunities);
			}
		}
	}

})();
