﻿dojo.provide("jsapi.dijit.SimpleTOC");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dojo.data.ItemFileReadStore");

dojo.require("dijit.Tree");
dojo.require("dijit.Menu");
dojo.require("dijit.Dialog");
dojo.require("dojox.collections.Dictionary");

dojo.require("esri.map");

//
// IF USING LOCAL COPY: CHANGE URL TO WEB ACCESSIBLE FOLDER LOCATION OF THIS JS FILE
//
dojo.registerModulePath("jsapi.dijit.SimpleTOC", "http://Dallas.dfwmaps.com/");

var toc = null;
var legendsResponses = {responses:[]};


dojo.declare("jsapi.dijit.SimpleTOC.UI", [dijit._Widget, dijit._Templated], {
    templatePath: dojo.moduleUrl("jsapi.dijit.SimpleTOC", "templates/SimpleTOCUI.html"),

    started: false,
    map: null,
    tree: null,
    model: null,
    store: null,
    menuLayerItem: '',
    displayViewInMenu: true,
    legendsDict: null,

    constructor: function() {
        var head = document.getElementsByTagName("head")[0],
        css = document.createElement("link");
        css.setAttribute("rel", "stylesheet");
        css.setAttribute("type", "text/css");
        css.setAttribute("media", "all");
        css.setAttribute("href", dojo.moduleUrl("jsapi.dijit.SimpleTOC", "stylesheets/SimpleTOCUI.css"));
        head.appendChild(css);

        // PROVIDE PROPER CONTEXT FOR TREE EVENTS
        this.getIconClass = dojo.hitch(this, this.getIconClass);
        this.getNodeLabelClass = dojo.hitch(this, this.getNodeLabelClass);
        this.onTreeNodeClick = dojo.hitch(this, this.onTreeNodeClick);
        this.onTreeNodeOpen = dojo.hitch(this, this.onTreeNodeOpen);

        // PROVIDE PROPER CONTEXT FOR MENU EVENTS        
        this.createTree = dojo.hitch(this, this.createTree);
        this.zoomToInitial = dojo.hitch(this, this.zoomToInitial);
        this.zoomToFull = dojo.hitch(this, this.zoomToFull);
        this.legendImage = dojo.hitch(this, this.legendImage);
        this.layerTransp = dojo.hitch(this, this.layerTransp);
        this.setLayerOpacity = dojo.hitch(this, this.setLayerOpacity);
        this.layerInfo = dojo.hitch(this, this.layerInfo);
        this.onMenuItemOpen = dojo.hitch(this, this.onMenuItemOpen);
        this.setLayerLegend = dojo.hitch(this, this.setLayerLegend);
        this.testCommand = dojo.hitch(this, this.testCommand);

        legendsDict = new dojox.collections.Dictionary();
    },

    buildRendering: function() {
        this.inherited("buildRendering", arguments);
        dojo.parser.parse(this.domNode);
    },

    startup: function() {

        if (!this.started) {

            // CREATE TREE
            this.createTree();

            // TREE EVENTS
            this.tree.getIconClass = this.getIconClass;
            this.tree.getLabelClass = this.getNodeLabelClass;
            this.tree.onClick = this.onTreeNodeClick;
            this.tree.onOpen = this.onTreeNodeOpen;

            // MENU ITEMS EVENTS
            dojo.connect(dijit.byId(this.id + ".layerMenu.zoomToInital"), "onClick", this, "zoomToInitial");
            dojo.connect(dijit.byId(this.id + ".layerMenu.zoomToFull"), "onClick", this, "zoomToFull");

            dojo.connect(dijit.byId(this.id + ".layerMenu.viewIn.arcmap"), "onClick", this, "viewInArMap");
            dojo.connect(dijit.byId(this.id + ".layerMenu.viewIn.explorer"), "onClick", this, "viewInExplorer");
            dojo.connect(dijit.byId(this.id + ".layerMenu.viewIn.googleEarth"), "onClick", this, "viewInGoogleEarth");

            dojo.connect(dijit.byId(this.id + ".layerMenu.test.command"), "onClick", this, "testCommand");

            dojo.connect(dijit.byId(this.id + ".opacitySlider"), "onChange", this, "setLayerOpacity");
            dojo.connect(dijit.byId(this.id + ".legendDlg"), "onOpen", this, "legendImage");
            dojo.connect(dijit.byId(this.id + ".layerTransparencyDlg"), "onOpen", this, "layerTransp");
            dojo.connect(dijit.byId(this.id + ".layerMetadataDlg"), "onOpen", this, "layerInfo");

            // MENU OPEN EVENT
            dojo.connect(dijit.byId(this.id + ".layerMenu"), '_openMyself', this, 'onMenuItemOpen');

            // BIND MENU TO TREE
            // when we right-click anywhere on the tree, make sure we open the menu
            dijit.byId(this.id + ".layerMenu").bindDomNode(this.tree.domNode);

            // LAYER MENU
            var layerMenu = dijit.byId(this.id + ".layerMenu");

            // REMOVE "VIEW IN" MENU?
            if (!this.displayViewInMenu) {
                var viewInSep = dijit.byId(this.id + ".layerMenu.viewInSep");
                var viewInMenu = dijit.byId(this.id + ".layerMenu.viewIn");
                layerMenu.removeChild(viewInSep);
                layerMenu.removeChild(viewInMenu);
            }

            // REMOVE TEST COMMAND
            var testSep = dijit.byId(this.id + ".layerMenu.testSep");
            var testMenu = dijit.byId(this.id + ".layerMenu.test");
            layerMenu.removeChild(testSep);
            layerMenu.removeChild(testMenu);
        }

        this.started = true;
    },

    createTree: function() {

        // WE NEED THIS INITIAL ITEM SO THE TREE IS CREATED CORRECTLY
        var dummyItem = { root: true, url: 'Dummy', label: 'Dummy', type: 'Layer', subLayers: '', children: [] };

        // DATA STORE
        this.store = new dojo.data.ItemFileWriteStore({
            data: {
                identifier: 'url',
                label: 'label',
                items: [dummyItem]
            }
        });

        // FOREST STORE MODEL
        this.model = new dijit.tree.ForestStoreModel({
            store: this.store,
            query: { type: 'Layer' },
            childrenAttrs: ["children"]
        });

        // TREE	    
        this.tree = new dijit.Tree({
            model: this.model,
            showRoot: false,
            persist: false
        }, dojo.byId(this.id + '.tree'));


        // REMOVE FIRST TREE ITEM
        this.store.deleteItem(dummyItem);
        this.store.save();
    },

    // INITIALIZE DIJIT WITH MAP
    init: function(map) {
        toc = this;
        this.map = map;
        // MAP ON LAYER ADD EVENT	    
        //dojo.connect(this.map,'onLayerAdd',this,'allLayersLoaded');
        this.buildTOC();
    },

    // CHECK TO SEE IF ALL LAYERS HAVE BEEN LOADED
    allLayersLoaded: function(layer) {

        var theMap = this.map;
        // GET LIST OF LAYERS THAT ARE LOADED
        var loadedLayers = dojo.filter(this.map.layerIds, function(layerId) {
            var layer = theMap.getLayer(layerId);
            return ((layer != null) && (layer.loaded));
        });

        // BUILD TOC AFTER ALL LAYERS ARE LOADED
        if (this.map.layerIds.length == loadedLayers.length) {
            this.buildTOC();
        }
    },


    addLegendImages: function(mapLayer, response) {



        var responseWithId = { id: mapLayer.url[0], response: response }
        legendsResponses.responses.push(responseWithId);



    },

    // BUILD THE TOC
    buildTOC: function() {

        /*
        // REMOVE NODES
        var nodesObj = this.tree._itemNodeMap;
        for(var nodeName in nodesObj) {
        if(nodeName) {
        console.info(nodeName);
        var node = nodesObj[nodeName];	        
        // REMOVE TREE ITEM
        this.store.deleteItem(node.item);                	    
        }
        }
        this.store.save();
        */

        var theMap = this.map;
        var layerIds = theMap.layerIds;
        // GET LAYER IDS IN REVERSE ORDER
        for (var idx = (agis_services.length - 1); idx >= 0; idx--) {
            var layer = agis_services[idx];
            if (layer.id == null) {
                layer.id = idx;
            }



            this.buildLayerTOCItem(layer);
        }

        // EXPAND NODES	    	    
        var nodesObj = this.tree._itemNodeMap;
        for (var nodeName in nodesObj) {
            var node = nodesObj[nodeName];
            if (node.item.type) {
                if (node.item.type == 'Layer') {
                    this.tree._expandNode(node);
                }
            }
            else {
                this.tree._expandNode(node);
            }
            //for (var childNodeName in node.)
        }
    },

    // ADD MAP LAYER TO TOC
    buildLayerTOCItem: function(layer) {
        try {
            var isTiled = layer.hasOwnProperty('tileInfo');
            var layerObj = { root: true, url: layer.url, label: layer.id, type: 'Layer', subLayers: '', children: [] };

            var subLayers = [];
            var layerInfos = layer.layerInfos;
            var groupLayers = [];

        

            for (var slIdx = 0; slIdx < layerInfos.length; slIdx++) {

                var subLayerId = layerInfos[slIdx].id;

                var parentObj = layerObj;
                var parentId = layerInfos[slIdx].parentLayerId;
                if (parentId != -1) {
                    var _store = this.store;
                    parentObj = dojo.filter(layerObj.children, function(item) {
                        var subId = _store.getValue(item, 'subId');
                        return (subId === parentId);
                    })[0];
                } else {
                    if (layerInfos[slIdx].defaultVisibility) {
                        subLayers.push(subLayerId);
                    }
                }
            //************************************************************************
            //sonia monga: added 04/30/09 to handle Group layers
var groupLayers = [];
dojo.forEach(layer.layerInfos, function(layerInfo) {
  if (layerInfo.subLayerIds) {
    groupLayers.push(layerInfo.id);
  }
});
//alert(groupLayers);
 

            //************************************************************************
                var itemName = layerInfos[slIdx].name;
                var itemUrl = layerObj.url + "/" + subLayerId;
                var itemStyle = (isTiled) ? 'TiledSubLayer' : 'DynamicSubLayer';
                var subLayerObj = { root: false, url: itemUrl, label: itemName, subId: subLayerId, type: itemStyle, parentId: parentObj.url, subLayers: '', children: [] };

                var newSubItem = this.model.newItem(subLayerObj);
                parentObj.children.push(newSubItem);

                var legendObj = { root: false, url: itemName, label: 'value', type: 'legendImages', children: [] };
                var legendItem = this.model.newItem(legendObj);
                newSubItem.children.push(legendItem);

            }
            if (layer.id == GeoRSSAddToServiceId) {
                GeoRSSLayerId = layerInfos.length;
                var subLayerId = layerInfos.length;
                var parentObj = layerObj;

                var itemName = 'Libraries';
               

                var itemName = 'Libraries';

                var itemUrl = 'HannesDemo.xml';
              
                var itemStyle = 'DynamicSubLayer';
                var subLayerObj = { root: false, url: itemUrl, label: itemName, subId: subLayerId, type: itemStyle, parentId: parentObj.url, subLayers: '', children: [] };

                var newSubItem = this.model.newItem(subLayerObj);
                parentObj.children.push(newSubItem);

                
                          
               


                var legendObj = { root: false, url: 'GeoRSSImage' + itemUrl, label: 'georssvalue', type: 'legendImages', children: [] };
                var legendItem = this.model.newItem(legendObj);
                newSubItem.children.push(legendItem);


            }

            layerObj.subLayers = subLayers.join(',');
            var newItem = this.model.newItem(layerObj);
            

            //request for layer's legend
            esri.request({
                url: legendGeneratorURL,
                content: { f: "json", soapUrl: layer.url },
                callbackParamName: "callback",
                load: dojo.partial(this.addLegendImages, newItem),
                error: function(err) {
                    console.error("Unable to get legend for " + layer.id);
                }
            });
        }
        catch (e) {
            console.error(e);
        }
    },

    setLayerLegend: function(layer, imageUrl) {
        legendsDict.add(layer.url, imageUrl);
    },

    // GET TOC ITEM ICON CLASS
    getIconClass: function(item, opened) {
        var iconClass = 'LayerIcon';

        if (item != null) {
            var type = this.store.getValue(item, 'type');

            if (type === 'Layer') {
                var layerId = this.store.getValue(item, 'label');
                var layer = this.map.GetTileLayerByID(layerId);
                if (layer != null) {
                    iconClass = (layer.IsVisible) ? 'MapServiceOnIcon' : 'MapServiceOffIcon';
                }
            }
            else if (type == 'legendImages') {
                iconClass = '';
            }
            else

                if (type === 'TiledSubLayer') {
                iconClass = 'LayerIcon';
            } else {
                if (type === 'DynamicSubLayer') {

                    var subId = this.store.getValue(item, 'subId').toString();
                    var parentID = this.store.getValue(item, 'parentId');
                    var parentItem = this.store._getItemByIdentity(parentID);
                    var parentType = this.store.getValue(parentItem, 'type');

                    if (parentType != 'Layer') {
                        iconClass = 'LayerIcon';
                    } else {
                        var subIdsStr = this.store.getValue(parentItem, 'subLayers');
                        layersLandBase = subIdsStr;
                        if (subIdsStr != null) {
                            var subIds = subIdsStr.split(',');
                            iconClass = (dojo.indexOf(subIds, subId) > -1) ? 'LayerOnIcon' : 'LayerOffIcon';
                        }
                    }
                }
            }
        }
        return iconClass;
    },

    // GET TOC ITEM LABEL CLASS
    getNodeLabelClass: function(item) {
        if (item != null) {
            var type = this.store.getValue(item, "type");
            return type;
        }
    },

    onTreeNodeOpen: function(item, node) {
        if (item.type) {
            if (item.type[0].indexOf('SubLayer') > 0) {
                var newLabel = '';
                if (node.getChildren()[0].labelNode.innerHTML == 'value') {
                    for (var i = 0; i < legendsResponses.responses.length; i++) {
                        var response = legendsResponses.responses[i];
                        if (response.id == item.parentId[0]) {
                            for (var j = 0; j < response.response.layers.length; j++) {
                                var layer = response.response.layers[j];
                                if (item.label[0] == layer.layerName) {
                                    for (var k = 0; k < layer.legend.length; k++) {
                                        var legend = layer.legend[k];
                                        newLabel += "<br><img src='" + legend.url + "' />" + legend.label;


                                    }
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    node.getChildren()[0].labelNode.innerHTML = newLabel;
                    node._updateLayout();
                }
                else if (node.getChildren()[0].labelNode.innerHTML == 'georssvalue') {
                       newLabel += "<br><img src='../images/library.gif' />";
                    node.getChildren()[0].labelNode.innerHTML = newLabel;
                    node._updateLayout();
                }
            }
        }
    },

    // TOGGLE LAYER VISIBILITY WHEN NODE IS CLICKED
    onTreeNodeClick: function(item, node) {

        if (item != null) {

            var type = this.store.getValue(item, 'type');
            if (type === 'Layer') {
                var layerId = this.store.getValue(item, 'label');
                var layer = this.map.GetTileLayerByID(layerId);

                dojo.removeClass(node.iconNode, this.getIconClass(item));
                if (layer.IsVisible) {
                    map.HideTileLayer(layerId);
                }
                else {
                    map.ShowTileLayer(layerId);
                }
                dojo.addClass(node.iconNode, this.getIconClass(item));

            } else if (type === 'DynamicSubLayer') {
                var parentID = this.store.getValue(item, 'parentId');
                var parentItem = this.store._getItemByIdentity(parentID);
                var parentType = this.store.getValue(parentItem, 'type');
                if (parentType === 'Layer') {

                    dojo.removeClass(node.iconNode, this.getIconClass(item));

                    var subIdsStr = this.store.getValue(parentItem, 'subLayers').toString();
                    var subIds = subIdsStr.split(',');
                    var subId = this.store.getValue(item, 'subId').toString();

                    var idIdx = dojo.indexOf(subIds, subId).toString();
                    if (idIdx >= 0) {
                        subIds.splice(idIdx, 1);
                    } else {
                        subIds.push(subId);
                    }
                    subIds.sort();

                    var newlayerId = subIds.join(',');

                    this.store.setValue(parentItem, 'subLayers', subIds.join(','));
                    layersLandBase = subIds.join(',');
                    if (subId == GeoRSSLayerId) {
                        if (idIdx >= 0) {
                            slGeoRSS.Hide();
                        }
                        else {

                            slGeoRSS.Show();
                        }
                    }
                    dojo.addClass(node.iconNode, this.getIconClass(item));


                    var layerId = this.store.getValue(parentItem, 'label');
                    var layer = this.map.GetTileLayerByID(layerId);
                    map.HideTileLayer(layerId);
                    map.ShowTileLayer(layerId);
                }
            }
        }
    },

    onMenuItemOpen: function(evt) {

        // MENU
        var menu = dijit.byId(this.id + ".layerMenu");
        // get a hold of the tree node that was the source of this open event
        var tn = dijit.getEnclosingWidget(evt.target);
        // IS NODE A LAYER NODE?
        var isLayerNode = (this.store.getValue(tn.item, 'type') == 'Layer');
        // HAS LEGEND
        var hasLegend = legendsDict.contains(this.store.getValue(tn.item, 'url'));
        // DISABLE MENU ITEMS IF NOT LAYER NODE
        menu.getChildren().forEach(function(menuItem) {
            if (dojo.isFunction(menuItem.setDisabled)) {
                if (menuItem.id.indexOf('.layerMenu.legend') > -1) {
                    menuItem.setDisabled(!hasLegend);
                } else {
                    menuItem.setDisabled((!isLayerNode) && (menuItem.id.indexOf('.layerMenu.layerInfo') == -1));
                }
            }
        });

        // SET CURRENT STORE ITEM
        this.menuLayerItem = tn.item;
    },

    zoomToInitial: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            this.map.setExtent(layer.initialExtent);
        }
    },

    zoomToFull: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            this.map.setExtent(layer.fullExtent);
        }
    },

    viewInArMap: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            var lyrURL = dojo.string.substitute('${url}/?f=lyr&v=9.2', layer);
            this.viewResource(lyrURL);
        }
    },

    viewInExplorer: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            var nmfURL = dojo.string.substitute('${url}/?f=nmf', layer);
            this.viewResource(nmfURL);
        }
    },

    viewInGoogleEarth: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            var kmzURL = dojo.string.substitute('${url}/kml/mapImage.kmz', layer);
            this.viewResource(kmzURL);
        }
    },

    viewResource: function(resourceURL) {
        setTimeout(function() { window.open(resourceURL); }, 500);
    },

    legendImage: function() {
        if (this.menuLayerItem != null) {
            var layerUrl = this.store.getValue(this.menuLayerItem, 'url');
            var legendImgUrl = legendsDict.item(layerUrl);
            dojo.byId(this.id + ".legendImg").src = legendImgUrl;
        }
    },

    layerTransp: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            var slider = dijit.byId(this.id + '.opacitySlider');
            slider.setValue(layer.opacity * 100);
        }
    },

    setLayerOpacity: function(opacity) {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            if (layer != null) {
                layer.setOpacity(opacity / 100);
            }
        }
    },

    layerInfo: function() {
        if (this.menuLayerItem != null) {
            var layerUrl = this.store.getValue(this.menuLayerItem, 'url');
            dojo.byId(this.id + '.layerMetadataFrame').src = layerUrl;
        }
    },

    testCommand: function() {
        if (this.menuLayerItem != null) {
            var layerId = this.store.getValue(this.menuLayerItem, 'label');
            var layer = this.map.getLayer(layerId);
            if (layer != null) {
                alert(layer.url);
            }
        }
    }

});	


