﻿dojo.provide("Indy.PropertyAssessmentViewer.Legend");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.Tree");
dojo.require("dojo.parser");   
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit._tree.dndSource");
Indy.PropertyAssessmentViewer.Legend.LegendGenerator = function() {
    var navigatorVersion = navigator.appVersion;
    var navigatorIE6 = navigatorVersion.indexOf("MSIE 6", 0);
    var navigatorIE7 = navigatorVersion.indexOf("MSIE 7", 0);
    var countCSS = 0;
    var oldHandlerURL = 'handler/AJAXProxyHandler.ashx?url=';
    var getLegend = function() {
        var myTreeDiv = dojo.byId('myTree');
        if (myTreeDiv != null) {
            console.log("tree is not null");
            var myTree = dijit.byId("myTree")
            myTree.destroyRecursive();
            myTree = null;
            items = [];
        }
        //        var widget = dojo.byId('LegendDivWindow');
        //        widget.style.visibility = "visible";
        //dojo.byId("ToolUp").innerHTML = "Legend";
        //!!!Find map's layers
        //        var loading = dojo.byId("loadingImg");
        //        esri.show(loading);
        var tLM = myMap.getLayer("layer0");
        //var mapScale = map.getScale();
        var mapScale = myMap._LOD.scale;
        console.log(mapScale);

        var mapLayers = myMap.layerIds;
        var mapLayersNames = [];
        var layerClasses = [];
        var arrayOfLinks = [];
        var dataArray = [];
        items = [];
        for (var layerId in mapLayers) {
            if (mapLayers.hasOwnProperty(layerId)) {
                var mapLayer = myMap.getLayer(mapLayers[layerId]);

                if (mapLayer.declaredClass == "esri.layers.ArcGISDynamicMapServiceLayer") {
                    layerClasses.push("dynamic");
                } else if (mapLayer.declaredClass == "esri.layers.ArcGISTiledMapServiceLayer") {
                    layerClasses.push("tiled");
                }
                var layerUrl = mapLayer.url;
                var firstSlicePos = layerUrl.indexOf("/services/", 0);
                var lastSlicePos = layerUrl.indexOf("/MapServer", 0);
                var mapLayerName = layerUrl.slice((firstSlicePos + 10), lastSlicePos);
                mapLayersNames.push(mapLayerName);
                var layerLegendUrl = layerUrl.replace("rest/", "");
                arrayOfLinks.push(layerLegendUrl);
            }
        }

        var i = 0;
        function callLegendService(arrayElem, layerElem, layerElemId, layerIdInMap) {
            var request = {
                //mapServicePath: 'http://192.168.65.111/arcgis/services/busroutes/MapServer',
                //mapServicePath: 'http://192.168.65.111/arcgis/services/TemplateBaseMap1/MapServer',
                //mapServicePath: 'http://192.168.65.111/arcgis/services/TownshipsNeighborhoodsSchoolsChurches/MapServer',
                mapServicePath: arrayElem,
                layerName: '',
                width: 30,
                height: 15,
                dpi: 96,
                imageFormat: 10
            };
            var layerClass = layerClasses[i];

            //Call Legend Web service via Indy.Services.Utilities
            var onComplete = function(data) {
                //Handle case when data is null
                if (data == null) {
                    var legendContainer = dojo.byId("LegendDiv");
                    legendContainer.style.visibility = "visible";
                    legendContainer.innerHTML = "Legend Web service failed to respond."
                } else {
                    console.log(data);
                    console.log(tLM);
                    var newData = [];
                    for (var dataCounter = 0; dataCounter < data.length; dataCounter++) {
                        newData.push(data[dataCounter]);
                    }
                    var dataObject = {
                        map: newData,
                        type: layerElem,
                        id: layerElemId,
                        idInMap: layerIdInMap
                    }
                    //console.log(dataObject);
                    dataArray.push(dataObject);
                    if (dataArray.length == mapLayers.length) {
                        Indy.PropertyAssessmentViewer.Legend.LegendGenerator.onCreateTree(dataArray);
                    }
                    iIncrement();
                }
            }
            var onError = function(error) {
                //Ext.MessageBox.alert('Legend Error','Legend has not been loaded.\n Check map services availability.',null);
                dojo.byId("LegendDiv").innerHTML = "Legend has not been loaded.<br/>Check map services availability.";
            }
            var url = configDataForMap.externalServices.legendService;
            //var url = configDataForMap.externalServices.legendService;
            Indy.Services.Utilities.callService(url, request, onComplete, onError);

        }
        var incrementTimeOut = 2000;
        if (i <= arrayOfLinks.length) {
            loopThroughArray(i);
        }
        function loopThroughArray(i) {
            var arrayElem = arrayOfLinks[i];
            var layerElem = layerClasses[i];
            var layerIdInMap = mapLayers[i];
            var layerElemId = mapLayersNames[i];
            //i++;
            console.log(i, arrayOfLinks.length);
            if (i < arrayOfLinks.length) {
                callLegendService(arrayElem, layerElem, layerElemId, layerIdInMap);
                //setTimeout(loopThroughArray, 3000, i);
                //setTimeout(iIncrement, incrementTimeOut);
                //iIncrement();
            }
        }
        function iIncrement() {
            i++;
            loopThroughArray(i);
        }
        var collectTimeOut = (incrementTimeOut * arrayOfLinks.length) + 1000;
        //setTimeout(collectDataArray, collectTimeOut);
        //collectDataArray();
        function collectDataArray() {
            console.log("pass to the constructor", dataArray);
            Indy.PropertyAssessmentViewer.Legend.LegendGenerator.onCreateTree(dataArray);
        }
        //assign event onZoomEnd to the map
        dojo.connect(myMap, 'onZoomEnd', function(checksectionals) {
            var myTreeDiv = dojo.byId('myTree');
            if (myTreeDiv != null) {
                console.log("tree is not null");
                var myTree = dijit.byId("myTree")
                myTree.destroyRecursive();
                myTree = null;
                items = [];
                Indy.PropertyAssessmentViewer.Legend.LegendGenerator.onCreateTree(dataArray);
            }
        });
    }


    var onCreateTree = function(dataArray) {
        //var currentMapScale = map.getScale();
        var currentMapScale = myMap._LOD.scale;
        for (var mapCount = 0; mapCount < dataArray.length; mapCount++) {
            var data = dataArray[mapCount].map;
            var mapService = {
                value: dataArray[mapCount].type + mapCount,
                type: 'map',
                label: dataArray[mapCount].id,
                id: dataArray[mapCount].idInMap,
                children: []
            }
            for (var i = 0; i < data.length; i++) {
                if (data[i].MinScale != 0 && data[i].MinScale > currentMapScale) {
                    var layerItem = data[i];
                    var firstChildren = { _reference: layerItem.Name + "_" + mapCount + i };
                    mapService.children.push(firstChildren);
                }
                if (data[i].MinScale == 0) {
                    var layerItem = data[i];
                    var firstChildren = { _reference: layerItem.Name + "_" + mapCount + i };
                    mapService.children.push(firstChildren);
                }
            }
            items.push(mapService);
            for (var i = 0; i < data.length; i++) {
                if (data[i].MinScale != 0 && data[i].MinScale > currentMapScale) {
                    var childrenDefinitions = {
                        value: data[i].Name + "_" + mapCount + i,
                        type: 'layer',
                        layerType: dataArray[mapCount].type,
                        parentId: mapService.id,
                        label: data[i].Name,
                        minScale: data[i].MinScale,
                        maxScale: data[i].MaxScale,
                        children: []
                    }
                    var groups = data[i].Groups;
                    //		        for (var j in groups) {
                    //			        var dataChildren = {
                    //				        _reference: groups[j].Heading
                    //			        }
                    //			        childrenDefinitions.children.push(dataChildren);
                    //		        }
                    //items.push(childrenDefinitions);
                    for (var j = 0; j < groups.length; j++) {
                        //			        var dataChildrenDefinitions = {
                        //				        value: groups[j].Heading,
                        //				        children:[]
                        //			        }
                        var classes = groups[j].Classes;
                        for (var k = 0; k < classes.length; k++) {
                            var groupChildren = {
                                _reference: classes[k].Url
                            }
                            //dataChildrenDefinitions.children.push(groupChildren);
                            childrenDefinitions.children.push(groupChildren);
                        }
                        items.push(childrenDefinitions);
                        for (var k = 0; k < classes.length; k++) {
                            var groupChildrenDefinitions = {
                                value: classes[k].Url,
                                label: classes[k].Label
                                //description:classes[k].Description
                            }
                            items.push(groupChildrenDefinitions);
                        }
                    }
                }

                if (data[i].MinScale == 0) {
                    var childrenDefinitions = {
                        value: data[i].Name + "_" + mapCount + i,
                        type: 'layer',
                        layerType: dataArray[mapCount].type,
                        parentId: mapService.id,
                        label: data[i].Name,
                        minScale: data[i].MinScale,
                        maxScale: data[i].MaxScale,
                        children: []
                    }
                    var groups = data[i].Groups;
                    for (var j = 0; j < groups.length; j++) {
                        var classes = groups[j].Classes;
                        for (var k = 0; k < classes.length; k++) {
                            var groupChildren = {
                                _reference: classes[k].Url
                            }
                            childrenDefinitions.children.push(groupChildren);
                        }
                        items.push(childrenDefinitions);
                        for (var k = 0; k < classes.length; k++) {
                            var groupChildrenDefinitions = {
                                value: classes[k].Url,
                                label: classes[k].Label
                            }
                            items.push(groupChildrenDefinitions);
                        }
                    }
                }
            }
        }

        var itemsJSON = dojo.toJson(items);
        //console.log(itemsJSON);
        //        var widget = dojo.byId('ManageMapsDivWindow');
        //        widget.style.visibility = "visible";
        //        var legendContainer = document.createElement("div");
        //        legendContainer.setAttribute('class', "legend");
        //        widget.appendChild(legendContainer);

        var legendContainer = dojo.byId("LegendDiv");
        legendContainer.style.visibility = "visible";
        var treeDiv = document.createElement("div");

        legendContainer.appendChild(treeDiv);
        //widget.appendChild(treeDiv);
        var store = {
            identifier: "value",
            label: "label",
            items: items
        }


        myStore = new dojo.data.ItemFileReadStore({ data: store });
        myModel = new dijit.tree.ForestStoreModel({
            store: myStore,
            query: { type: 'map' },
            rootId: "layers",
            rootLabel: "Maps",
            childrenAttrs: ["children"]
        });
        myTree = new dijit.Tree({
            id: "myTree",
            model: myModel,
            showRoot: false,
            //dndController: "dijit._tree.dndSource",
            getIconClass: dojo.hitch(this, "getIconClass")
        }, treeDiv);

        //        dojo.rawXhrPost ({
        //            url: oldHandlerURL + address + '&input=' + parametersJSON,
        //            handleAs: 'json', // IMPORTANT: tells Dojo to automatically parse the HTTP response into a JSON object
        //            load: function (dataCountries) {
        //                console.log(dataCountries);
        //                myStore = new dojo.data.ItemFileWriteStore({data:dataCountries});
        //	            myModel = new dijit.tree.ForestStoreModel({
        //				    store: myStore,
        //				    query: {type:'continent'},
        //				    rootId: "earth",
        //				    rootLabel: "Earth",
        //				    childrenAttrs: ["children"]
        //			    });
        //	            myTree = new dijit.Tree({
        //		            id: "myTree",
        //		            model: myModel,
        //		            showRoot: false//,
        //		            //dndController: "dijit._tree.dndSource",
        //		            //getIconClass: dojo.hitch(this, "getIconClass") 
        //	            }, treeDiv);
        //        	    
        //	            //myTree.onClick = dojo.hitch(this, "treeClickHandler");
        //	            myTree.startup();
        //            },
        //            error: function (error) {
        //                console.error('Error: ', error);
        //            }
        //        });	    

        //myTree.onClick = dojo.hitch(this, "treeClickHandler");
        dojo.forEach(myTree.rootNode.getChildren(), function(n) {
            this._expandNode(n);
            dojo.forEach(n.getChildren(), function(node) {
                if (node.isExpandable && !node.isExpanded) {
                    this._expandNode(node);
                }
            }, myTree);
        }, myTree);
        myTree.startup();
    }



    return {
        getLegend: getLegend,
        onCreateTree: onCreateTree,
        treeClickHandler: function(item, node, event) {
            if (item.type == "map") {
                var clickedLayerId = item.id;
                var clickedLayer = myMap.getLayer(clickedLayerId);
                if (clickedLayer.visible == true) {
                    dojo.removeClass(node.iconNode, this.getIconClass(item));
                    clickedLayer.hide();
                    dojo.addClass(node.iconNode, this.getIconClass1(item));

                } else {
                    dojo.removeClass(node.iconNode, this.getIconClass1(item));
                    clickedLayer.show();
                    dojo.addClass(node.iconNode, this.getIconClass(item));

                }
            }

            if (item.type == "layer") {
                if (item.layerType == "dynamic") {
                    var clickedLayerName = item.label;
                    var clickedLayerParentId = item.parentId;
                    var parentLayer = myMap.getLayer(clickedLayerParentId);
                    var parentLayerInfos = parentLayer.layerInfos;
                    var thisLayerId;
                    var visibleLayers = parentLayer.visibleLayers;
                    var newVisibleLayers = [];
                    var thisLayerIsVisible = false;
                    for (var infoItem in parentLayerInfos) {
                        if (clickedLayerName == parentLayerInfos[infoItem].name) {
                            thisLayerId = parentLayerInfos[infoItem].id;
                        }
                    }
                    for (var iVis in visibleLayers) {
                        if (visibleLayers[iVis] == thisLayerId) {
                            thisLayerIsVisible = true;
                        }
                    }
                    if (thisLayerIsVisible == true) {
                        for (var iVis in visibleLayers) {
                            if (visibleLayers[iVis] != thisLayerId) {
                                newVisibleLayers.push(visibleLayers[iVis]);
                            }
                        }
                        dojo.removeClass(node.iconNode, this.getIconClass(item));
                        dojo.addClass(node.iconNode, this.getIconClass1(item));
                        if (parentLayer.visible == true) {
                            parentLayer.hide();
                            parentLayer.setVisibleLayers(newVisibleLayers);
                            parentLayer.show();
                        } else {
                            parentLayer.setVisibleLayers(newVisibleLayers);
                        }
                    } else {
                        visibleLayers.push(thisLayerId);
                        dojo.removeClass(node.iconNode, this.getIconClass1(item));
                        dojo.addClass(node.iconNode, this.getIconClass(item));
                        if (parentLayer.visible == true) {
                            parentLayer.hide();
                            parentLayer.setVisibleLayers(visibleLayers);
                            parentLayer.show();
                        } else if (parentLayer.visible == false) {
                            parentLayer.setVisibleLayers(visibleLayers);
                        }
                    }
                }
            }

        },
        getIconClass: function(item, opened) {
            //var currentMapScale = map.getScale();
            //var currentMapScale = map._LOD.scale;

            //Find current scale
            var maxX = myMap.extent.xmax;
            var minX = myMap.extent.xmin;
            var maxY = myMap.extent.ymax;
            var minY = myMap.extent.ymin;
            var dpi = 96;
            var imageWidth = myMap.width;
            var imageHeight = myMap.height;
            var centreX = maxX - (maxX - minX) / 2.;
            var centreY = maxY - (maxY - minY) / 2.;
            var dots_per_m = dpi / 2.54 * 100;
            var width_size_in_m = (imageWidth / 2) / dots_per_m;
            var currentMapScale = (maxX - centreX) / width_size_in_m;
            //Get classes
            var iconClass = "tocLayerCheckedIcon";
            if (item.root == true) {
                iconClass = "tocLayerMapsIcon";
            }
            if (item.type == "layer") {
                if (item.layerType == "tiled") {
                    if (item.minScale != 0) {
                        if (currentMapScale > item.minScale) {
                            iconClass = "tocLayerMapsIcon";
                        } else {
                            iconClass = "tocLayerCheckedShadowedIcon"
                        }
                    } else {
                        iconClass = "tocLayerCheckedShadowedIcon";
                    }
                }
            }
            if (item.root != true && item.type != "layer" && item.type != "map") {
                //document.styleSheets[0].cssRules[1].styleSheet.cssRules[i].style.backgroundImage = "url(" + item.value + ")";
                //document.styleSheets[0].cssRules[1].styleSheet.insertRule('.newRuleForLegend {width: 16px; height: 16px; vertical-align: top; background-repeat: no-repeat; background-image: url(' + item.value + ');}');
                //var css = document.styleSheets[0].cssRules[1].styleSheet;
                if (navigatorIE6 != -1 || navigatorIE7 != -1 || navigatorIE8 != -1) {
                    document.styleSheets[0].addRule('.newRuleForLegend' + countCSS, ' {width: 16px; height: 16px; vertical-align: top; background-position:center; background-repeat: no-repeat; background-image:url(' + item.value + ');}');
                } else {
                    document.styleSheets[1].insertRule('.newRuleForLegend' + countCSS + ' {width: 16px; height: 16px; vertical-align: top; background-position:center; background-repeat: no-repeat; background-image:url(' + item.value + ');}', 0);
                }
                iconClass = "newRuleForLegend" + countCSS;
                countCSS = countCSS + 1;
            }
            if (item.label[0] == undefined) {
                iconClass = "tocHiddenLayer";
            }
            //console.log(item.label[0]);

            if (item.type == "layer") {
                if (item.layerType == "dynamic") {
                    var clickedLayerName = item.label;
                    var clickedLayerParentId = item.parentId;
                    var parentLayer = myMap.getLayer(clickedLayerParentId);
                    var parentLayerInfos = parentLayer.layerInfos;
                    var thisLayerId;
                    var visibleLayers = parentLayer.visibleLayers;
                    var newVisibleLayers = [];
                    var thisLayerIsVisible = false;
                    for (var infoItem in parentLayerInfos) {
                        if (clickedLayerName == parentLayerInfos[infoItem].name) {
                            thisLayerId = parentLayerInfos[infoItem].id;
                        }
                    }
                    for (var iVis in visibleLayers) {
                        if (visibleLayers[iVis] == thisLayerId) {
                            thisLayerIsVisible = true;
                        }
                    }
                    if (thisLayerIsVisible == true) {
                        iconClass = "tocLayerCheckedIcon";
                    } else {
                        iconClass = "tocLayerUncheckedIcon";
                    }
                }
            }
            if (item.type == "map") {
                var clickedLayerId = item.id;
                var clickedLayer = myMap.getLayer(clickedLayerId);
                var thisMapIsVisible = true;
                if (clickedLayer.visible) {
                    thisMapIsVisible = true
                } else {
                    thisMapIsVisible = false
                }
                if (thisMapIsVisible) {
                    iconClass = "tocLayerCheckedIcon";
                } else {
                    iconClass = "tocLayerUncheckedIcon";
                }
            }
            return iconClass;
        },
        getIconClass1: function(item, opened) {
            var iconClass1 = "tocLayerUncheckedIcon";
            return iconClass1;
        },
        getIconClass2: function(item, opened) {
            var iconClass2 = "tocLayerUncheckedIcon";
            return iconClass2;
        },
        convertExtentToScale: function() {
            //from: http://forums.esri.com/Thread.asp?c=158&f=2396&t=258269&mc=1#msgid792510
            //The JS code below will calculate the map scale. IT assumes a DPI of 96 though (which is the default usually).
            var maxX = myMap.extent.xmax;
            var minX = myMap.extent.xmin;
            var maxY = myMap.extent.ymax;
            var minY = myMap.extent.ymin;
            var dpi = 96;
            var imageWidth = myMap.width;
            var imageHeight = myMap.height;

            var centreX = maxX - (maxX - minX) / 2.;
            var centreY = maxY - (maxY - minY) / 2.;

            var dots_per_m = dpi / 2.54 * 100;
            var width_size_in_m = (imageWidth / 2) / dots_per_m;
            var scale = (maxX - centreX) / width_size_in_m;

            return scale;
        }
    }
} ();