(function (jQuery) {
    jQuery.infiniti.mapping = {
        providers: {}
    };
    jQuery.infiniti.mapping.getMapper = function (options) {
        options = jQuery.extend(true, {
            context: "",
            provider: "multimap",
            container: "#mapContainer",
            routeContainer: "#routeContainer",
            startZoom: 80,
            marker: {
                url: "/img/mapping/map_logo.png",
                height: 47,
                width: 67
            },
            distanceUnit: "miles",
            language: "en_gb",
            country: "gb",
            routing: {
                marker: {
                    url: "/img/mapping/map_home.png",
                    height: 38,
                    width: 38 
                },
                line: {
                    thickness: 8,
                    opacity: 1,
                    color: "#ff5522"
                },
                showFrom: true,
                showTo: true
            },
            localization: {
                routing: {
                    from: "Begin From: ",
                    to: "Arrive At: ",
                    distance: "Total Distance: ",
                    duration: "Estimated Travel Time: ",
                    days: "day",
                    daysPlural: "days",
                    hours: "hour",
                    hoursPlural: "hours",
                    minutes: "minute",
                    minutesPlural: "minutes",
                    km: "kilometre",
                    kmPlural: "kilometres",
                    miles: "mile",
                    milesPlural: "miles",
                    disclaimer: "Disclaimer",
                    loading: "Loading Driving Directions...",
                    nomatcherror: "Cannot find that location.<br/>Please try again.",
                    overrides: []
                }
            }
        }, options);
        var mapper = new jQuery.infiniti.mapping.providers[options.provider];
        mapper.options = options;
        if (mapper.key && options.key) {
            mapper.key = options.key;
        }
        jQuery(options.container).get(0).mapper = mapper;
        mapper.initialize();
        return mapper;
    };
    jQuery.infiniti.mapping.loadProvider = function (options) {
        jQuery.infiniti.mapping.providers[options.provider].load(options);
    };
    jQuery.infiniti.mapping.providers = {};
    jQuery.infiniti.mapping.providers.multimap = function () {
        this.key = "OA08070819546452808";
        this.map = null;
        this.locations = [];
        this.markers = [];
        this.localize = function (module, text) {
            var replacements = this.options.localization[module].overrides;
            if (replacements.length > 0) {
                for (var rep = 0; rep < replacements.length; rep++) {
                    var reps = replacements[rep].split("||");
                    text = text.replace(new RegExp(reps[0], "g"), reps[1]);
                }
                return text;
            } else {
                return text;
            }
        };
        this.locale = function (country, language) {
            return language + "-" + country;
        };
        this.language = function (languageCode) {
            switch (languageCode.toLowerCase()) {
            case "en":
            case "en_us":
            case "en-us":
            case "eng":
            case "eng_us":
            case "eng-us":
                return "en_us";
                break;
            case "en_gb":
            case "en-gb":
            case "eng_gb":
            case "eng-gb":
                return "en_gb";
                break;
            case "da":
            case "dan":
                return "da";
                break;
            case "de":
            case "deu":
            case "ger":
                return "de";
                break;
            case "es":
            case "spa":
                return "es";
                break;
            case "fr":
            case "fre":
            case "fra":
                return "fr";
                break;
            case "it":
            case "ita":
                return "it";
                break;
            case "nl":
            case "dut":
            case "nld":
                return "nl";
                break;
            case "no":
            case "nn":
            case "nb":
            case "nno":
            case "nob":
            case "nor":
                return "no";
                break;
            case "pt":
            case "por":
                return "pt";
                break;
			case "pl":
			case "pol":
				return "pl";
				break;
            case "sv":
            case "swe":
                return "sv";
                break;
            default:
                return "en_us";
                break;
            }
            return "en_us";
        };
        this.initialize = function () {
            this.mapviewer = MMFactory.createViewer(jQuery(this.options.container).get(0));
            this.mapviewer.mapper = this;
            this.mapviewer.setOption("units", this.options.distanceUnit);
            this.geocoder = MMFactory.createGeocoder(this._geocodeHandler);
            this.geocoder.mapper = this;
            this.addMainControl();
            if ( !! this.options.startLocation.length && this.options.startLocation.length > 0) {
                for (var l = 0; l < this.options.startLocation.length; l++) {
                    var startLoc = this.addLocation(this.options.startLocation[l]);
                    this.addMarker(startLoc, this.options.startLocation[l].name, l + 1);
                }
                this.showAllLocations();
                this.currentMarker = this.markers[0];
            } else if (typeof(this.options.startLocation) == "object") {
                var startLoc = this.addLocation(this.options.startLocation);
                this.showLocation(startLoc, this.options.startZoom);
                this.currentMarker = this.addMarker(startLoc, this.options.startLocation.name);
            }
            if (typeof(this.options.initialized) == 'function') {
                this.options.initialized.apply(this);
            }
            window["jQueryinfinitimapping" + this.key] = null;
        };
        this._geocodeHandler = function () {
            if (this.error_code == "MM_GEOCODE_NO_MATCHES" || this.result_set.length === 0) {
                if (this.mapper.showRouteError && typeof(this.mapper.showRouteError) == "function") {
                    this.mapper.showRouteError();
                }
                return;
            }
            var queue = this.mapper._geocodeHandlerQueue;
            try {
                if (queue.length > 0) {
                    var func = queue.shift();
                    if (func != undefined) {
                        func.apply(this.mapper, this.result_set);
                    }
                }
            } catch (e) {}
        };
        this._geocodeHandlerQueue = [];
        this.addMarker = function (location, label, index) {
            var icon = new MMIcon((this.options.marker.url.indexOf(this.options.context) == -1 ? this.options.context : "") + this.options.marker.url);
            icon.iconSize = new MMDimensions(this.options.marker.width, this.options.marker.height);
            icon.iconAnchor = new MMPoint(Math.floor(this.options.marker.width / 4), Math.floor(this.options.marker.height / 4));
            var marker = this.mapviewer.createMarker(location, {
                'label': label,
                'icon': icon,
                'text': ( !! index ? index : null)
            });
            this.markers.push(marker);
            return this.markers[this.markers.length - 1];
        };
        this.addRouteMarker = function (location, label) {
            var icon = new MMIcon((this.options.routing.marker.url.indexOf(this.options.context) == -1 ? this.options.context : "") + this.options.routing.marker.url);
            icon.iconSize = new MMDimensions(this.options.routing.marker.width, this.options.routing.marker.height);
            icon.iconAnchor = new MMPoint(Math.floor(this.options.routing.marker.width / 2), Math.floor(this.options.routing.marker.height / 2));
            return this.mapviewer.createMarker(location, {
                'label': label,
                'icon': icon
            });
        };
        this.addLocation = function (location) {
            this.locations.push(this.location(location));
            return this.locations[this.locations.length - 1];
        };
        this._routingLine = function (line) {
            return {
                thickness: (line.thickness / 5),
                color: line.color,
                opacity: line.opacity
            };
        };
        this.addMainControl = function () {
            this.mainControl = new MMSmallPanZoomWidget(new MMBox(10, 10));
            this.mapviewer.addWidget(this.mainControl);
        };
        this.location = function (data) {
            var address = new Object();
            var coords = new Object();
            coords = (typeof(data.point) != 'undefined' && typeof(data.point.latitude) != 'undefined' && typeof(data.point.longitude) != 'undefined') ? new MMLatLon(data.point.latitude, data.point.longitude) : coords;
            address = (data.address) ? (typeof(data.address) == "string" ? new MMAddress({
                qs: data.address
            }) : new MMAddress(data.address)) : address;
            return new MMLocation(coords, address);
        };
        this.location.toString = function () {
            return this.address.qs;
        };
        this.point = function (latitude, longitude) {
            return new MMLatLon(latitude, longitude);
        };
        this.zoom = function (zoomIndex) {
            if (zoomIndex === null) {
                return null;
            }
            var zoom = 0;
            var factors = this.mapviewer.getAvailableZoomFactors();
            var zoomRatio = (factors.length - 1) / 100;
            return factors[factors.length - Math.floor(zoomRatio * zoomIndex) + 1];
        };
        this.showLocation = function (location, zoom) {
            this.mapviewer.goToPosition(location, this.zoom(zoom));
            this.currentLocation = location;
        };
        this.showAllLocations = function () {
            this.mapviewer.goToPosition(this.mapviewer.getAutoScaleLocation(this.locations));
            this.currentLocation = this.locations[0];
        };
        this.getRoute = function (data, target) {
            if (target !== null) {
                this.currentLocation = this.locations[target];
            } else {
                target = 0;
            }
            if (this.markers.length > 1) {
                for (var i = 0; i < this.markers.length; i++) {
                    this.markers[i].setVisibility(i == target);
                }
            }
            var loc = this.location(data);
            if (loc.coords == undefined) {
                this._geocodeHandlerQueue.push(function (results) {
                    if (typeof(results.length) == "number") {
                        this._getRoute([results[0], this.currentLocation]);
                    } else {
                        this._getRoute([results, this.currentLocation]);
                    }
                });
                this.geocoder.geocode(loc.address);
            } else {
                this._getRoute([loc, this.currentLocation]);
            }
        };
        this._getRoute = function (locations) {
            if (typeof(this.router) == 'undefined') {
                this.router = MMFactory.createRouteRequester(this.showRoute);
                this.router.mapper = this;
            }
            this.route = new MMRoute(locations);
            this.route.lang = this.language(this.options.language);
            this.route.locale = this.locale(this.options.country, this.route.lang);
            this.router.request(this.route);
        };
        this.showRoute = function () {
            this.route = this.mapper.route;
            if (this.route.error_code) {
                alert(this.route.error_code + ': ' + this.route.error_explanation);
            } else {
                this.mapper.mapviewer.goToPosition(this.mapper.mapviewer.getAutoScaleLocation(this.route.bounds));
                this.mapper.showRouteSteps(this.route.stages[0]);
                for (var i = 0, l = this.route.polyLine.length; i < l; ++i) {
                    this.route.polyLine[i].reset(null, this.mapper._routingLine(this.mapper.options.routing.line));
                    if (typeof(this.mapper.overlays) == 'undefined') {
                        this.mapper.overlays = new Array();
                    }
                    this.mapper.mapviewer.addOverlay(this.route.polyLine[i]);
                    this.mapper.overlays.push(this.route.polyLine[i]);
                }
            }
        };
        this._pluralize = function (localizationType, object, value) {
            return object[value] + " " + this.options.localization[localizationType][value + (object[value] != 1 ? "Plural" : "")];
        };
        this.getStartAddress = function (route) {
            var sa = route.stages[0].start_address;
            var address = new Array();
            var toadd = ["display_name", "street", "city", "state", "region", "postal_code", "country_code"];
            for (var i = 0; i < toadd.length; i++) {
                if (typeof(sa[toadd[i]]) != "undefined") {
                    address.push(sa[toadd[i]]);
                }
            }
            return address.join(", ");
        };
        this.showRouteSteps = function (route) {
            var count = 0;
            var curr_step = 1;
            var max_zindex = 1000;
            var container = jQuery(this.options.routeContainer);
            var infoContainer = jQuery(".routeInfo", container);
            var finePrint = jQuery("#routeFinePrint", container);
            var routingSummary = new Array();
            routingSummary.push("<dl class=\"routingSummary\">");
            if (this.options.routing.showFrom) {
                var routeStart = this.getStartAddress(this.route);
                routingSummary.push("<dt class=\"from\">" + this.options.localization.routing.from + "</dt><dd class=\"from\">" + routeStart + "</dd>");
            }
            if (this.options.routing.showTo) {
                routingSummary.push("<dt class=\"to\">" + this.options.localization.routing.to + "</dt><dd class\"to\">" + this.location.toString.apply(this.currentLocation) + "</dd>");
            }
            routingSummary.push("<dt class=\"distance\">" + this.options.localization.routing.distance + "</dt><dd class=\"distance\"> ");
            routingSummary.push(this._pluralize("routing", route.distance, this.options.distanceUnit));
            routingSummary.push("</dd><dt class=\"duration\">" + this.options.localization.routing.duration + "</dt><dd class=\"duration\">");
            if (route.duration.days > 0) {
                routingSummary.push(this._pluralize("routing", route.duration, "days") + " ");
            }
            if (route.duration.hours > 0) {
                routingSummary.push(this._pluralize("routing", route.duration, "hours") + " ");
            }
            if (route.duration.minutes > 0) {
                routingSummary.push(this._pluralize("routing", route.duration, "minutes"));
            }
            routingSummary.push("</dd></dl>");
            routingSteps = new Array();
            routingSteps.push("<ol class=\"routeSteps\">");
            var steps = route.steps;
            for (var stepCount = 0; stepCount < steps.length; stepCount++) {
                routingSteps.push("<li>");
                if (stepCount === 0) {
                    if (typeof(this.overlays) != "undefined") {
                        for (var i = 0; i < this.overlays.length; i++) {
                            this.mapviewer.removeOverlay(this.overlays[i]);
                        }
                    }
                    if (this.overlays == undefined) {
                        this.overlays = new Array();
                    }
                    this.overlays.push(this.addRouteMarker(steps[stepCount].start_point, "Start"));
                }
                routingSteps.push(steps[stepCount].instruction);
                var roadname = steps[stepCount].road_name;
                var roadnumber = steps[stepCount].road_number;
                if (roadname && roadnumber) {
                    routingSteps.push(' ' + roadname + ' (' + roadnumber + ') ');
                } else if (roadname) {
                    routingSteps.push(' ' + roadname + ' ');
                } else if (roadnumber) {
                    routingSteps.push(' ' + roadnumber + ' ');
                }
                if (steps[stepCount].distance.miles != 0) {
                    routingSteps.push(" <em>" + this._pluralize("routing", steps[stepCount].distance, this.options.distanceUnit) + "</em>");
                }
                routingSteps.push("</li>");
            }
            routingSteps.push("</ol>");
            routingDisclaimer = new Array();
            routingDisclaimer.push("<p class=\"copyright\">" + this.route.copyright + "</p><p class=\"disclaimer\"><a href=\"" + this.route.disclaimer + "\">" + this.options.localization.routing.disclaimer + "</a></p>");
            infoContainer.html(this.localize("routing", routingSummary.join("") + routingSteps.join("")));
            finePrint.html(routingDisclaimer.join(""));
        };
    };
    jQuery.infiniti.mapping.providers.multimap.load = function (options) {
        var params = "";
        if (options.callback) {
            window["jQueryinfinitimapping" + options.key] = options.callback;
            params = "?callback=jQueryinfinitimapping" + options.key;
        }
        document.write("<scr" + "ipt src=\"http://clients.multimap.com/API/maps/1.2/" + options.key + params + "\"></scr" + "ipt>");
    };
})(jQuery);
(function (jQuery) {
    jQuery.fn.rotateDimensions = function (options) {
        var t = jQuery(this);
        options = jQuery.extend({
            resizecallback: null,
            split: 4,
            height: t.width(),
            width: t.height(),
            speed: "fast",
            easing: "linear"
        }, options);
        var hdiff = (t.height() - options.height) / 4;
        var wdiff = (t.width() - options.width) / 4;
        if (hdiff !== 0 && wdiff !== 0) {
            hdiff = (hdiff > 0 ? "-=" + hdiff : ("+=" + hdiff).replace("-", "")) + "px";
            wdiff = (wdiff > 0 ? "-=" + wdiff : ("+=" + wdiff).replace("-", "")) + "px";
            for (var i = 0; i < options.split; i++) {
                t.animate({
                    height: hdiff,
                    width: wdiff
                }, options.speed, options.easing).queue(function () {
                    options.resizecallback.apply(this);
                    jQuery(this).dequeue();
                });
            }
        }
        if (typeof(options.callback) == 'function') {
            t.queue(function () {
                options.callback.apply(this);
                jQuery(this).dequeue();
            });
        }
    };
})(jQuery);
