(function ($) {
    $.widget("ui.QuickSearch", {
        // default options
        options: {
        	MlsGroupID: -1,
            LocationLabel: "Location:",
            HeaderLabel: "Quick Search",
            LocationWatermark: "Area, City, ZIP, or Address",
            PriceRangeLabel: "Price:",
            BedsLabel: "Beds:",
            BathsLabel: "Baths:",
            ButtonLabel: "Search",
            CirrusUrl: "",
            Orientation: "Vertical",
            DefaultLocation: "",
            Hyperlink: ""
        },
        _create: function () {
            if (this.options.CirrusUrl == "") {
                $(this.element).text("Cirrus URL Must Be Specified!").css("color", "red");
            }
            else if (this.options.MlsGroupID == -1) {
            	$(this.element).text("MLS Group ID Must Be Specified!").css("color", "red");
            }
            else {
                $(this.element).hide();
                $(this.element).html('<div class="qsHeaderContainer"></div>' +
                '<div class="qsLocationLabelContainer">' +
	    	        '<label class="qsLocationLabel" for="txtLocation"></label>' +
	    	    '</div>' +
	    	    '<div class="qsLocationTxtContainer" >' +
	    	        '<input class="qsLocationTxt" type="text" />' +
	    	    '</div>' +
	    	    '<div class="qsPriceRangeContainer" >' +
	    	        '<label class="qsPriceRangeLabel" for="txtMinPrice"></label>' +
	    	        '<input class="qsMinPrice" type="text" maxlength="12" />' +
	    	        '&nbsp;to&nbsp;' +
	    	        '<input class="qsMaxPrice" type="text" maxlength="12" />' +
	    	    '</div>' +
	    	    '<div class="qsBedBathContainer" >' +
	    	        '<label class="qsBedsLabel" for="ddlBeds"></label>' +
	    	        '<select class="qsBedsList">' +
	    	            '<option value="-1">Any</option>' +
	    	            '<option value="1">1+</option>' +
	    	            '<option value="2">2+</option>' +
	    	            '<option value="3">3+</option>' +
	    	            '<option value="4">4+</option>' +
	    	            '<option value="5">5+</option>' +
	    	        '</select>' +
	    	        '<label class="qsBathsLabel" for="ddlBaths"></label>' +
	    	        '<select class="qsBathsList">' +
	    	            '<option value="-1">Any</option>' +
	    	            '<option value="1">1+</option>' +
	    	            '<option value="2">2+</option>' +
	    	            '<option value="3">3+</option>' +
	    	            '<option value="4">4+</option>' +
	    	            '<option value="5">5+</option>' +
	    	        '</select>' +
	    	    '</div>' +
	    	    '<div class="qsErrorButtonContainer">' +
	    	        '<label class="qsErrorLabel"></label>' +
	    	        '<button class="qsButton" ></button>' +
	            '</div>' +
	            '<div class="qsHyperlinkContainer">' +
	            '</div>' +
	            '<input id="hdnPolygonID" type="hidden" />');
                this._onLoad();
                $(this.element).fadeIn();
            }
        },
        _onLoad: function () {
            var self = this;            
            //if no default location given, use watermark
            if (this.options.DefaultLocation == "")
				$(this.element).find(".qsLocationTxt").val(this.options.LocationWatermark)
					.addClass("qsWatermarked")
					.focus(function () { self._LocationFocus(self, this); })
					.blur(function () { self._LocationBlur(self, this); });
			//otherwise ignore watermark and use default location
			else
				$(this.element).find(".qsLocationTxt").val(this.options.DefaultLocation);
				
            $(this.element).find(".qsLocationLabel").text(this.options.LocationLabel);
            $(this.element).find(".qsPriceRangeLabel").text(this.options.PriceRangeLabel);
            $(this.element).find(".qsBedsLabel").text(this.options.BedsLabel);
            $(this.element).find(".qsBathsLabel").text(this.options.BathsLabel);
            $(this.element).find(".qsButton").text(this.options.ButtonLabel);
            $(this.element).find(".qsButton").click($.proxy(this._search, this));
            $(this.element).addClass("qsQuickSearchContainer");

            //We only want to provide a style sheet link if they are not using a Custom Layout
            if (this.options.Orientation.toLowerCase() != "custom") {
                (this.options.Orientation.toLowerCase() == "vertical") ?
                $("head").append("<link rel='Stylesheet' type='text/css' id='qsCss' href='http://tools.1parkplace.com/Widgets/CirrusQuickSearch/CirrusQuickSearchVertical.css' />") :
                $("head").append("<link rel='Stylesheet' type='text/css' id='qsCss' href='http://tools.1parkplace.com/Widgets/CirrusQuickSearch/CirrusQuickSearchHorizontal.css' />");
            }

            //Display the header if specified.
            (this.options.HeaderLabel != "") ?
            $(this.element).find(".qsHeaderContainer").text(this.options.HeaderLabel)
            : $(this.element).find(".qsHeaderContainer").hide();
            
            //Display hyperlink if provided (Thank you Pru Centennial!)
            (this.options.Hyperlink != "") ?
            $(this.element).find(".qsHyperlinkContainer").html(this.options.Hyperlink)
            : $(this.element).find(".qsHyperlinkContainer").hide();

            //Hook up the Enter key to the button.
            $(this.element).keydown(function (event) {
                if (event.keyCode == 13)
                    $(self.element).find(".qsButton").click();
            });
            
            //dsa 11.9.2010: gnarly autocomplete goodness!
            var MlsGroupID = this.options.MlsGroupID;
            $(".qsLocationTxt").autocomplete({
            	source: function (request, response) {
            		$.ajax({
            			url: "http://realestatelistings.1parkplace.com/UserControls/AreaWebService.asmx/GetAreaCompletionListAll",
            			data: { mlsGroupID : MlsGroupID, query : JSON.stringify(request.term) },
            			dataType: "jsonp",	//jsonp is basically a workaround to allow cross-domain JSON
				        type: "GET",		//jsonp requires GET requests instead of POST
				        contentType: "application/json; charset=utf-8",
				        dataFilter: function (msg) { return msg; },
				        success: function (msg) {
							response($.map(msg.d, function (item) {
								return {
									label: item.Name,
									id: item.PolygonID,
									subLabel: item.PolygonType
								}
							}));
				    	}
					});
				},
				select: function (event, ui) {
					$(".qsLocationTxt").val(ui.item.label);
					$("#hdnPolygonID").val(ui.item.id + "|" + ui.item.label);	//set the selected polygon ID in the hidden field
				},
				change: function (event, ui) {
					if (!ui.item) {
						$("#hdnPolygonID").val("");
					}
				},
				minLength: 3
            })
            .data( "autocomplete" )._renderItem = function( ul, item ) {
						return $( "<li></li>" )
							.data( "item.autocomplete", item )
							.append( '<a>' + item.label + '<span class="ui-autocomplete-sublabel">' + item.subLabel + "</span></a>" )
							.appendTo( ul );
					};

            MaskPriceRangeValues();
        },
        _search: function () {
            //clear any error messages
            this._ClearError();

            var loc = $(this.element).find(".qsLocationTxt");
            var qsLocation = $.trim(loc.val());

            //Location required
            if (!this.options.IsWatermarkValidLocation && qsLocation == $.trim(this.options.LocationWatermark)) {
                this._SetError("Specify a location!");
                loc.parent().addClass("qsInputError");
                return;
            }

            var redirectUrl = this.options.CirrusUrl;

            //append appropriate character to query string
            (redirectUrl.indexOf("?") == -1) ? redirectUrl += "?" : redirectUrl += "&";
            
            //add the quick search service ID so Cirrus can verify
            redirectUrl += "cirrusServiceID=222&";
            
			var minPrice = $(this.element).find(".qsMinPrice");
            var maxPrice = $(this.element).find(".qsMaxPrice");
            var qsMinPrice = $.trim(minPrice.val().cleanNumber());
            var qsMaxPrice = $.trim(maxPrice.val().cleanNumber());
            var qsBeds = $(this.element).find(".qsBedsList").val();
            var qsBaths = $(this.element).find(".qsBathsList").val();
            var qsPolygonKey = $(this.element).find("#hdnPolygonID").val();
            var qsPolygonID;
            var qsPolygonName;
            
            //generate querystring
            if (qsPolygonKey != "") {
            	qsPolygonID = qsPolygonKey.split("|")[0];
            	qsPolygonName = qsPolygonKey.split("|")[1];
            }
            
            //check whether a polygon was selected via autocomplete
            if (qsPolygonID && (qsPolygonName == qsLocation)) {
            		redirectUrl += "cirrusCriteria=boundaries-" + qsPolygonID;
            }	
            else {
            	redirectUrl += "cirrusCriteria=loc-" + qsLocation.replace(/\W/g, '+');
            }	

            if (qsMinPrice != "" && qsMaxPrice != "") {
                if (parseInt(qsMinPrice) <= parseInt(qsMaxPrice)) {
                    redirectUrl += "|minPrice-" + qsMinPrice + "|maxPrice-" + qsMaxPrice;
                }
                else {
                    minPrice.addClass("qsInputError");
                    maxPrice.addClass("qsInputError");
                    this._SetError("Invalid price range!");
                    return;
                }
            }
            else {
                if (qsMinPrice != "") {
                    redirectUrl += "|minPrice-" + qsMinPrice;
                }

                if (qsMaxPrice != "") {
                    redirectUrl += "|maxPrice-" + qsMaxPrice;
                }
            }

            if (qsBeds != "-1") {
                redirectUrl += "|minBed-" + qsBeds;
            }

            if (qsBaths != "-1") {
                redirectUrl += "|minBath-" + qsBaths;
            }

            window.location = redirectUrl;
        },

        _LocationFocus: function (widget, textBox) {
            if (widget.options.LocationWatermark == $(textBox).val()) {
                $(textBox).val("");
                $(textBox).toggleClass("qsWatermarked");
                $(textBox).css("border", "");
            }
        },

        _LocationBlur: function (widget, textBox) {
            if ($(textBox).val() == "") {
                $(textBox).val(widget.options.LocationWatermark);
                $(textBox).toggleClass("qsWatermarked");
            }
        },

        _SetError: function (message) {
            $(this.element).find(".qsErrorLabel").text(message);
        },

        _ClearError: function () {
            $(this.element).find(".qsLocationTxtContainer").removeClass("qsInputError");
            $(this.element).find("input").removeClass("qsInputError");
            $(this.element).find(".qsErrorLabel").text("");
        }
    });

    //Helper Functions
    String.prototype.insertAt = function (loc, strChunk) {
        return (this.valueOf().substr(0, loc)) + strChunk + (this.valueOf().substr(loc))
    }

    String.prototype.toCurrency = function (currencySymbol, thousandsSeparator) {
        var n, startAt, intLen;
        n = this.valueOf();
        if (currencySymbol == null) currencySymbol = "$";
        if (thousandsSeparator == null) thousandsSeparator = ",";
        intLen = this.length;
        if ((startAt = intLen % 3) == 0) startAt = 3;
        for (var i = 0, len = Math.ceil(intLen / 3) - 1; i < len; i++)
            n = n.insertAt(i * 4 + startAt, thousandsSeparator);
        return currencySymbol + n;
    }

    String.prototype.cleanNumber = function () {
        var str = this.valueOf();
        var strlen = str.length;

        return str.replace(/[^0-9]+/g, "");
    }

    String.prototype.trim = function (chars) {
        var str = this.valueOf();

        //Trim chars from the left (beginning)
        var trim = str.replace(new RegExp("^[" + chars + "]+", "g"), "");

        //Trim chars from the right (end)
        trim = trim.replace(new RegExp("[" + chars + "]+$", "g", ""));

        return trim;
    }

    function CheckNumericKeys(evt) {
        if (evt.which >= 48 && evt.which <= 57)
            return true;
        else
            return false;
    }

    //Price Range Mask
    function MaskPriceRangeValues() {
        $(".qsPriceRangeContainer input").bind({
            keypress: function (e) {
                var key = e.which || e.keyCode;
                //If it is the backspace or tab key, always want to return true
                if (key == 8 || key == 9 || key == 13)
                    return true;

                var inputText = $(this).val();
                if (!CheckNumericKeys(e))
                    return false;
            },

            focus: function (e) {
                var inputText = $(this).val();
                $(this).val(inputText.cleanNumber());
            },

            blur: function (e) {
                var inputText = $(this).val();
                if (inputText.length > 0)
                    $(this).val(inputText.toCurrency('$', ','));
            }
        });
    }
})(jQuery);

