/**
 * Карта
 */
(function() {

    var drivers = [{
        name: "google",
        driver: GoogleMapV3Interface
    }, {
        name: "yandex",
        driver: YandexMapInterface
    }];

    var views = [{
        name: "google",
        caption: "Google.Карта",
        mode: "normal"
    }, {
        name: "google",
        caption: "Google.Спутник",
        mode: "satellite"
    }, {
        name: "yandex",
        caption: "Яндекс.Схема",
        mode: "normal"
    }, {
        name: "yandex",
        caption: "Яндекс.Спутник",
        mode: "satellite"
    }, {
        name: "google",
        caption: "OSM",
        mode: "osm"
    }];

    var types = {
        "google": {
            "normal": 1,
            "satellite": 2,
	    "osm" : 5
        },
        "yandex": {
            "normal": 3,
            "satellite": 4
        }
    };

    var driverAttr = "MapMain.driver";
    var modeAttr = "MapMain.mode";
    var frameAttr = "MapMain.frame";

    var expires = function() {
        return Date.nextDay(7);
    };

    myterra.MapWaitEl = myterra.extend(myterra.Observable, {

        el: null,

        constructor: function(el, opts) {
            myterra.inherited(this);
            this.el = el = $(el);
            this.opts = opts = myterra.applyIf(opts || {
                cls: "map-wait"
            });
        },

        bind: function(navlink) {

            navlink.addStartChangeHandler(this, function() {
                this.el.addClass(this.opts.cls);
            });

            navlink.addChangeRegionHandler(this, function(f, d) {
                this.el.removeClass(this.opts.cls);
            });

        }

    });

    myterra.MapWaitEl.bind = function(navlink, el, opts) {
        new myterra.MapWaitEl(el, opts).bind(navlink);
    };

    myterra.MapPanel = myterra.extend(myterra.Observable, {

        map: null,
        el: null,
        driver: null,
        viewMode: null,

        constructor: function(el, opts) {

            myterra.inherited(this);

            this.el = el = $(el);
            opts = myterra.applyIf(opts, {
                // умолчания
                storeDriver: true,
                restoreDriver: false,
                storeViewMode: true,
                restoreViewMode: false,
                storeFrame: true,
                restoreFrame: false,
                defaultDriver: drivers[1].name,
                defaultViewMode: "normal",
                crosshair: false,
		search: true
            });

            // Quick fix
            opts.storeViewMode = opts.storeDriver;
            opts.restoreViewMode = opts.restoreDriver;

            this.opts = opts;

            var map, map_el, i, t;

            this.map = map = new MapControl();
            var map_el = $("<div class=\"map_area\" />").appendTo(el);

            var height = map_el.innerHeight();
            var width = map_el.innerWidth();
	    
	    var driverOptions = { search : this.opts.search };

            for (i = 0; i < drivers.length; i++) {
                t = drivers[i];
                var mapBlock = $("<div style=\"position:absolute; left:0px; top:0px;\" />")
                    .appendTo(map_el);
                mapBlock.height(height).width(width);
                map.addMapDriver(t.name, new t.driver(mapBlock[0], driverOptions));
            }

            if (opts.crosshair === true) {
                this._chctl = new myterra.Crosshair(map_el);
                this._chctl.update();
                this._chctl.showCrosshair();
            }

            var view = opts.mapType > 0 ? views[opts.mapType - 1] : null;
            var driver = view != null ? view.name : opts.defaultDriver;
            var viewMode = view != null ? view.mode : opts.defaultViewMode;

            if (opts.restoreDriver === true) {
                driver = this.restoreDriver(driver);
            } else {
                map.selectMap(this.driver = driver);
            }

            if (opts.restoreViewMode === true) {
                viewMode = this.restoreViewMode(viewMode);
            } else {
                map.setViewMode(this.viewMode = viewMode);
            }

            if (opts.storeViewMode === true) {
                this.map.addViewModeChangeHandler(this, function() {
                    this.saveViewMode();
                });
            }

            if (opts.mapOptionsEl) {
                this.renderMapOptions(opts.mapOptionsEl, driver, viewMode);
            }

            if (opts.restoreFrame === true) {
                this.restoreFrame();
            }

            if (opts.storeFrame === true) {
                this.map.addBoundsChangeHandler(this, function() {
                    this.saveFrame();
                });
            }

        },

        getMapType: function() {
            var t = types[this.driver];
            if (!!t) {
                t = t[this.viewMode];
                if (!!t) return t;
            }
            return null;
        },

        renderMapOptions: function(el, driver, viewMode) {

            var b = $("<div class=\"button2 button\" />").appendTo(el);
            var caption = $("<div class=\"text combo\" />");
            b.append("<div class=\"left\" />")
                .append("<div class=\"right\" />")
                .append($("<div class=\"bg\" />").append(caption));

            var popup = new myterra.PopupWindow(
            $("<div class=\"popup mt-popup\" />").appendTo(el), {
                button: b,
                togglePopup: true
            });

            el = popup.el;

            var self = this;

            var bindSelectDriverButton = function(a, t) {
                a.click(function(e) {
                    self.selectDriver(t.name, t.mode);
                    caption.text(t.caption);
                    popup.hide();
                    return false;
                });
            };

            var i, len, t, a;
            for (i = 0, len = views.length; i < len; i++) {
                t = views[i];
                a = $("<a href=\"#\"/>").text(t.caption).appendTo(el);
                bindSelectDriverButton(a, t);
                if (t.name == driver && t.mode == viewMode) {
                    caption.text(t.caption);
                }
            }

        },

        selectDriver: function(driver, viewMode, storeFlag) {
            if (this.fireEvent("beforeselectdriver", this, driver) === false)
                return;

            if(driver=='osm') {
                driver = 'google';
                viewMode = 'osm';
            }

            if (this.opts.storeDriver === true || storeFlag === true) {
                myterra.setAttr(driverAttr, driver, expires());
                myterra.setAttr(modeAttr, viewMode, expires());
            }

            this.map.selectMap(this.driver = driver);
            this.map.setViewMode(this.viewMode = viewMode);

            this.fireEvent("selectdriver", this, driver);
        },

        restoreDriver: function(defaultDriver) {
            var driver = myterra.getAttr(driverAttr) || defaultDriver;
            if (!!driver) {
                this.map.selectMap(this.driver = driver);
            }
            return driver;
        },

        saveFrame: function() {
            var frame = this.map.getMapFrame();
            var m = Math.min(frame.latSize, frame.lngSize);
            frame.latSize = m;
            frame.lngSize = m;
            myterra.setAttr(frameAttr, frame, expires());
        },

        restoreFrame: function() {
            var frame = myterra.getAttr(frameAttr);
            if (frame) {
                this.map.setMapFrame(frame.lat, frame.lng, frame.latSize,
                    frame.lngSize);
            }
        },

        saveViewMode: function() {
            var mode = this.map.getViewMode();
            myterra.setAttr(modeAttr, mode, expires());
        },

        restoreViewMode: function(defaultViewMode) {
            var viewMode = myterra.getAttr(modeAttr) || defaultViewMode;
            if (!!viewMode) {
                this.map.setViewMode(this.viewMode = viewMode);
            }
            return viewMode;
        }

    });

    myterra.MapPanel.hasSavedFrame = function() {
        return myterra.getAttr(frameAttr) != null;
    };

})();
