function EstateWeb_Objects_PropertySearch(){
	this.searchCriteria = new EstateWeb_Objects_PropertySearch_SearchCriteria(this);
	this.properties = new EstateWeb_Objects_PropertySearch_Properties(this);
	this.search = EstateWeb_Objects_PropertySearch_Search;
	this.presearchvalidation = EstateWeb_Objects_PropertySearch_PreSearchValidation;
	this.events = new HttpManager.Browser.eventManager();
	this.mapping = new EstateWeb_Objects_PropertySearch_Mapping(this);
	//events
	this.onPriceRangeChanged = EstateWeb_Objects_PropertySearch_OnPriceRangeChanged;
	this.onOfficesSelectedChanged = EstateWeb_Objects_PropertySearch_OnOfficesSelectedChanged;
	this.onBedroomRangeChanged = EstateWeb_Objects_PropertySearch_OnBedroomRangeChanged;
	this.onStatusesSelectedChanged = EstateWeb_Objects_PropertySearch_OnStatusesSelectedChanged;
}

function EstateWeb_Objects_PropertySearch_Properties(o){
	this.items = new Array();
	this.getProperty = EstateWeb_Objects_PropertySearch_Properties_GetProperty;
	this.totalResultCount = 0;
	this.clear = EstateWeb_Objects_PropertySearch_Properties_Clear;
	this.sorting = new EstateWeb_Objects_PropertySearch_Properties_Sorting(this);
}

function EstateWeb_Objects_PropertySearch_Properties_GetProperty(propertyReference){
	for ( var i = 0; i < this.items.length; i ++ ){
		if ( this.items[i].propertyReference == propertyReference ){
			return this.items[i];
		}
	}
}

function EstateWeb_Objects_PropertySearch_Properties_Clear(){
	this.items.splice(0, this.items.length);
}

function EstateWeb_Objects_PropertySearch_Properties_Sorting(o){
	this.parent = o;
	this.sortLatitudeDesc = EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLatitudeDesc;
	this.sortLatitudeAsc = EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLatitudeAsc;
	this.sortLongitudeDesc = EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLongitudeDesc;
	this.sortLongitudeAsc = EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLongitudeAsc;
}

function EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLatitudeDesc(){
	//copy the array so we dont affect the order
	var localproperties = this.parent.items;
	localproperties.sort( function(a,b){ return (b.mapping.latitude - a.mapping.latitude) } );
	return localproperties;
}

function EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLatitudeAsc(){
	//copy the array so we dont affect the order
	var localproperties = this.parent.items;
	localproperties.sort( function(a,b){ return (a.mapping.latitude - b.mapping.latitude) } );
	return localproperties;
}

function EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLongitudeDesc(){
	//copy the array so we dont affect the order
	var localproperties = this.parent.items;
	localproperties.sort( function(a,b){ return (b.mapping.longitude - a.mapping.longitude) } );
	return localproperties;
}

function EstateWeb_Objects_PropertySearch_Properties_Sorting_SortLongitudeAsc(){
	//copy the array so we dont affect the order
	var localproperties = this.parent.items;
	localproperties.sort( function(a,b){ return (a.mapping.longitude - b.mapping.longitude) } );
	return localproperties;
}

function EstateWeb_Objects_PropertySearch_Mapping(o){
	this.parent = o;
	this.calculateCenter = EstateWeb_Objects_PropertySearch_Mapping_CalculateCenter;
}


function EstateWeb_Objects_PropertySearch_Mapping_CalculateCenter(){
	//calculates bounds of a rectangle by getting the min/max latitude and min/max longitude
	var nlat = 0;
	var slat = 0;
	var elon = 0;
	var wlon = 0;
	
	var aproperties = new Array();
	try{
		aproperties = this.parent.properties.sorting.sortLatitudeDesc();
		nlat = aproperties[0].mapping.latitude;
		slat = aproperties[aproperties.length -1].mapping.latitude;
		aproperties = this.parent.properties.sorting.sortLongitudeDesc();
		elon = aproperties[0].mapping.longitude;
		wlon = aproperties[aproperties.length -1].mapping.longitude;
	}catch(e){
		HttpManager.Document.Errors.add("Property Search Manager", "Unable to calculate center point from results");
		HttpManager.Document.Errors.show();
	}

	
	return [ nlat, slat, elon, wlon ];
}

function EstateWeb_Objects_PropertySearch_Search(){
	this.properties.clear();
	this.events.raiseEvent("searchbegin", this, null);
	//search properties using the criteria provided
		if ( this.presearchvalidation() ){
			MapView.Search(
										this.searchCriteria.pagingDetails.pageNumber,
										this.searchCriteria.pagingDetails.itemsPerPage,
										function(o){	
											if ( o.error ){
												HttpManager.Document.Errors.add("Property Search Manager", "There was an error performing a search");
												HttpManager.Document.Errors.show();
											}else{
												//results received, stored locally
												for ( var i = 0; i < o.value.length; i ++ ){
													var opropertydetails = o.value[i];
													o.context.properties.totalResultCount = opropertydetails.ResultCount;
													var oproperty = new EstateWeb_Objects_Property();
													with ( oproperty ){
														propertyReference = opropertydetails.PropertyReference;
														mapping.latitude = opropertydetails.PropertyLatitude;
														mapping.longitude = opropertydetails.PropertyLongitude;
														propertyStatusID = opropertydetails.PropertyStatus;
														propertyListingType = opropertydetails.PropertyListingType;
														propertyAddress.formattedAddress = opropertydetails.PropertyAddress;
														propertyPrice.formattedPrice = opropertydetails.PropertyFormattedPrice;
														officeID = opropertydetails.PropertyLocationID;
														detailsURL = opropertydetails.PropertyDetailsURL;
													}
													o.context.properties.items.push( oproperty );
												}
												o.context.events.raiseEvent("searchcompleted", o.context, null);											
											}
										 }, 
										 this
									   )
		}
	//

}

function EstateWeb_Objects_PropertySearch_SearchCriteria(o){
	this.listingType = 5;
	this.minimumPrice = -1;
	this.maximumPrice = -1;
	this.offices = new Array();
	this.areas = new Array();
	this.minimumBedrooms = -1;
	this.maximumBedrooms = -1;
	this.quickSearch = "";
	this.statuses = new Array();
	this.pagingDetails = new EstateWeb_Objects_PropertySearch_SearchCriteria_PagingDetails();
}

function EstateWeb_Objects_PropertySearch_SearchCriteria_PagingDetails(){
	this.itemsPerPage = 10;
	this.pageNumber = 1;
	this.resultCount = 0;
}

function EstateWeb_Objects_PropertySearch_PreSearchValidation(){
	if ( typeof MapView == "undefined" ){
		HttpManager.Document.Errors.add("Property Search Manager", "Unable to find search proxy class");
	}
	
	if ( HttpManager.Document.Errors.errors.length > 0 ){
		HttpManager.Document.Errors.show();
		return false;
	}
	return true;
}

//############ Events #####################

function EstateWeb_Objects_PropertySearch_OnPriceRangeChanged(creator,sender,eventArgs){
	creator.searchCriteria.minimumPrice = eventArgs.minimumPrice;
	creator.searchCriteria.maximumPrice = eventArgs.maximumPrice;
}

function EstateWeb_Objects_PropertySearch_OnOfficesSelectedChanged(creator,sender,eventArgs){
	creator.searchCriteria.offices = eventArgs.offices;
}

function EstateWeb_Objects_PropertySearch_OnBedroomRangeChanged(creator,sender,eventArgs){
	creator.searchCriteria.minimumBedrooms = eventArgs.minimumBedrooms;
	creator.searchCriteria.maximumBedrooms = eventArgs.maximumBedrooms;
}

function EstateWeb_Objects_PropertySearch_OnStatusesSelectedChanged(creator,sender,eventArgs){
	creator.searchCriteria.statuses = eventArgs.statuses;
}