﻿//dojo.requireLocalization("hb", "mapslt_api");
dojo.require("dojox.analytics.Urchin");
dojo.require("dijit.MenuItem");
dojo.require("dijit.Dialog");
dojo.require("dijit.form.SimpleTextarea");
dojo.require("hb.dijit.InfoWindow");

//dojo.require("hb.PanoramaGraphics");


// STATIC SETTINGS

var staticSettings = {
    dynamicLayers: [
        {
            id: "stops",
            title: {lt:"Stotelės", en:"Public transport"},
            layerUrl: hbConfig.servicesProxyUrl + "mapslt_query/MapServer/0",
            outFields: "T_ID,T_TOPO_NAME",
            tipUrl: "map_tips.ashx?lang=${dojo.locale}&cl=tstp&objID=stop$${T_ID}",
            tileSize: 4000,
            minScale: 3000,
            symbol: {
                className:"esri.symbol.PictureMarkerSymbol",
                args: ['images/stop.gif', 20, 20]
            },
            enabled: true
        }, {
            id: "zebra",
            title: {lt:"\"Zebra belaidis\" interneto vietos", en:"\"Zebra belaidis\" internet zones"},
            layerUrl: hbConfig.servicesProxyUrl + "mapslt_query/MapServer/2",
            outFields: "T_ID,T_TOPO_NAME",
            tipUrl: "map_tips.ashx?lang=${dojo.locale}&cl=tstp&objID=wifi$${T_ID}",
            tileSize: 4000,
            minScale: 3000,
            symbol: {
                className:"esri.symbol.PictureMarkerSymbol",
                args: ['images/zebra.gif', 20, 32]
            }
        }, {
            id: "ads",
            title: {lt:"Reklama", en:"Advertisments"},
            layerUrl: hbConfig.servicesProxyUrl + "mapslt_query/MapServer/12",
            outFields: "title,OBJECTID,imageWidth,imageHeight,imageName,minScale,maxScale",
            tipUrl: "map_tips.ashx?lang=${dojo.locale}&cl=tstp&type=ad&id=${OBJECTID}",
            where: djConfig.isDebug ? "" : "enabled<>0",
            tileSize: 8000000,
            minScale: 30000000,
            symbolTemplate: {
                url: (hbConfig.adsImagesUrl || (hbConfig.servicesUrl + "images/_ads/")) + '${imageName}', 
                width: '${imageWidth}', 
                height: '${imageHeight}'
            },
            graphics: {
                className: "hb.ScaleDependantGraphics",
                options: {minScaleAttr:"minScale", maxScaleAttr:"maxScale"}
            },
            tags: ["ad"],
            enabled: true
        }, {
            id: "panoramas",
            title: {lt:"Panoramos", en:"Panoramas"},
            layerUrl: hbConfig.servicesProxyUrl + "mapslt_query/MapServer/13",
            outFields: "OBJECTID,title_${dojo.locale},thumb,url_${dojo.locale},authorName,authorUrl_${dojo.locale},thumbSmall",
            tipTemplate: {
                title: "${title_${dojo.locale}}",
                info: "<div class='hbPanorama'>"+
                        "<div class='hbPanoramaImg'>"+
                            "<a href='${url_${dojo.locale}}' target='_blank'>"+
                            "<img src='${thumb}' style='height:100px' /></a><br />"+
                            "<a href='${url_${dojo.locale}}' target='_blank'>${strings.panoramasView}</a>"+
                        "</div>"+
                    "${strings.panoramasAuthor}: <a href='${authorUrl_${dojo.locale}}' target='_blank'>${authorName}</a><br />"+
                    "${strings.panoramasSource}: <a href='http://www.turizmas.info' target='_blank'>www.turizmas.info</a></div>"
            },
            tileSize: 8000000,
            minScale: 3000000,
            symbolTemplate: {
                url: '${thumbSmall}', 
                width: "30", 
                height: "22"
            },
            graphics: {
                className: "hb.ClusteredGraphics",
                options: {
                    clusterDist:[[6000,40]],
                    clusterSymbol: {
                        _type: "esri.symbol.PictureMarkerSymbol",
                        _args: ["images/panoramas_cluster.png", 40, 32]
                    }
                }
            },
            enabled: false
        }
    ]
}

if (hb) hb.client='tstp'; // FIXME: find out why in some cases this is not set automatically

// ---------------

var settings = {};
var map = null;
var infoWindow = null;
var ovMap = null;
var gfx = null;
var layers = null;
var layersSwitcher = null;
var scaleBar = null;
var geocoding = null;
var routing = null;
var comments = null;
var stopsMapTips = null;
var toaster = null;
var widgets = null;
var strings = null;
var resizeTimer = null;
var connects = [];
var subscriptions = [];
var contextMenu = null;
var dialogs = {};
var dijits = [];

function init(){ setTimeout(init_, 1); }

function init_(){
    dijit.byId("layout").layout();

    if (hb.layerDefs["stops"]) delete hb.layerDefs["stops"];
    hb.tipSize = {width:270, height:170};
    strings = dojo.i18n.getLocalization("hb", "mapslt_api");

    esri.config.defaults.map.slider = { left:"16px", top:"70px", width:null, height:"14em" };
    esri.config.defaults.io.proxyUrl = "proxy.ashx?cl=" + hb.client;
    
    map = new hb.Map("center", {
        extent: new esri.geometry.Extent({xmin:214648, ymin:5864081, xmax:779799, ymax:6344300, spatialReference: { wkid: 2600} })
    });
    contextMenu = addDijit(new hb.dijit.MapContextMenu({map:map}));
    gfx = new hb.GraphicsManager(map);
    layers = new hb.Layers(map, hb.layerDefs);
    layersSwitcher = addDijit(new hb.LayersSwitcher({layers:layers, id:"layers"/*, 'class':'hbPanel'*/}, dojo.byId("layers")));
    scaleBar = addDijit(new hb.ScaleBar({map:map, width:100}, dojo.byId("scalebar")));
    
    /*geocoding = new hb.dijit.Locator({"class":"hbGeocoding", gfxManager:gfx }, dojo.byId("geocoding"));
    geocoding.textWidget.focus();
    routing = new hb.dijit.Routing({map:map}, dojo.byId("routing"));*/
    geocoding = addDijit(new hb.dijit.Locator({
        "class":"hbGeocoding", 
        gfxManager:gfx, 
        title:strings.searchPlace 
    }), false);
    dijit.byId("searchTabs").addChild(geocoding);
    geocoding.textWidget.focus();
    
    toaster = addDijit(new hb.dijit.Toaster({
        positionDirection: "bl-up",
        messageTopic: "hb.showMessage"}, dojo.byId("toaster")));
    
    if (map.loaded) onMapLoad();
    else connects.push(dojo.connect(map, "onLoad", onMapLoad));
    
    if (dojo.isOpera)
        dojo.publish("hb.showMessage", [{message:strings.ie6Warning, type:"warning", duration:3000000}]);
    if (dojo.isIE == 6){
        if (!dialogs["warning"]){
            var dlg = new hb.dijit.Dialog({ title: strings.warning, content:strings.ie6Warning });
            dlg.startup();
            dlg.attr("buttons", hb.dijit.Dialog.OK);
            dlg.show();
            dojo.addClass(dlg.domNode, "hbWarningDialog");
            dialogs["warning"] = dlg;
        }   
    }
    if (window.external && typeof (window.external.AddService) != "undefined")
        addToolButton(strings.installAccelerator, "hbAcceleratorIcon", function(){window.external.AddService('maps-lt-accelerator.xml');});
    
    // load static settings
    loadSettings(staticSettings);
    // load dynamic settings
    dojo.xhrGet({
        url: "settings.ashx",
        content: {cl:hb.client, lang:dojo.locale},
        load: loadSettings,
        handleAs: "json"
    });
        
    fadeOut("loading");
}

function onMapLoad(){
    try {
        loadSettings(settings, "onMapLoad");
        map.disableKeyboardNavigation();
        var iw = hb.dijit.InfoWindow.create(map); // create alternative InfoWindow for the map
        //iw.registerSection({callback:updateInfoWindowAd});
        
        if (dojo.isIE != 6)
        {
            routing = addDijit(new hb.dijit.Routing({
                map:map, 
                title:strings.searchRoute, 
                serviceUrl:hb.servicesProxyUrl+"mapslt_routing/NAServer/Route?cl=tstp"
            }), false);
            dijit.byId("searchTabs").addChild(routing);
        }
        
        ovMap = addDijit(new hb.dijit.OverviewMap({
            map: map,
            width: 150,
            height: 150,
            attachTo: "BL",
            expandFactor: 3,
            "class": "hbPanel",
            showMaximizer: false,
            baseLayer: new hb.TiledMapServiceLayer(hb.servicesProxyUrl+"mapslt_overview/MapServer?cl=tstp", 
                {tilesUrls:["http://www.maps.lt/cache/mapslt_overview"]})
        }, "ovMap"));
        
        if (dojo.isIE != 6)
        {
            widgets = addDijit(new hb.widgets.WidgetsContainer(
                {map:map, configUrl:"widgets.json"}, dojo.byId("widgets")));
            dojo.subscribe("searchTabs-selectChild", updateLayout);
            //updateLayout();
        }
        
        addContextMenuItems();
        
        connects.push(dojo.connect(map, "onUnload", onMapUnload));
        connects.push(dojo.connect(dijit.byId("center"), "resize", resizeMap));
        dijit.byId("layout").layout();
        //resizeMap();
    
        showBanners();
        
        checkUriFragment();
        connects.push(dojo.connect(dojo.body(), "onhashchange", null, checkUriFragment, true));
    }
    catch(e){hb.err(e);}
}

function onMapUnload(){
    dojo.forEach(connects, dojo.disconnect);
    dojo.forEach(subscriptions, dojo.unsubscribe);
    for (var i in dialogs) dialogs[i].destroyRecursive();
    for (var i in dijits) dijits[i].destroyRecursive();
    hb.dijit.InfoWindow.destroy(map);
}

function resizeMap() {
    if (resizeTimer) clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function() {
        map.resize();
        map.reposition();
        updateLayout();
    }, 500);
    
    //updateLayout();
}

function updateLayout(){
    restrictHeight("#center", "#search", ".hbRouting", 45);
    restrictHeight("#center", "#search", ".hbGeocoding", 45);
    //restrictHeight("#center", "#widgets", ".hbWidgetsContainer", 45);
}

function restrictHeight(containerQuery, componentQuery, elementQuery, reminder){
    var setMaxHeight = function(container, component, element){
        dojo.style(element, {
            maxHeight: Math.max(dojo.contentBox(container).h - 
                dojo.marginBox(component).h + dojo.contentBox(element).h - 
                reminder, 100) + "px",
            overflowY: "auto",
            overflowX: "hidden"
        });
    }
    
    dojo.query(containerQuery).forEach(function(container){
        dojo.query(componentQuery, container).forEach(function(component){
            if (elementQuery)
                dojo.query(elementQuery, component).forEach(function(element){
                    setMaxHeight(container, component, element);
                });
            else
                setMaxHeight(container, component, component);
        });
    });
}

function closeTopBanner(){
    dojo.style("topBanner", "display", "none");
    dijit.byId("layout").resize();
}

function fadeOut(id){
    dojo.animateProperty({
        node:id, 
        properties: {opacity: 0},
        duration:500,
        onEnd: function(){ dojo.style(id, "display", "none"); }
    }).play();
}

var problemDlg;
function reportProblem(){
    if (!problemDlg){
        problemDlg = new hb.dijit.SendMessageDialog({
            title:strings.reportBug,
            url: hb.servicesUrl + 'comment.ashx?cl=' + hb.client
        });
    }
    problemDlg.show();
}

function showBanners(){
    try {
        /*dojo.place("topBanner", "top", "first");
        dojo.style("topBanner", "visibility", "visible");
        dojo.place("bottomBanner", "bottom", "first");
        dojo.style("bottomBanner", "visibility", "visible");*/
        if (bottomBanner.document.getElementsByTagName("img").length){
            dojo.style("bottomBanner", "display", "");
            dijit.byId("layout").layout();
            resizeMap();
        }   
    } catch(e) {}
}

function checkUriFragment(){
    try {
        var query = hb.hash.get("q");
        if (query) geocoding.search(query);
        
        var type = hb.hash.get("t");
        if (type && hb.layerDefs[type] && hb.layerDefs[type].group === "bg")
            layers.show(type);
            
        var center = hb.hash.get("xy");
        if (center){
            var coords = center.split(",");
            if (coords.length === 2){
                var scale = hb.hash.get("z");
                if (scale)
                    var level = hb.level({map:map, scale:scale});
                else
                    var level = map.getLevel();
                var pt = new esri.geometry.Point(parseFloat(coords[0]), parseFloat(coords[1]))
                map.centerAndZoom(pt, level);
            }
        }
        
        var obj = hb.hash.get("obj");
        if (obj){
            var parts = obj.split("|");
            if (parts.length === 4){
                var object = {
                    geometry: {type:"point", coords:[parseFloat(parts[0]), parseFloat(parts[1])]},
                    title: parts[2],
                    info: parts[3]
                };
                gfx.showObject(object);
            }
        }
        
        //hb.hash.set({}, true);
        
        if (dojo.isIE) document.title = "maps.lt";
    } catch(e) {hb.err(e);}
}

function addDijit(/* dijit._Widget */widget, /* Boolean */noStartup)
{
    !noStartup && widget.startup();
    dijits.push(widget);
    return widget;
}

function addToolButton(title, iconClass, action){
    var tools = dojo.byId("tools");
    var btn = dojo.create("span", {"class":"hbActiveElement hbActiveElementWithIcon dijitInline"}, tools, "first");
    btn.innerHTML = "<span class='hbIcon dijitInline " + iconClass + "'></span> " + title;
    connects.push(dojo.connect(btn, "onclick", action));
}

function addContextMenuItems(){
    // Get coordinates item
    var item = new dijit.MenuItem({ label: strings.getCoordinates });
    dojo.publish("hb.dijit.MapContextMenu.addItem", [map, item]);
    connects.push(dojo.connect(item, "onClick", function(){
        var event = item.getParent().lastEvent;
        if (event) {
            var lks = event.mapPoint;
            var geometryService = new esri.tasks.GeometryService(hb.servicesProxyUrl + "Geometry/GeometryServer?cl=" + hb.client);
            geometryService.project(
                [new esri.Graphic(lks)], 
                new esri.SpatialReference({ wkid: 4326 }),
                function(graphics){
                    if (!dialogs["coordsDlg"]){
                        var dlg = new dijit.Dialog({ title: strings.coordinates });
                        dlg.startup();
                        dialogs["coordsDlg"] = dlg;
                    }
                    
                    var wgs = graphics[0].geometry;
                    var content = dojo.string.substitute("${lks_x}, ${lks_y} (LKS)<br \>${wgs_y}, ${wgs_x} (WGS)", 
                        { lks_x: Math.round(lks.x, 0), lks_y: Math.round(lks.y, 0),
                          wgs_x: Math.round(wgs.x*1000000)/1000000, wgs_y: Math.round(wgs.y*1000000)/1000000});
                    dialogs["coordsDlg"].attr("content", content);
                    dialogs["coordsDlg"].show();
                }
            );
        }
    }));
    
    // Get link item
    var item = new dijit.MenuItem({ label: strings.getPointLink });
    dojo.publish("hb.dijit.MapContextMenu.addItem", [map, item]);
    connects.push(dojo.connect(item, "onClick", function(){
        var event = item.getParent().lastEvent;
        if (event)
            getPointLink(event.mapPoint);
    }));
}

function getPointLink(mapPoint){
    var center = hb.center(map.extent);
    var dlg = dialogs["linkDlg"];
    if (!dlg){
         dlg = new dijit.Dialog({ title: strings.pointLink });
         dlg.startup();
         dialogs["linkDlg"] = dlg;
    }
    
    var endPos = location.href.indexOf("#");
    var url = endPos > 0 ? location.href.substr(0, endPos) : location.href;
    url = url + "#obj=" + Math.round(mapPoint.x, 0) + "|" + Math.round(mapPoint.y, 0) + "|" +
        encode(strings.pointTitle) + "|&xy=" + Math.round(center.x, 0) + "," + Math.round(center.y, 0) + 
        "&z=" + hb.scale(map);
    dlg.attr("content", "<textarea cols='50' rows='6'>"+url+"</textarea>");
    dlg.show();
}

function updateInfoWindowAd(node, context){
    console.log(context);
    var baseClass = "hbInfoWindowAd";
    if (!dojo.hasClass(node, baseClass)){
        dojo.addClass(node, baseClass);
        dojo.addClass(node, "hbBubble");
        dojo.create("div", {innerHTML:strings.advertisment, 'class':baseClass+"Header"}, node);
        var ad = dojo.create("div", {'class':baseClass+"Content"}, node);
        dojo.create("a", {
            href: "http://dc1.maps.lt/maps/quickmapgen.html",
            target: "_blank",
            innerHTML: strings.infoWindowSampleAd
        }, ad);
    }
    dojo.style(node, "display", context.tags && context.tags.indexOf("ad") >=0 ? "none" : "");
}

function addDynamicLayers(defs){
    dojo.forEach(defs, function(def){
        var options = {
            id: def.id,
            map: map,
            layerUrl: def.layerUrl,
            outFields: def.outFields,
            where: def.where||null,
            tileSize: def.tileSize,
            minScale: def.minScale,
            tipUrl: def.tipUrl,
            tipTemplate: def.tipTemplate,
            symbolTemplate: def.symbolTemplate,
            visible: def.enabled,
            tags: def.tags || []
        };
        if (def.graphics)
            options.graphics = construct(def.graphics.className, [map, map.graphics, def.graphics.options]);
        if (def.symbol)
            options.symbol = construct(def.symbol.className, def.symbol.args);
        var mapTips = new hb.MapTips(options);
        layersSwitcher.addCheckBox({
            id: def.id,
            title: hb.label(def.title),
            visible: def.enabled,
            onClick: function(ev){mapTips.setVisibility(ev.target.checked);}
        });
    });
}

function encode(s){
    s = encodeURIComponent(s);
    s = s.replace(/\'/g, '&#39;');
    return s;
}

function construct(className, args) {
    var constructor = dojo.getObject(className);
    function F() {
        return constructor.apply(this, args);
    }
    F.prototype = constructor.prototype;
    return new F();
}

function substitute(obj){
    if (!obj || !dojo.isObject(obj))
        return obj;
    for (var i in obj)
    {
        if (dojo.isString(obj[i])){
            obj[i] = obj[i].replace(/\${dojo\.locale}/g, dojo.locale);
            obj[i] = obj[i].replace(/\${strings\.(\w+)}/g, function(str, p1){ return strings[p1]; });
        }
        else if (dojo.isObject(obj[i]))
            substitute(obj[i]);   
    }
}

function initObjects(obj){
    if (!obj || !dojo.isObject(obj))
        return obj;
    for (var i in obj)
    {
        if (!dojo.isString(obj[i]) && dojo.isObject(obj[i])){
            initObjects(obj[i]); 
            if (obj[i]._type){
                obj[i] = construct(obj[i]._type, obj[i]._args);
            }
        }
    }
}

function loadSettings(s, event){
    // settings loaded imediately
    if (event !== "onMapLoad"){
        // perform default substitutions
        substitute(s);
        // initialize declared objects
        initObjects(s);
    }
    // settings loaded only after map is loaded
    if (event === "onMapLoad" || (map && map.loaded)){
        if (s.dynamicLayers)
            addDynamicLayers(s.dynamicLayers);
    }
    settings = dojo.mixin(settings, s);
}


dojo.addOnLoad(init);
