﻿dojo.provide("jsapi.dijit.SimpleTOC");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.require("dojo.data.ItemFileWriteStore");
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://keller.dfwmaps.com");

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);        
        
        // 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;

 //draybuck:  commented out all items under MENU ITEMS EVENTS, MENU OPEN EVENT, and BIND MENU TO TREE in order to
 //disable the right-click context menu
 
    	    // 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){
	    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();
	    }	
	},
	
	// 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];
    	    this.tree._expandNode(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;
		    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);
			        }
			    }
    			
			    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);				
		    }
    		
		    layerObj.subLayers = subLayers.join(',');
		    var newItem = this.model.newItem(layerObj);	
		} 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 === '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;
        }
    },

    // 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(',');
		    	    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);
		    }
		}
	}
	
});	

