﻿// Copyright 2010 Microsoft Corporation
// Scripts to support the AddressSearchControl - requires jQuery.js and UIExtensions.js

/// <summary>Enumerate the LocationAddressEntity</summary>
var LocationType = {
    Unknown: "Unknown",
    StreetAddress: "Address",
    State: "AdminDivision1",
    City: "PopulatedPlace",
    Zip: "Postcode1"
};

/// <summary>Enumerate the LocationMatchConfidence</summary>
var LocationMatchConfidence = {
    None: "None",
    Low: "Low",
    Medium: "Medium",
    High: "High"
};

/// <summary>Address Format</summary>
var AddressFormat = "{0}, {1}, {2} {3}";

/// <summary>Declare the addressSearchControl object</summary>
var addressSearchControl = {};

/// <summary>Shows the address search when the control to show is clicked</summary>
addressSearchControl.Show = function() {
    var addressBar = $(addressSearchControl.vars.ui.mainSelector);
    if (addressBar.is(":hidden")) {
        addressBar.slideDown("slow"); 
    }
};

/// <summary>Hides the address search when the control to hide is clicked</summary>
addressSearchControl.Hide = function() {
    var addressBar = $(addressSearchControl.vars.ui.mainSelector);
    if (addressBar.is(":visible")) {
        addressBar.slideUp("slow");
    }
};

addressSearchControl.RaiseEvent = function (resultData) {
    var addressBar = $(addressSearchControl.vars.ui.mainSelector);
    addressBar.trigger("addressSearchControl-SearchCompleted", [resultData]);
};

/// <summary>Handles the web service call completed</summary>
/// <param name="resultData">The return data from the web service call (JSON)</param>
addressSearchControl.SearchCompleted = function(resultData) {
    addressSearchControl.HideWaiting();
    addressSearchControl.RaiseEvent(resultData);
    if (!resultData.Success) {
        addressSearchControl.ShowError("[Web service returned an error] " + resultData.ErrorMessage);
    }
    else {
        if (resultData.Value.length <= 0) {
            addressSearchControl.ShowError(addressSearchControl.vars.validation.invalidAddress);
            return;
        }

        if (!addressSearchControl.vars.result.suppressRedirection) {
            var url = "";
            switch (resultData.Value[0].AddressEntity) {
                case LocationType.StreetAddress:
                    url = String.format(addressSearchControl.vars.result.pagePerHomeUrl, resultData.Value[0].Location.SubRegion.ShortCode, escape(addressSearchControl.SanitizeCityName(resultData.Value[0].Location.City)),
                    resultData.Value[0].Location.PostalCode, escape(resultData.Value[0].Location.Address));
                    break;
                case LocationType.City:
                    url = String.format(addressSearchControl.vars.result.pagePerCityUrl,
                    resultData.Value[0].Location.SubRegion.ShortCode, escape(addressSearchControl.SanitizeCityName(resultData.Value[0].Location.City)));
                    break;
                case LocationType.Zip:
                    url = String.format(addressSearchControl.vars.result.pagePerZipUrl,
                    resultData.Value[0].Location.PostalCode.substring(0, 5));
                    break;
                default:
                    addressSearchControl.ShowError(addressSearchControl.vars.validation.invalidAddress);
                    break;
            }
            if (url != "") {
                if ((resultData.Value[0].MatchConfidence == LocationMatchConfidence.Medium || resultData.Value[0].MatchConfidence == LocationMatchConfidence.Low) 
                    && (resultData.Value[0].AddressEntity == LocationType.Zip || resultData.Value[0].AddressEntity == LocationType.City)) {
                    url = url + "?confidence=" + resultData.Value[0].MatchConfidence;
                }
                window.location = url;
            }
        }
    }
};

/// <summary>Sanitize a city name so that it still works with the url rewriter.</summary>
/// <param name="cityName">The city name to sanitize.</param>
/// <returns>The city name without any commas or dots</returns>
addressSearchControl.SanitizeCityName = function(cityName) {
    return cityName.replace(/\.|,/g, "");
}

/// <summary>Handles the web service call failure</summary>
/// <param name="requestObj">unused</param>
/// <param name="status">The error status of the request</param>
/// <param name="error">The error message thrown</param>
addressSearchControl.SearchFailed = function (requestObj, status, error) {
    addressSearchControl.HideWaiting();
    addressSearchControl.ShowError("[" + status + "] " + error);
};

/// <summary>Shows the error inlay</summary>
/// <param name="errorMsg">The error message to display</param>
addressSearchControl.ShowError = function(errorMsg) {
    var errorBar = $(addressSearchControl.vars.ui.errorSectionSelector);
    if (addressSearchControl.vars.ui.isErrorCallout) {
        if (errorBar.is(":hidden")) {
            errorBar.fadeIn("slow");
        }
    }
    else {
        errorBar.text(errorMsg);
        if (errorBar.is(":hidden")) {
            errorBar.slideDown("fast");
        }
    }
}

addressSearchControl.ShowWaiting = function () {
    if (addressSearchControl.vars.ui.showWaiting) {
        var waitingBar = $(addressSearchControl.vars.ui.waitingSectionSelector);
        if (waitingBar.is(":hidden")) {
            waitingBar.fadeIn("slow");
        }
    }
}

addressSearchControl.HideWaiting = function () {
    if (addressSearchControl.vars.ui.showWaiting) {
        var waitingBar = $(addressSearchControl.vars.ui.waitingSectionSelector);
        if (waitingBar.is(":visible")) {
            waitingBar.fadeOut("slow");
        }
    }
}

/// <summary>Hide the error inlay</summary>
addressSearchControl.HideError = function() {
    var errorBar = $(addressSearchControl.vars.ui.errorSectionSelector);
    if (addressSearchControl.vars.ui.isErrorCallout) {
        if (errorBar.is(":visible")) {
            errorBar.fadeOut("slow");
        }
    }
    else {
        errorBar.text(errorMsg);
        if (errorBar.is(":visible")) {
            errorBar.slideUp("fast");
        }
    }
}

/// <summary>
/// Handles the search event which is triggered by the enter key press on the search text box
/// or by clicking on the "go" button.
/// </summary>
addressSearchControl.Search = function () {
    var address = $(addressSearchControl.vars.ui.addressSearchTextBox).val();
    // check if the value of the textbox is the watermark value
    if (address == addressSearchControl.vars.ui.watermark) {
        address = "";
    }
    // check address text box is not empty
    if (address != "") {
        addressSearchControl.ShowWaiting();
        // call the web service that will verify the address if it is valid
        $.ajax({
            type: "POST",
            url: addressSearchControl.vars.service.url + addressSearchControl.vars.service.getHomeInfo,
            data: { address: address, addresstype: addressSearchControl.vars.service.addresstype, postprocess: addressSearchControl.vars.service.postprocess, processownername: addressSearchControl.vars.service.processownername, fallbacktozip: addressSearchControl.vars.service.fallbacktozip },
            dataType: "json",
            error: addressSearchControl.SearchFailed,
            success: addressSearchControl.SearchCompleted
        });
    }
    else {
        addressSearchControl.ShowError(addressSearchControl.vars.validation.invalidAddress);
    }
};

/// <summary>
/// Attaches the event handlers for the controls
/// </summary>
addressSearchControl.AttachControls = function() {
    // search trigger on click of "go" button
    $(addressSearchControl.vars.ui.searchButtonSelector).click(function() {
        addressSearchControl.Search();
    });
    // search trigger on "enter key" on the textbox
    $(addressSearchControl.vars.ui.addressSearchTextBox).keypress(function(key) {
        if (key.keyCode == keyCodes.enter) {
            addressSearchControl.Search();
            return false;
        }
        else {
            addressSearchControl.HideError();
        }
    });
    // trigger for hiding the error on copy and paste.
    $(addressSearchControl.vars.ui.addressSearchTextBox).select(function(key) {
        addressSearchControl.HideError();
    });
    // trigger for showing the search bar
    $(addressSearchControl.vars.ui.showControlSelector).click(function() {
        addressSearchControl.Show();
    });
    // trigger for hiding the search bar
    $(addressSearchControl.vars.ui.hideControlSelector).click(function() {
        addressSearchControl.Hide();
    });
    // replace menu item href with javascript:void(false) to disable triggering a redirect
    $(addressSearchControl.vars.ui.showControlSelector).filter("a").attr("href", "javascript:void(false);");
};

/// <summary>This will execute when the DOM is ready</summary>
$(document).ready(function() {
    // Attach this control to "MainContentMargin" div tag
    $(addressSearchControl.vars.ui.mainSelector).prependTo(addressSearchControl.vars.ui.containerSelector);

    // register the event handlers for the controls
    addressSearchControl.AttachControls();

    // initially hide the address bar depending on the property passed on the control
    if (addressSearchControl.vars.ui.isHidden) {
        $(addressSearchControl.vars.ui.mainSelector).hide();
    }
    else {
        $(addressSearchControl.vars.ui.mainSelector).show();
    }

    // initially hide the error/validation message bar
    $(addressSearchControl.vars.ui.errorSectionSelector).hide();
    // initially hide the waiting bar
    $(addressSearchControl.vars.ui.waitingSectionSelector).hide();

    // adds watermark effect to the textbox
    var addressTextBox = $(addressSearchControl.vars.ui.addressSearchTextBox);
    if (addressTextBox.val() == addressSearchControl.vars.ui.watermark) {
        addressTextBox.watermark();
    }
});


