/*
 * Copyright (c) 2010, Inmite s.r.o. (www.inmite.eu). All rights reserved.
 *
 * This source code can be used only for purposes specified by license contract
 * signed by rightful deputy of Inmite s.r.o. This source code can be used only
 * by owner of the license.
 * Any disputes arising in respect of this agreement (license) shall be brought
 * before the Municipal Court of Prague.
 */

/**
 * Custom Google Map with a lot of extra features.
 *
 * Version 0.2
 *
 * Made by inmite
 */

$.address.change(function(e) {
    if (IMap.m && IMap.m.getCenter()) {
        if (e.value != IMap.prepareCurrentParamStr()) {
            IMap.setCenterByParamStr(e.value);
        }
    }
});


var IMap = {
    m: null,
    cfg: null,
    overlays: [],

    init: function(cfg) {
        // set defaults first
        cfg.mapElementId = cfg.mapElementId || 'map';
        cfg.lat = cfg.lat || 43.834526;
        cfg.lng = cfg.lng || 7.03125;
        cfg.zoom = cfg.zoom || 7;

        IMap.cfg = cfg;

        // setup and run resize callback (if any)
        if (cfg.resizeCallback) {
            cfg.resizeCallback.call();
            $(window).bind('resize', cfg.resizeCallback);
        }

        // now initialize map
        IMap.m = new GMap2($('#'+cfg.mapElementId)[0], {
            mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]
        });

        var hash = window.location.hash;
        if (hash && hash.length > 1 && IMap.setCenterByParamStr(hash.substr(1))) {
            // nothing to do, center was succesfully set by IMap.setCenterByParamStr()
        } else {
            // otherwise use values set by cfg
            IMap.m.setCenter(new GLatLng(cfg.lat, cfg.lng), cfg.zoom);
            IMap.updateCurrentURL();
        }

        IMap.m.setMapType(G_NORMAL_MAP);
        IMap.m.enableScrollWheelZoom();
        IMap.m.enableContinuousZoom();
//        IMap.m.addControl(new GLargeMapControl3D());
//        IMap.m.addControl(new GLargeMapControl());
        IMap.m.addControl(new GSmallMapControl());
//        IMap.m.addControl(new GMenuMapTypeControl());
//        IMap.m.addControl(new GOverviewMapControl());

        // initialize custom controls
        if (cfg.controls) {
            for (k = 0; k < cfg.controls.length; k++) {
                cfg.controls[k].initControl(IMap.m);
            }
        }

        // initialize overlays
        if (cfg.overlays) {
            for (k = 0; k < cfg.overlays.length; k++) {
                cfg.overlays[k].initOverlay(IMap.m.getBounds(), IMap._overlayInitDone);
            }
        }

        // map moving listener
        GEvent.addListener(IMap.m, "moveend", IMap.mapMoved);

        // place picking on the map
        if (cfg.pickPlaceCallback) {
//            GEvent.addListener(IMap.m, "click", IMap.mapClicked);
        }
    },


        /**
         * Callback that indicates given markerOverlay succesfully loaded data (we can add it to map).
         */
        _overlayInitDone: function(overlay) {
            IMap.overlays.push(overlay);// store overlay reference
            IMap.m.addOverlay(overlay);

            if (overlay == poslitoOverlay) {
                overlayInited();
            }
        },


    /**
     * Sets current map center (and zoom) by given param string.
     *
     * @param paramStr  string parsable by parseParamStr()
     */
    setCenterByParamStr: function(paramStr) {
        var p = IMap.parseParamStr(paramStr);
        if (p.ll) {
            if (p.z == IMap.m.getZoom()) {
                IMap.m.panTo(GLatLng.fromUrlValue(p.ll));
            } else {
                // changing also zoomlevel
                IMap.m.setCenter(GLatLng.fromUrlValue(p.ll), p.z ? parseInt(p.z) : IMap.cfg.zoom);
            }
            return true;
        } else {
            return false;
        }
    },


    /**
     * Updates current URL hash, to match current map center/zoom.
     * This is called on "moveend" event of map.
     */
    updateCurrentURL: function() {
        if (IMap.cfg.disableHistory) {
            return false;
        }

        var l = window.location + '';

        l = l.replace(/#.*/, '');
        l += '#'+IMap.prepareCurrentParamStr();

        window.location = l;

        // indicate history change
        $.address.value();
    },


    /**
     * Generates paramStr with current center/zoom of the map.
     */
    prepareCurrentParamStr: function() {
        return 'll='+IMap.m.getCenter().toUrlValue()+'&z='+IMap.m.getZoom();
    },


    /**
     * Parses paramStr and pulls out parameters.
     * Has special handling for "ll" parameter.
     *
     * @param paramStr  expected format of paramStr is "ll=49.396675,16.281738&z=6"
     */
    parseParamStr: function(paramStr) {
        var out = {};

        var items = paramStr.split('&');
        for (var k = 0; k < items.length; k++) {
            var it = items[k].split('=');
            if (it[0] == 'll') {
                out.ll = it[1];
                var ll = it[1].split(',');
                out.lat = ll[0];
                out.lng = ll[1];
            } else if (it[0].match(/[a-zA-Z_]+/)) {
                eval('out.'+it[0]+' = "'+it[1]+'";');
            }
        }

        return out;
    },

    findOverlayById: function(overlayId) {
        for (k = 0; k < IMap.overlays.length; k ++ ) {
            if (IMap.overlays[k].overlayId == overlayId) {
                return IMap.overlays[k];
            }
        }
        return false;
    },

    hideOverlayId: function(overlayId) {
        var o = IMap.findOverlayById(overlayId);
        if (o) { o.hide(); }
    },

    showOverlayId: function(overlayId) {
        var o = IMap.findOverlayById(overlayId);
        if (o) { o.show(); }
    },

    overlayCheck: function(checkId, overlayId) {
        if ($('#'+checkId)[0].checked) {
            IMap.showOverlayId(overlayId);
        } else {
            IMap.hideOverlayId(overlayId);
        }
    },

    mapMoved: function() {
        for (k = 0; k < IMap.overlays.length; k++) {
            if (IMap.overlays[k].boundsChanged) {
                IMap.overlays[k].boundsChanged(IMap.m.getBounds());
            }
        }
        IMap.updateCurrentURL();
        $('#log')[0].innerHTML = IMap.m.getCenter().toString() + IMap.m.getZoom();
    },

    mapClicked: function(overlay, latlng, overlaylatlng) {
        if (!latlng) {
            return false;
        }

        IMap.cfg.pickPlaceCallback(latlng);

        IMap.m.openInfoWindowHtml(latlng,
            '<div class="fph">Cítím se tady...</div>' +
            '<div class="fp" id="feel1" onclick="picked(1);">Skvěle!</div>' +
            '<div class="fp" id="feel2" onclick="picked(2);">V pohodě</div>' +
            '<div class="fp" id="feel3" onclick="picked(3);">Jde to...</div>' +
            '<div class="fp" id="feel4" onclick="picked(4);">Nic moc</div>' +
            '<div class="fp" id="feel5" onclick="picked(5);">Hrozně!</div>');

    },

    mapClicked__marker: function(overlay, latlng, overlaylatlng) {
        if (!latlng) {
            latlng = overlaylatlng;
        }

        if (!latlng) {
            return false;
        }

        IMap.m.openInfoWindow(latlng, $('#feel-picking')[0]);

        IMap.cfg.pickPlaceCallback(latlng);

        if (IMap.pickerMarker) {
            IMap.pickerMarker.setLatLng(latlng);
            return true;
        } else {
            IMap.pickerMarker = new GMarker(latlng, {
                draggable: true,
                bouncy: true
            });
            IMap.m.addOverlay(IMap.pickerMarker);

            GEvent.addListener(IMap.pickerMarker, 'dragend', function(latlng) {
                IMap.cfg.pickPlaceCallback(latlng);
            });
        }
    }

};