Search.search_mode = true;

Initializers.push(function()
{
	Search.last_used_filter = null;
	
	Search.AllResults = new Hash();

	Map.last_view = map.getBounds();
    GEvent.addListener(map, 'moveend', Search.Event_Handlers.View_Changed);
	GEvent.addListener(map, 'resized', Search.Event_Handlers.View_Changed);
    GEvent.addListener(map, "click", Search.Event_Handlers.Marker_Click);	

	Search.Initialize_Controls();

	if(Search.URL_Has_Search_Params())
		Search.Load_Search_From_Query_String(window.location.search);

	//Only search if we aren't locating the user and we haven't searched
	if (!Services.geoLocating && !Search.search_last_performed) 
		Search.Perform_Search();
	
	//Check the fields every half second.  When they change, set has_changed
	//At the next time the fields haven't changed for a half second, perform the search
	Search._has_changed = false;
	Search._last_checked_filter	= Search.Get_Search_Query_Params().join('&');	
	Search.form_checker = new PeriodicalExecuter(Search.check_search_changed, Search.FILTER_CHECK_FREQUENCY);
});

Search.Initialize_Controls = function()
{
  Map.Overlay_Manager._show_paths = $('opt_show_paths').checked = ClientSettings.get_setting('show_trail_paths');
 
	$('opt_show_paths').observe('click',function(){
		Map.Overlay_Manager._show_paths = $('opt_show_paths').checked == true;
		Map.Overlay_Manager.Reset_Loading();
		Map.Overlay_Manager.Update_Overlays();
    ClientSettings.set_setting('show_trail_paths', Map.Overlay_Manager._show_paths);
	});

  Map.Overlay_Manager._faster_computer = $('opt_more_overlays').checked = ClientSettings.get_setting('show_more_overlays');

	$('opt_more_overlays').observe('click', function(){
		Map.Overlay_Manager._faster_computer = $('opt_more_overlays').checked == true;
		Map.Overlay_Manager.Update_Overlays();
    ClientSettings.set_setting('show_more_overlays', Map.Overlay_Manager._faster_computer);
	});

	var slider_dist = $("slider-distance-max");
	if(slider_dist){
		var slide = new Slider(slider_dist, $("slider-distance-input-max"));	
		slide.onchange = function(){
			if(this.isValueSet())
				$('length-label-max').update(Units.length(this.getScaledValue()));
			else
				$('length-label-max').update("Not Set");
		}
		
		slide.getScaledValue = function(){
			return this.expand_range(this.log_scale_value(this), 100, 100000);
		}
		
		slide.expand_range = function(value, min, max){
			if(value <= 0)
				return min;
			if(value >=1)
				return max; 
			return min + ((value * value) * (1-value) + value * value) * (max-min);
		}
		
		slide.log_scale_value = function(slider){
			var s = this;
			var max = s.getMaximum();
			var lin = 1.025;
			var log = Math.log(max*lin - s.getValue());
			var min_log = Math.log(max * (lin - 1));
			var max_log = Math.log(max * lin);
			return 1 - (log - min_log) / (max_log - min_log);
		}		
		Search.UI.Max_Slider = slide;
	}
};

Search.UI.Clear_All = function(){
	Search.UI.Max_Slider.setValue(null);
	Search.UI.Multiselect_tags.invoke('clearSelections');
	$('trail_search_text').value = '';
	Search.UI.custom_route_button.setSelected(null);
}

Search.URL_Has_Search_Params = function(){
	return window.location.search  && window.location.search.length > 0;
}

Search.Load_Search_From_Query_String = function(params)
{
	if(typeof(params) == 'string')
		params = params.toQueryParams();
		
	inc_tag_ids = (params.tags_inc || "").split(/[|_]/);
	exc_tag_ids = (params.tags_exc || "").split(/[|_]/);
	
	if (inc_tag_ids.length > 0 || excc_tag_ids.length > 0) 
	{
		Search.UI.Multiselect_tags.each(function(multi)
		{
			multi.set_items_states(inc_tag_ids,1);
			multi.set_items_states(exc_tag_ids,2);			
		});
	}
	
	if(params.text)
		$('trail_search_text').value = decodeURIComponent(params.text);
	
	if(params.cust){
		Search.UI.custom_route_button.setSelected(params.cust);
	}
	
	if(params.len){
		Search.UI.Max_Slider.setValue(parseFloat(params.len));
	}
	
	if (params.loc && Init.Load_Loc_From_String(params.loc)) 
		return true;

	return false;
}

Search.Get_Search_Query_String = function()
{
	var params = Search.Get_Search_Query_Params();
	params.push("loc=" + encodeURIComponent(Init.Get_Loc_String()));
	
	return params.join("&");
}

Search.Get_Search_Query_Params = function()
{
	var params = [];
	var inc_tag_ids = [];
	var exc_tag_ids = [];
	
	Search.UI.Multiselect_tags.each(function(multi)
	{
		inc_tag_ids.push(multi.getSelectedIds("inc"));
		exc_tag_ids.push(multi.getSelectedIds("exc"));		
	});
	inc_tag_ids = inc_tag_ids.flatten().compact();
	exc_tag_ids = exc_tag_ids.flatten().compact();	
	
	if (inc_tag_ids.length > 0) 
		params.push("tags_inc=" + encodeURIComponent(inc_tag_ids.join('_')));
	if (exc_tag_ids.length > 0) 
		params.push("tags_exc=" + encodeURIComponent(exc_tag_ids.join('_')));
	
	var filter = Search.Build_Text_Filter();
	if(filter && filter.text && !filter.text.blank())
		params.push('text=' + encodeURIComponent(filter.text));
	
	var cust = Search.UI.custom_route_button.getSelected();
	if(cust) params.push('cust=' + cust);

	if(Search.UI.Max_Slider.isValueSet())
		params.push('len=' + Search.UI.Max_Slider.getValue());
	
	return params;
}


Search.Event_Handlers.View_Changed = function()
{
	var bounds =  map.getBounds();
	if (Map.last_view && !bounds.equals(Map.last_view)) 
	{
		Map.last_view = bounds;
		Search._reset_search_delay(Search.SEARCH_DELAY);
	}
};

Search.Search_Delay_executor = null;
Search._reset_search_delay = function(delay){
	if(Search.Search_Delay_executor)
		window.clearTimeout(Search.Search_Delay_executor);
	UI.show_Busy_Message("Searching...");
	Search.Search_Delay_executor = Search.Perform_Search.delay(delay);	
}

Search.check_search_changed = function(){
	var filter = Search.Get_Search_Query_Params().join('&');
	if (Search._last_checked_filter != filter) 
	{
		Search._has_changed = true;
		Search._reset_search_delay(Search.SEARCH_FILTER_DELAY);
	}
	Search._last_checked_filter = filter;	
};

Search.Perform_Search = function()
{
	UI.show_Busy_Message("Searching...");
	
	var filter = Search.Build_Filter();

	Search.last_used_filter = filter.unset('no_filter') ? null : filter;
	Search.search_last_performed = new Date();
	
    new Ajax.Request('/search/search_area',{ 
        parameters: filter.toObject(),
        method: 'get',
        onSuccess: Search.Callbacks.Successful,
        onFailure: Search.Callbacks.Failure,
		onComplete: function(){UI.hide_Message.delay(UI.MSG_DELAY);}
        });
};

Search.Callbacks.Successful = function(response){
//	try {
		switch(response.request.Type)
		{
			case "info":
				Search.ReadResults(response.responseXML);
				break;
			default:
				Search.MarkCachedSearchResults(Search.last_used_filter != null);
				Search.Callbacks.Process_Results(response.responseXML);
		}
/*	}
	catch(e)
	{
		UI.show_Error_Message(e.message);
		UI.hide_Message.delay(UI.MSG_DELAY);		
	}
	*/
};

Search.Callbacks.Failure = function(response)
{
	UI.show_Busy_Message("Search Failed");
	UI.hide_Message.delay(UI.MSG_DELAY);
};


Search.Build_Filter = function(dont_expand_search){
	var filter = new Hash();
	[Search.Build_Text_Filter(),
	 Search.Build_Tags_Filter(),
	 Search.Build_Dist_Filter(),
	 Search.Build_Loc_Filter(dont_expand_search)].each(function(filter_part){
		filter.update(filter_part);
	});
	
	var cust = Search.UI.custom_route_button.getSelected();
	if(cust) filter.set('custom_route', cust);
	
	//If there is only a location filter, then there are no filters set
	if(filter.size() <= 4)
		filter.set('no_filter', true);
	
	return filter;
}

Search.Build_Loc_Filter = function(dont_expand){
	var area = map.getBounds();
	
	if(!dont_expand)
		area = area.expand(Search.SEARCH_BOUNDS_EXPANSION);
	
    sw = area.getSouthWest();
    ne = area.getNorthEast();
	
	return {ne_lat: RoundDeg(ne.lat()), ne_lng: RoundDeg(ne.lng()), sw_lat: RoundDeg(sw.lat()), sw_lng: RoundDeg(sw.lng())};
}

Search.Build_Text_Filter = function(){
	var text = $F("trail_search_text");
	if(text && !text.blank())
		return {text: text.truncate(50, '')};
}

Search.Build_Dist_Filter = function(){
	if(Search.UI.Max_Slider.isValueSet())
		return {max_dist: Search.UI.Max_Slider.getScaledValue()};
}

Search.Build_Tags_Filter = function()
{
	var params = new Hash();

	var AND_tags = [];
	var NOT_tags = [];
	var i=0;
	
	Search.UI.Multiselect_tags.each(function(multi){
			var included = multi.getSelectedIds("inc");
			if(included.length > 0)
				AND_tags.push(included.join(','));
				
			NOT_tags.push(multi.getSelectedIds("exc"));
		});
	
	NOT_tags = NOT_tags.flatten();	

	if(AND_tags.length > 0)
		params.set('tags[AND]', AND_tags.join('|'));

	if(NOT_tags.length > 0)
		params.set('tags[NOT]', NOT_tags.join(','));
	
	return params;
};


//Need to break this method up
Search.Callbacks.Process_Results = function(results_node)
{
    var ResultsAry = [];
	var NewResults = [];
	
    var Start = new Date();
	
	UI.show_Busy_Message("Loading...");
	
	//Convert the XML into javascript objects, or get them from previus results 
	var results = Search.ReadResults(results_node);
		
    var Parse = (new Date()) - Start;
	//======
	
	if(results) 
	{
		results.all_results.each(function(trail)
		{
			Map.Overlay_Manager.Add_Trail(trail);
		});
	}
	
	//Start immediately
	Map.Overlay_Manager.Reset_Loading();

	UI.show_Busy_Message("Displaying..."); 

    var Create = ((new Date()) - Start) - Parse;
	//======  

	Map.Overlay_Manager.Update_Overlays();
			
    var Add = ((new Date()) - Start) - Parse - Create;
    
	/*
    GLog.write("Parse: " + Parse);
    GLog.write("Create: " + Create);    
    GLog.write("Add: " + Add);
	GLog.write("new Results: " + NewResults.length);
	*/
	UI.hide_Message();    
};


Search.Request_TrailDetails = function(trail, success_callback)
{
    var Request = new Ajax.Request('/trails/get/' + trail.id,{ 
        method: 'get',
        onSuccess: function(response)
			{
				Search.Callbacks.Successful(response);
				if(success_callback)
					success_callback(trail);
			},
        onFailure: Search.Callbacks.Failure,
		onComplete: function(){UI.hide_Message.delay(UI.MSG_DELAY);}
        });
		
	Request.Type = 'info';
};


Search.ReadResults = function(results_node)
{
	if(!results_node || !results_node.documentElement)
		return;
		
	var Results = [];
	var NewResults = [];	
	
	//Convert the XML into javascript objects, or get the from previus results 
    $A(results_node.documentElement.childNodes).each(function(node)
    {
		//only 't' Elements, thanks.
        if(node.nodeType != 1 || node.nodeName != "t")
			return;
		
		var trail_id = node.getAttribute("id");
		
		var storedObj = Search.AllResults.get(trail_id);
		
		if (!Object.isUndefined(storedObj)) 
			storedObj.UpdateFromXML(node);
		else 
		{
			storedObj = Trail.ReadFromXML(node, true);
			NewResults.push(storedObj);
		}
		
		Results.push(storedObj);
		
		Search.AllResults.set(storedObj.id, storedObj);
    });
	
	return {
		all_results: Results,
		new_results: NewResults
	};
};

Search.MarkCachedSearchResults = function(in_filtered)
{
	Search.AllResults.each(function(pair){pair.value.filtered = in_filtered;});
}


Search.UI.UpdateInfoWindow = function(trail)
{
  if (trail.hasMetaInfo())
  {
  	var c = Common.info_window;
    c.title.update(trail.title ? trail.title.truncate(60) : "");
    c.description.update(trail.description ? trail.description.truncate(200): "");  
    
    //Links
	var params = {ID:trail.id};
	Search.UI._info_window_trail = trail;
    c.viewdetails.setAttribute("href", UI.InfoWindow.View_Details_href.evaluate(params));
    c.edit.setAttribute("href", UI.InfoWindow.Edit_href.evaluate(params));
	Search.UI.InfoWindow.current_trail = trail;
    if (c['delete']) c['delete'].setAttribute("onclick", UI.InfoWindow.Delete_onclick.evaluate(params));	
	c.zoomtoview.show();
	c.zoomout.hide();

	c.distance.update(Units.length(trail.getDistance()));    
	
	if (trail.hasTrack()) 
	{
		var track = trail.get_primary_track();
		c.alt_change.update(Units.length(track.altitude_change, 1));
		c.alt_gain.update(Units.length(track.altitude_gain, 1));
		c.alt_loss.update(Units.length(track.altitude_loss, 1));
		c.uphill_dist.update(Units.length(track.uphill_dist));
		c.downhill_dist.update(Units.length(track.downhill_dist));
	}
	else{
		[c.alt_change,
		c.alt_gain,
		c.alt_loss,
		c.uphill_dist,
		c.downhill_dist].each(function(e){e.update('-');});
	}
  }
}; 

Search.UI.ShowInfoWindow = function(trail)
{
	Search.UI.UpdateInfoWindow(trail);
	map.openInfoWindow(trail.start_loc, Common.infowindow_basic);
};

Search.UI.ZoomToTrail = function(id)
{
	var trail = Search.AllResults.get(id);
	map.savePosition();
	Common.info_window.zoomtoview.hide();
	Common.info_window.zoomout.show();
	
	Map.RecenterView(trail);
};

Search.UI.ZoomBackOut = function()
{
	map.returnToSavedPosition();
	Common.info_window.zoomtoview.show();
	Common.info_window.zoomout.hide();
}

Search.UI.send_Share_Search_Email = function()
{
	$('share_url').value = "/search?" + Search.Get_Search_Query_String(); 
	$("share_form").request({parameters: Search.Build_Filter(true).toObject()});
	UI.closeWizard();
}

Search.Event_Handlers.Marker_Click = function(overlay, latlng)
{
    //If they clicked on a marker
    if(overlay && overlay.getLatLng && overlay.trail)
	{
		var trail = overlay.trail;

		var success_func = function(trail){
				UI.hide_Message();
				var visible = Map.Overlay_Manager.Toggle_Trail_Visibility(trail);
				if(visible) Search.UI.ShowInfoWindow(trail);
			};
		
		if (!trail.hasMetaInfo()) 
		{
			UI.show_Busy_Message("Requesting Trail Info...");
			Search.Request_TrailDetails(trail, success_func);
		}
		else
		{
			success_func(trail);
		}
	}	
};

//Tells the location loader that the location has already been loaded
//(in Search.init) if the url has search params
Loc_Loaders.push(function() {return	Search.URL_Has_Search_Params();});