﻿(function ($) {


    var cancelClickFlag = false;

    function getParameterByName(name) {
        name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
        var regexS = "[\\?&]" + name + "=([^&#]*)";
        var regex = new RegExp(regexS);
        var results = regex.exec(window.location.href);
        if (results == null)
            return "";
        else
            return results[1];
    }

    // checks for london postcode out codes ie: SW1
    function isValidLondonOutcode(p) {
        var londonOutcodeRegEx = /^(EC|WC|N|E|SE|SW|W|NW)\d{1,2}\b/i;
        return londonOutcodeRegEx.test(p);
    }

    /* tests to see if string is in correct UK style postcode: AL1 1AB, BM1 5YZ etc. */
    function isValidPostcode(p) {
        var postcodeRegEx = /[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}/i;
        return postcodeRegEx.test(p);
    }

    /*	formats a VALID postcode nicely: AB120XY -> AB1 0XY */
    function formatPostcode(p) {
        if (isValidPostcode(p)) {
            var postcodeRegEx = /(^[A-Z]{1,2}[0-9]{1,2})([0-9][A-Z]{2}$)/i;
            return p.replace(postcodeRegEx, "$1 $2");
        } else {
            return p;
        }
    }

    $.fn.findNearest = function (parameters) {
        var defaults = {
            pathToJson: "/handlers/nurseries-json.ashx",
            searchLimit: 15,
            searchBoxId: "TextBox1",
            searchButtonId: "butt",
            formId: "aspnetForm",
            resultsMessage: "<h2>Search results</h2><p>You searched for nurseries closest to <strong>{search-phrase}</strong>. We found the following nurseries...</p>",
            resultsContainerId: "nursery-list",
            errorContainerId: "nursery-list-errors",
            templateId: "locationsTemplate",
            cancelClickFlag: false
        };

        $.extend(defaults, parameters);
        var locations = {};
        var requestedPoint = null;

        // capture any static HTML from results container
        var originalContent = $("#" + defaults.resultsContainerId).html();

        // load JSON from disk
        $.getJSON(defaults.pathToJson, function (data) {
            locations = data;

            var cancelClick = function () {
                findNearest();
                return false;
            };

            var findNearest = function () {
                var searchTerms = $("#" + defaults.searchBoxId).val();

                /* KIDSUNLIMITED-4 Perform substitutions for certain values */
                if (searchTerms.toLowerCase() == "tytherington") { searchTerms = "Tytherington, Macclesfield"; }
                if (searchTerms.toLowerCase() == "bickley") { searchTerms = "Bickley, Bromley"; }
                $("#" + defaults.searchBoxId).val(searchTerms);

                if (searchTerms != "") {

                    if (isValidPostcode(searchTerms))
                        searchTerms = formatPostcode(searchTerms) + " postcode";
                    else if (isValidLondonOutcode(searchTerms))
                        searchTerms = searchTerms + ", London";
                    else
                        searchTerms = searchTerms + ", UK";

                    // attempt to geocode the supplied search term
                    var geocoder = new google.maps.ClientGeocoder();
                    geocoder.getLatLng(searchTerms, function (point) {
                        if (!point) {
                            $("#" + defaults.resultsContainerId).html(originalContent);
                            $("#" + defaults.errorContainerId).show();
                            $().scrollTo("#" + defaults.errorContainerId, 1000, { axis: 'y' });
                        } else {
                            requestedPoint = point;

                            // reset (hide) error container
                            $("#" + defaults.errorContainerId).hide();

                            // find out how far away each location is from the requestedPoint
                            $.each(locations, function (i, item) {

                                var thisLatLong = new google.maps.LatLng(item.Latitude, item.Longitude);
                                item.DistanceInMeters = requestedPoint.distanceFrom(thisLatLong);
                                item.DistanceInMiles = Math.round(0.621371192 * (item.DistanceInMeters / 1000) * 100) / 100;

                            });

                            // order the collection of locations with nearest first
                            locations.sort(function (a, b) {
                                return a.DistanceInMeters - b.DistanceInMeters;
                            });

                            var limit = locations.length;
                            if (defaults.searchLimit < limit)
                                limit = defaults.searchLimit;

                            // limit the number of results
                            var templateData = new Object();
                            templateData.limit = limit;
                            templateData.locations = {};
                            for (i = 0; i < limit; i++)
                                templateData.locations[i] = locations[i];

                            //attach and process the template to display the results
                            $("#" + defaults.resultsContainerId).setTemplate($("#" + defaults.templateId).html(), new Array(), { filter_data: false });
                            $("#" + defaults.resultsContainerId).setParam("resultsMessage", defaults.resultsMessage.replace('{search-phrase}', $("#" + defaults.searchBoxId).val()));
                            $('#' + defaults.resultsContainerId).setParam("searchPhrase", escape($("#" + defaults.searchBoxId).val()));
                            $("#" + defaults.resultsContainerId).processTemplate(templateData);
                            $().scrollTo("#" + defaults.resultsContainerId, 1000, { axis: 'y' });

                        }

                    });


                }

            };

            // check for a querystring value - if found, automatically do a search
            if (getParameterByName("searchTerm") != "") {

                var val = unescape(getParameterByName("searchTerm")).replace(/\+/g, ' ');

                $("#" + defaults.searchBoxId).val(val);
                findNearest();
            }

            // setup click event for search button
            $("#" + defaults.searchButtonId).click(findNearest);
            $("#" + defaults.formId).submit(cancelClick);

            $("#" + defaults.searchBoxId).keydown(function (e) {

                if (e.keyCode == 13) {
                    defaults.cancelClickFlag = true;
                    findNearest();
                }
            });
        });

    };

})(jQuery);
