/**
 *	D3mls Search
 *	
 *	Version History
 *	2011-11-10	2.16	Added ability to clear locations from the hidden location field
 *	2011-11-9	2.15	Searches entire document for paginationLink class so any pagination links outside of the search form will perform the search
 *	2011-8-30	2.14	Added ability to float a search form
 *	2011-8-16	2.13	Updated for Coldwell Refine Search form
 *	2011-7-20	2.12	Systematize form and ajax queries
 *	2011-7-20	2.11	Custom d3mls_maps infowindow for Home Deals
 *	2011-7-19	2.1		Set the dimmed box to also empty out its selected locations
 *	2011-7-11	2.0		Converted from literal singleton
 *	
 * 	@author D3
 *	@version 2.15
 *	@date 2011-11-9
 */
function Search()
{
	this.buttonClass = "button";
	this.divId = "d3mls_search";
	this.formName = "search_form";
	this.loadingIcon = "/images/ajax-loader.gif";
	this.progressTarget;
	this.view = "LOCATIONS";
	this.ajax = false;
	this.ajaxDivId = "d3mlsListings";
	this.$loadingBlanket = null;
	this.$loadingIcon = null;
	//	2D Array to hold a list of geographic divisions (currently regions, counties, areas, cities and sub_divisions)
	this.selectedLocations = [["Delaware"],[],[],[],[]];
	//	Array of scrollTops, one per select box, for remembering where in the box a location input was checked
	this.selectScrollTops = [0,0,0,0,0];
	this.query = [];//query object
	this.queryStr = null;//holds the query obj as a str
	this.query["view"] = this.view;
}

/**
 *	Initialization
 *	@param divId String Div that contains the form OR contains the tabs (in that case, form is outside the tabs)
 *	@param formName String Name of the search form
 *	@param view String Determine view to send to ajax controller (currently used for location boxes only
 *	@param ajax Boolean Whether to POST the form or get the results via ajax 
 *	@param ajaxDivId String The div to post ajax results
 *	@param buttonClass String Class of anchors serving as form buttons
 *	@param loadingIcon String Path to the progress icon
 *	@param progressTarget String Div to append progress icon to
 */
Search.prototype.init = function(divId, formName, view, ajax, ajaxDivId, buttonClass, loadingIcon, progressTarget)
{
	if (divId != null)
		this.divId = divId;
	if (formName != null)
		this.formName = formName;
	if (view != null)
	{
		this.view = view;
		this.query["view"] = this.view;
	}
	if (ajax != null)
		this.ajax = ajax;
	if (ajaxDivId != null)
		this.ajaxDivId = ajaxDivId;
	if (buttonClass != null)
		this.buttonClass = buttonClass;
	if (loadingIcon != null)
		this.loadingIcon = loadingIcon;
	if (progressTarget != null)
		this.progressTarget = progressTarget;

	this.setupSearchForm();
};

/**
 *	Set up search form, bind buttons, form inputs, progress wheels, etc.
 */
Search.prototype.setupSearchForm = function()
{
	var self = this;
	//bind submit and reset buttons
	$("#"+this.divId+" a."+this.buttonClass).bind("click", function(e){
		e.preventDefault();
		
		//serialize form
		self.setQuery($("form[name="+self.formName+"]").serialize());
		
		//reset button
		if ($(this).hasClass("reset"))
		{
			$("form[name="+self.formName+"] input")
				.not(':button, :submit, :reset, :hidden').each(function(){
					$(this).val($(this).attr("default")).removeAttr('checked').removeAttr('selected');
				});
			
			if (confirm('Form has cleared. Reset locations as well?'))
				var locations = $("form[name="+self.formName+"] input.locations").val('');
			return;
		}
		
		self.activateLoadingIcon();
		
		if (self.hasScrollTops())
			$("form[name="+self.formName+"]").parent().append("<input type='text' class='hidden' name='scrolltops' value='"+self.selectScrollTops.join(",")+"' />");

		//ajax search
		if (self.ajax)
		{
			self.setQuery($("form[name="+self.formName+"]").serialize());
			self.ajaxSearch();
		}
		else {//regular form submission
			var $loc = $("input[name=loc]");
			if ($loc.val()!="" && self.selectedLocations[1].length>0)
				$loc.val("");
			$("form[name="+self.formName+"]").submit();
		}
	});
	//set up form inputs
	$("#"+this.divId+" input, select").each(function(){
		if ($(this).attr("default")!="")
		{
			$(this).bind("focus", function(){
				if ($(this).val()==$(this).attr("default"))
					$(this).val("");
			});
			$(this).bind("blur", function(){
				if ($(this).val()=="")
					$(this).val($(this).attr("default"));
			});		
		}
	});
	
	//set up pagination links
	this.pagination();
	
	//set up progress wheel
	this.setupLoadingIcon();
};

/**
 *	Set up pagination links
 */
Search.prototype.pagination = function()
{
	var self = this;
	$("a.paginationLink").bind('click',function(e){
		e.preventDefault();
		$("#"+self.divId+" input, select").each(function(){
			if ($(this).val()==$(this).attr("default"))
				$(this).val("");
		});		
		self.setQuery($("form[name="+self.formName+"]").find("input[name=page]").val($(this).attr("page")).end().serialize());
		self.ajaxSearch();
	});		
}

/**
 *	Sort map search listings
 */
Search.prototype.sort = function()
{
	var self = this;
	$("select.sortSelect").bind('onchange',function(e){
		e.preventDefault();
	});	
}

/**
 *	Set the search query
 *	@param query String Currently this is a string via jQuery serialize() method
 */
Search.prototype.setQuery = function(query)
{
	this.clearDefaults();
	
	//split query string into array
	if (typeof query != "string")
		query = $("form[name="+this.formName+"]").serialize();

	this.queryStr = query;
	this.query = null;
	this.query = new Array();
	//console.log(this.queryStr);
	this.query["view"] = this.view;
	var fields = query.split("&");
	for (var i=0; i<fields.length; i++)
	{
		var field = fields[i].split("=");
		this.query[field[0]] = field[1];
	}
}

/**
 *	Check form inputs for default values; clear them if set
 */
Search.prototype.clearDefaults = function()
{
	$("#"+this.divId+" input, select").each(function(){
		if ($(this).val()==$(this).attr("default"))
			$(this).val("");
	});	
}

/**
 *	Return the current search query
 *	@return queryStr String The query object with exploded attributes
 */
Search.prototype.getQuery = function()
{
	if (this.queryStr == null)
	{
		for (var key in this.query)
			if (typeof this.query[key] == "string")
				this.queryStr += "&"+key+"="+this.query[key];
	}
	return this.queryStr;
}

/**
 *	Fill the form inputs with values from recent search
 *	@param data json Jsoned data
 */
Search.prototype.populateRecentParams = function(data)
{
	for (var key in data)
	{
		$("form[name="+this.formName+"] input[name="+key+"]").val(data[key]);
	}
};

/**
 *	jQueryUI Tabs
 */
Search.prototype.setupSearchTabs = function()
{
	$("#"+this.divId).tabs();
};

/**
 *	Float the search form
 */
Search.prototype.floatSearchForm = function()
{
	//floating search box -- http://jqueryfordesigners.com/fixed-floating-elements/
	var msie6 = $.browser == 'msie' && $.browser.version < 7;
	if (!msie6)
	{
		var top = $("#"+this.divId).offset().top - parseFloat($("#"+this.divId).css('margin-top').replace(/auto/, 0));
		var self = this;
		$(window).scroll(function (event) {
			// what the y position of the scroll is
			var y = $(this).scrollTop();

			// whether that's below the form
			if (y >= top) {
				// if so, ad the fixed class
				$("#"+self.divId).addClass('fixed');
			} else {
				// otherwise remove it
				$("#"+self.divId).removeClass('fixed');
			}
		});
	}  		
};

/**
 *	Perform OC Map search
 */
Search.prototype.defaultSearch = function()
{
	if (this.ajax)
		this.ajaxSearch();
	else
		$("form[name="+this.formName+"]").submit();
};

/**
 *	Ajax search
 */
Search.prototype.ajaxSearch = function()
{
	d3mls_main.loadProgressWheel(this.divId);
	var self = this;
	
	$.get("/app/modules/d3mls/xml/getListings.php",this.getQuery(),function(data){
		$("#"+self.ajaxDivId).html(data);
		
		if (typeof mapListings != "undefined" && mapListings.length > 0)
		{
			d3mls_maps.setListings(mapListings);
			var dropTime = d3mls_maps.inputMarkers('function', 'd3mls_search.showMapDetails', 'marker.system_id');
			var listingsPagination = $("#listingsPagination").html();
			if (listingsPagination!="")
				$(".pagination:not(#listingsPagination)").html(listingsPagination);
			self.pagination();
			setTimeout(function(){
				$("#"+self.ajaxDivId+"Link").show();
				$("#"+self.ajaxDivId+"Div").show();
				$(".loadingBlanket, .loadingIcon").hide();//form progress animation
				d3mls_main.hideProgressWheel(self.divId);//map progress animation
			},dropTime);			
		}
	});	
};

/**
 *	Populate suggest box
 */
Search.prototype.getSuggest = function(input)
{
	var $input = $(input);
	if (( $input.val().length > 2 && parseInt($input.val()) ) || $input.val().length > 5){
		$.post('/app/modules/d3mls/ninja_code/search_simple.php', {'loc' : $input.val()},
			function(data){
				if (data.length > 1)
				{
					$input.parent().next().html(data).css({"width":$input.width()}).show();
				}
				else
					$input.parent().next().hide();
			}
		);
	}
};

/**
 *	Input suggestion
 */
Search.prototype.locationSuggestFill = function(value, suggestResult)
{
	$(suggestResult).parent().prev().find("input").val(value);
	$(suggestResult).parent().hide();
};

/**
 *	Append blanket and loading icon to the search form
 */
Search.prototype.setupLoadingIcon = function()
{
	this.$loadingBlanket = $("<div class='loadingBlanket'></div>").prependTo("#"+((this.progressTarget)?this.progressTarget:this.divId));
	this.$loadingIcon = $("<img class='loadingIcon' src='"+this.loadingIcon+"' />").prependTo("#"+((this.progressTarget)?this.progressTarget:this.divId));
};

/**
 *	Activate loading icon
 */
Search.prototype.activateLoadingIcon = function()
{
	this.$loadingBlanket.css({
			height: $("#"+this.divId).height()
		}).show();
	this.$loadingIcon.css({
			"top"		: ($("#"+this.divId).height() / 2),
			"left"		: ($("#"+this.divId).width() / 2)
		}).show();
};

/**
 *	Set up checkboxes to respond to location selects
 */
Search.prototype.setupLocationsSelectInputs = function()
{
	var self = this;
	$(".location input[type=checkbox]").each(
		function()
		{
			$(this).bind("click",function(event){
				self.selectInputs($(this),parseInt($(this).attr("index")),event);
			});
		}
	);
};

/**
 *	Get a new set of locations select boxes for the container (#locationsSelectsContainer)
 *	@param $input jQuery The clicked input
 *	@param index Integer The index of the locations select box
 *	@param $event jQuery The click event
 */
Search.prototype.selectInputs = function($input, index, $event)
{
	this._dim($(".locationsSelects:eq("+(index)+")"), true, index);
	this.selectScrollTops[index] = $input.parents(".locationsSelects").scrollTop();
	var locations = $input.val().split("|");
	if ($input.is(":checked") && $.inArray(locations[index],this.selectedLocations[index])<0)
		this.selectedLocations[index].push(locations[index]);
	else
		this.selectedLocations[index] = this._removeElements([locations[index]], this.selectedLocations[index]);

	if (index < 4)//sub_division inputs don't have children
	{
		var self = this;
		$.post("/app/modules/d3mls/xml/getLocations.php",
			{
				'locations' : this.selectedLocations,
				'index' : index,
				'view'	: this.view
			},
			function(data, status)
			{
				$("#locationsSelectsContainer").replaceWith(data);
				$(".locationsSelects").each(function(i){
					var scrollTopValue = self.selectScrollTops[i+1];
					$(this).scrollTop(scrollTopValue);
				});
			}
		);
	}
};

/**
 * Update locations select boxes scroll tops from posted array
 * @param scrolltopsAr Array
 */
Search.prototype.updateScrolltops = function(scrolltopsAr)
{
	this.selectScrollTops = scrolltopsAr;
	var self = this;
	$(".locationsSelects").each(function(i){
		var scrollTopValue = self.selectScrollTops[i+1];
		$(this).scrollTop(scrollTopValue);
	});
};

Search.prototype.hasScrollTops = function()
{
	if (this.selectScrollTops[0]>0 || this.selectScrollTops[1]>0 || this.selectScrollTops[2]>0 || this.selectScrollTops[3]>0 || this.selectScrollTops[4]>0)
		return true;
	return false;
};

/**
 * Dim/undim a div's content
 * @param $div jQuery Div to dim
 * @param dim Boolean True to dim, false to undim
 * @param index Integer Empty out next in array of selectedLocations
 */
Search.prototype._dim = function($div, dim, index)
{
	$div.css({
		"color" :"white",
		"-ms-filter" : "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)",
		"filter" : "alpha(opacity="+((dim)?40:100)+")",
		"-moz-opacity" : ((dim)?.40:1),
		"opacity" : ((dim)?.40:1)
		});
	
	this.selectedLocations[index + 1].length = 0;
};

/**
 *	Remove an array of elements from an array
 *	@param theseElements Array of strings to remove
 *	@param fromThisArray Array to remove from
 *	@return	fromThisArray
 */
Search.prototype._removeElements = function(theseElements, fromThisArray)
{
	$.unique(theseElements);
	$.unique(fromThisArray);

	for (var i=0; i<theseElements.length;i++)
		fromThisArray = $.grep(fromThisArray, function(value) {
			return value != theseElements[i];
		});
	return fromThisArray;
};

/**
 *	Group all locations under location parent (i.e. parent county > child city) and collapse the group
 *	@param divId String The id of the node containing location parent/child group
 */
Search.prototype.locationsAccordion = function(divId)
{
	//set each group to open and collapse
	$('#'+divId+' .locationsSelectSection .locationsHeader').click(function() {
		var $locationsHeaderIcon = $(this).find("div.locationsHeaderIcon");
		if ($locationsHeaderIcon.hasClass('locationsHeaderIconClicked'))
			$locationsHeaderIcon.removeClass("locationsHeaderIconClicked");
		else
			$locationsHeaderIcon.addClass("locationsHeaderIconClicked");
		$(this).next().toggle('slow');
	}).next().hide();
	//if location select contains only one group (contains title div and div of inputs), open that group
	if ($('#'+divId+' > .locationsSelectSection').children().size()<4)
	{
		$('#'+divId).find(">:first-child .locationsHeader .locationsHeaderIcon")
			.addClass("locationsHeaderIconClicked").end()
			.find(".locationsContent").show();
	}
	else
	{	//search each group for checked inputs and open if any found
		$('#'+divId+' .locationsSelectSection .locationsContent input:checked').each(
			function(){
				$(this).parent().parent().parent().prev().find(".locationsHeaderIcon").addClass("locationsHeaderIconClicked").end().next().show();
			}
		);
	}
};

Search.prototype.locationsAccordions = function(divArray)
{
	for (var i=0; i<divArray.length; i++)
		this.locationsAccordion(divArray[i]);
};

/**
 *	Make an accordion. Assumes div.accordionPanel and then the div to collapse/show
 */
Search.prototype.accordion = function(divId)
{
	var $panels = $('#'+divId+' .accordionPanel');

	$panels.click(function() {
		$(this).next().toggle('slow');
	}).next().hide();

	if ($panels.length == 1)
		$panels.next().show();
};

/**
 *	Property Details for OC Home Deals Map Search
 */
Search.prototype.showMapDetails = function(marker, system_id)
{
	var self = this;
	google.maps.event.addListener(marker, 'click', function() {
		
		$.get("/app/modules/d3mls/xml/getMapDetails.php",self.getQuery()+"&system_id="+system_id,function(data){
			
			d3mls_maps.infowindow.close();
			d3mls_maps.infowindow.setContent(data);
			d3mls_maps.infowindow.setPosition(marker.getPosition());				
			d3mls_maps.infowindow.open(d3mls_maps.map,marker);			
		});
	});			
	
};
