// ------------------------------------------
// ------ jquery.changeAddressModal -----
// ------------------------------------------
// Controls the change address modal
// ------------------------------------------

; (function ($, window, document, undefined) {

    var pluginName = "changeAddressModal";

    function changeAddressModal(options) {
        this._name = pluginName;
        this._defaults = $.fn.changeAddressModal.defaults;
        this.options = $.extend({}, this._defaults, options);

        this.init();
    };

    function reformatPostcode(value) {
        var postcodeValue = value.toUpperCase();
        var result = postcodeValue;

        postcodeValue = postcodeValue.replace(/\s/g, "");

        if (postcodeValue.length >= 5 && postcodeValue.length <= 7)
        {
            result = postcodeValue.substring(0, postcodeValue.length - 3) + " " + postcodeValue.substring(postcodeValue.length - 3);
        }

        return result;
    };

    function getCurrentLocation(plugin) {

        plugin.$loadingDiv.show();
        plugin.$errorMessageContainer.hide();
        plugin.$addressContainer.hide();
        plugin.$saveContainer.hide();

        var options = {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
        };

        function getCurrentPositionSuccess(pos) {
            var crd = pos.coords;

            this.$latitudeField.val(crd.latitude);
            this.$longitudeField.val(crd.longitude);

            plugin.$loadingDiv.hide();

            plugin.setError("Position has been captured");

            plugin.$saveContainer.show();

        };

        function getCurrentPositionError(error) {
            
            var message = "An error has occurred whilst trying to retrieve your location";

            switch (error.code) {
                case error.PERMISSION_DENIED:
                    message = "You do not have the permission for the browser to access your location";
                    break;
                case error.POSITION_UNAVAILABLE:
                    message = "Location information is currently unavailable.";
                    break;
                case error.TIMEOUT:
                    message = "The request to get your location timed out.";
                    break;
                case error.UNKNOWN_ERROR:
                    message = "An unknown error occurred whilst trying to get your location.";
                    break;
            }

            plugin.$loadingDiv.hide();

            plugin.setError(message);

        };

        navigator.geolocation.getCurrentPosition(getCurrentPositionSuccess, getCurrentPositionError, options);                
    };

    function loadAddresses(plugin, postcode) {

        plugin.$loadingDiv.show();
        plugin.$errorMessageContainer.hide();
        plugin.$addressContainer.hide();
        plugin.$saveContainer.hide();

        $.ajax
        (
            {
                contentType: "application/json; charset=utf-8",
                url: plugin.options.addressLookupUrl,
                data: { postcode: postcode, classification: "" },
                dataType: "jsonp"
            }
        )
        .done(function (data)
        {            
            if (data === null || $.isEmptyObject(data) ) {
                plugin.setError(plugin.options.noResultsMessage);
                return;
            }

            plugin.$addressSelect.html("");

            $(data).each(function (i, val) {
                $("<option />", {
                    val: val.Uprn,
                    text: val.AddressLine1
                }).appendTo(plugin.$addressSelect);
            });

            plugin.$addressContainer.show();
            plugin.$saveContainer.show();

        })
        .fail(function (jqXHR, textStatus, errorThrown)
        {            
            var msg = (errorThrown === null || errorThrown.length === 0) ? plugin.options.defaultErrorMessage : errorThrown;

            plugin.setError(msg);

        })
        .always(function ()
        {
            plugin.$loadingDiv.hide();

            plugin.$postcodeChangeButton.disabled = false;
        });
    
    };

    $.extend(changeAddressModal.prototype, {

        init: function () {
            this.buildCache();

            this.bindEvents();

            if (this.options.allowGeoLocationSelect === false || navigator.geolocation === false) {

                this.$orMessageSpan.hide();
                this.$useCurrentLocationContainer.hide();

            }

            this.$loadingDiv.hide();
            this.$errorMessageContainer.hide();
            this.$addressContainer.hide();
            this.$saveContainer.hide();
            
        },

        destroy: function () {
            this.unbindEvents();
        },

        buildCache: function () {

            this.$postcodeTextbox = $(this.options.postcodeTextboxId);
            this.$postcodeChangeButton = $(this.options.postcodeChangeButtonId);

            this.$loadingDiv = $(this.options.loadingDivId);
            this.$errorMessageContainer = $(this.options.alertContainerId);
            this.$alertBoxCloseLink = $(this.options.alertContainerId + " a.close");
            this.$errorMessage = $(this.options.alertMessageId);

            this.$orMessageSpan = $(this.options.orMessageSpanId);

            this.$useCurrentLocationContainer = $(this.options.useCurrentLocationContainerId);
            this.$useCurrentLocationButton = $(this.options.useCurrentLocationButtonId);

            this.$latitudeField = $(this.options.latitudeFieldId);
            this.$longitudeField = $(this.options.longitudeFieldId);

            this.$addressSelect = $(this.options.addressSelectId);

            this.$addressContainer = $(this.options.addressContainerId);

            this.$saveContainer = $(this.options.saveContainerId);

            this.$saveButton = $(this.options.saveContainerId + " .button");
            
        },

        bindEvents: function () {
            var plugin = this;

            plugin.$postcodeTextbox.on("keypress", function (args) {

                if (args.keyCode === 13) {
                    plugin.$postcodeChangeButton.click();
                    return false;
                }

            });

            plugin.$postcodeChangeButton.on("click", function (e) {
                e.preventDefault();

                var postcode = plugin.$postcodeTextbox.val().trim();

                if (postcode === "") {
                    return;
                }

                plugin.$postcodeChangeButton.disabled = true;

                postcode = reformatPostcode(postcode);

                loadAddresses(plugin, postcode);
            });

            plugin.$alertBoxCloseLink.on("click", function (e) {
                e.preventDefault();

                plugin.clearError();
            });

            plugin.$saveButton.on("click", function (e) {

                var addressId = plugin.$addressSelect.val();

                var lat = plugin.$latitudeField.val();
                var lng = plugin.$longitudeField.val();
                
                if ((addressId === "") && (lat === "" || lng === "") ) {
                    e.preventDefault();

                    plugin.setError(plugin.options.noAddressSelected);

                    return;
                }

            });

            plugin.$useCurrentLocationButton.on("click", function(e) {
               
                e.preventDefault();

                getCurrentLocation(plugin);

            });
        },

        unbindEvents: function () {
            var plugin = this;

            plugin.$postcodeTextbox.off("keypress");

            plugin.$postcodeChangeButton.off("click");
            plugin.$alertBoxCloseLink.off("click");
            plugin.$saveButton.off("click");

        },

        clearError: function () {

            var plugin = this;

            plugin.$errorMessageContainer.hide();
            plugin.$errorMessage.text("");
        },

        setError: function (errorMessage) {
            var plugin = this;

            plugin.$errorMessageContainer.show();
            plugin.$errorMessage.text(errorMessage);

        }
        
    });

    $.fn.changeAddressModal = function (options) {

        var self = new changeAddressModal(options);

        return this;
    };

    $.fn.changeAddressModal.defaults = {
        usingHomeAddress: true,
        allowGeoLocationSelect: false,
        postcodeTextboxId: "#postcodeChange",
        postcodeChangeButtonId: "#postcodeChangeButton",
        loadingDivId: "#loadingDiv",
        alertContainerId: "#alertContainer",
        alertMessageId: "#alertTitle",
        orMessageSpanId: "#orSpan",
        useCurrentLocationContainerId: "#useCurrentLocationContainer",
        useCurrentLocationButtonId: "#useCurrentLocationButton",
        latitudeFieldId: "#currentLat",
        longitudeFieldId: "#currentLong",
        addressContainerId: "#addressContainer",
        addressSelectId: "#address",
        saveContainerId: "#saveContainer",
        addressLookupUrl: "/llpg/lookup",
        noResultsMessage: "No results were found, please check the postcode entered",
        defaultErrorMessage: "There was a problem looking up this postcode, please try again later",
        noAddressSelected: "No address has been selected"
    };

})(jQuery, window, document);
