(function ($) {

    $.fn.loadMap = function (region, imgPath, jsPath, options) {

        // Map vars
        var container = this.selector;
        var baseZoom = 2;
        var startZoom = options.startZoom;
        var minZoom = 0;
        var maxZoom = 3;
        var zoomScaleBy = options.zoomScaleBy;
        var startHPos = options.startHPos;
        var startVPos = options.startVPos;
        var currZindex = 10;
        var contents = '<div class="zoom-btns"><div class="zoom-in zoom-btn"></div><div class="zoom-out zoom-btn"></div></div><div class="region-map-draggable"><img class="region-map-img"/></div>';

        var init = function () {

            // Add viewer controls to container
            $(container).prepend(contents);

            // Create viewer object vars
            var mapImg = $(container + ' .region-map-img');
            var dragMap = $(container + ' .region-map-draggable');
            var zoomInBtn = $(container + ' .zoom-in');
            var zoomOutBtn = $(container + ' .zoom-out');

            // Add map image to viewer
            mapImg.attr('src', mapPNG.src);

            // Zoom in/out functions
            zoomInBtn.click(function () {
                var newWidth = mapImg.width() * zoomScaleBy;
                var newHeight = mapImg.height() * zoomScaleBy;

                if (baseZoom < maxZoom) {
                    mapImg.height(newHeight);
                    $.each($(container + ' .region-map-clickarea'), function (e) {
                        pos = $(this).position();
                        $(this).height($(this).height() * zoomScaleBy);
                        $(this).width($(this).width() * zoomScaleBy);
                        $(this).css('left', pos.left * zoomScaleBy);
                        $(this).css('top', pos.top * zoomScaleBy);
                    });
                    baseZoom++;
                    setMapDrag();
                }
            });

            zoomOutBtn.click(function () {
                var newWidth = mapImg.width() / zoomScaleBy;
                var newHeight = mapImg.height() / zoomScaleBy;

                // If the zoomed out map will be less wide/tall than the container, don't zoom out
                if (baseZoom > minZoom && newWidth > $(container).width() && newHeight > $(container).height()) {
                    mapImg.height(newHeight);
                    $.each($(container + ' .region-map-clickarea'), function (e) {
                        pos = $(this).position();
                        $(this).height($(this).height() / zoomScaleBy);
                        $(this).width($(this).width() / zoomScaleBy);
                        $(this).css('left', pos.left / zoomScaleBy);
                        $(this).css('top', pos.top / zoomScaleBy);
                    });
                    baseZoom--;
                    setMapDrag();
                }
            });

            // Make map draggable
            var setMapDrag = function () {
                var bW = parseInt($(container).css('border-left-width').slice(0, -2));

                var cH = $(container).height();
                var cW = $(container).width();

                var cOT = $(container).offset().top;
                var cOL = $(container).offset().left;

                var mH = mapImg.height();
                var mW = mapImg.width();

                var x1 = cW - mW + bW;
                var y1 = cH - mH + bW;

                var currPos = dragMap.position();
                if (currPos.top < y1) {
                    dragMap.css('top', y1);
                }
                if (currPos.left < x1) {
                    dragMap.css('left', x1);
                }

                dragMap.draggable({
                    cursor: 'move',
                    containment: [x1 + cOL, y1 + cOT, cOL + (bW / 2), cOT + (bW / 2)],
                    stop: function () {
                        var currPos = dragMap.position();
                        if (currPos.top < y1) {
                            dragMap.css('top', y1 - (bW / 2));
                        }
                        if (currPos.left < x1) {
                            dragMap.css('left', x1 - (bW / 2));
                        }
                    }
                });
            }

            // Place loaded clickareas on the map
            var addClickArea = function (name, url, w, h, l, t) {
                currZindex++;
                var ca_id = region + "-" + name;
                var temp_div = "<div id='" + ca_id + "' class='region-map-clickarea'>&nbsp;</div>";
                dragMap.prepend(temp_div);
                var ca_div = '#' + ca_id;
                $(ca_div).height(h);
                $(ca_div).width(w);
                $(ca_div).css('top', t);
                $(ca_div).css('left', l);
                $(ca_div).css('z-index', currZindex);
                $(ca_div).click(function () {
                    window.location = url;
                });
            }

            // Load clickable areas data; set starting map scale and position
            $.ajax({
                url: jsPath + 'map.' + region + '.js',
                dataType: 'json',
                success: function (data) {
                    $.each(data, function (e) {
                        var item = data[e];
                        addClickArea(item.name, item.url, item.w, item.h, item.l, item.t);
                    });

                    // Set map starting scale
                    switch (startZoom) {
                        case 0:
                            zoomOutBtn.click();
                            zoomOutBtn.click();
                            break;
                        case 1:
                            zoomOutBtn.click();
                            break;
                        case 2: break;
                        case 3:
                            zoomInBtn.click();
                            break;
                        default: break;
                    }

                    // Set map starting position
                    switch (startHPos) {
                        case 'left':
                            break;
                        case 'right':
                            dragMap.css('left', dragMap.position().left - (mapImg.width() - $(container).width()));
                            break;
                        case 'center':
                            dragMap.css('left', dragMap.position().left - ((mapImg.width() - $(container).width()) / 2));
                            break;
                        default: break;
                    }

                    // Set map starting vertical position
                    switch (startVPos) {
                        case 'top':
                            break;
                        case 'bottom':
                            dragMap.css('top', dragMap.position().top - (mapImg.height() - $(container).height()));
                            break;
                        case 'middle':
                            dragMap.css('top', dragMap.position().top - ((mapImg.height() - $(container).height()) / 2));
                            break;
                        default: break;
                    }
                    startVPos
                }
            });

            // Start map drag
            setMapDrag();
        }

        // Preload image, then load map functionality
        function PreloadImage(imgSrc, callback) {
            var objImagePreloader = new Image();
            objImagePreloader.src = imgSrc;
            if (objImagePreloader.complete) {
                callback();
                objImagePreloader.onload = function () { };
            }
            else {
                objImagePreloader.onload = function () {
                    callback();
                    // clear onLoad, IE behaves irratically with animated gifs otherwise
                    objImagePreloader.onload = function () { };
                }
            }
        }

        var mapPNG = new Image();
        mapPNG.src = imgPath + 'google_' + region + '.png';
        PreloadImage(mapPNG.src, init);
    };
})(jQuery);
