﻿function TOC(layers, rootElementName, tocRootName, esriMap, url, legOpacity) {
    var imgPlus = '_images/plus.gif';
    var imgMinus = '_images/minus.gif';
    var ulRootLegend = 'ulRootLegend';
    var liRootLegend = 'liRootLegend';
    var liRootLegendDisabled = 'liRootLegendDisabled';

    var _legOpacity = legOpacity;

    //Methods
    this.BuildLayerList = BuildLayerList;
    this.UpdateLayerVisibility = UpdateLayerVisibility;
    this.UpdateScaleRendering = UpdateScaleRendering;
    this.GetLayerIDByName = GetLayerIDByName;
    this.GetLayerByID = GetLayerByID;
    this.GetLayerByName = GetLayerByName;
    this.hide = hide;
    this.show = show;
    this.SetLegendOpacity = SetLegendOpacity;
    this.GetVisibleLayers = GetVisibleLayers;

    //Opacity
    function SetLegendOpacity(op) {
        _legOpacity = op;
    }

    //Hide/Show TOC
    function hide() {
        document.getElementById(tocRootName).style.display = 'none';
    }

    function show() {
        document.getElementById(tocRootName).style.display = '';
    }

    //Build TOC
    function BuildLayerList() {
        var items = [];
        var root = document.createElement('ul');
        root.className = ulRootLegend;
        root.id = tocRootName;

        for (lyr in layers) {
            var layer = layers[lyr];

            if (layer.parentLayerId == -1) {
                var e_li = document.createElement('li');
                e_li.className = liRootLegend;
                e_li.id = "li" + layer.id;
                var e_li_text = document.createTextNode(layer.name);

                var e_img = document.createElement('img');
                e_img.className = 'plus';
                e_img.src = imgPlus;
                e_img.onclick = function() { return ToggleTOC(this); }

                //Checkbox
                var e_input = document.createElement('input');
                e_input.type = 'checkbox';
                e_input.id = layer.id;
                e_input.checked = layer.defaultVisibility ? true : false;
                e_input.defaultChecked = layer.defaultVisibility ? true : false;
                e_input.onclick = function() { return UpdateLayerVisibility(this); }

                //Scale rendering
                SetScaleRendering1(e_input, layer, e_li);

                //Append nodes
                e_li.appendChild(e_img);
                e_li.appendChild(e_input);
                e_li.appendChild(e_li_text);

                //Set nodisplay layers
                if (layer.name.indexOf("nodisplay") != -1) {
                    e_li.style.display = 'none';
                }

                //Get group layers
                if (layer.subLayerIds != null) {
                    AppendChildren(layers, layer, e_li, layer.defaultVisibility);
                }

                root.appendChild(e_li);
            }

        }

        document.getElementById(rootElementName).appendChild(root);
    }

    function AppendChildren(layers, layer, root, parentChecked) {
        var childLayers = FindChildren(layers, layer);
        var e_ul = document.createElement('ul');
        e_ul.style.display = 'none';
        e_ul.className = 'closed';

        for (childLayer in childLayers) {
            var child = childLayers[childLayer];
            var e_li = document.createElement('li');
            e_li.id = "li" + child.id;
            e_li.className = liRootLegendDisabled;
            var e_li_text = document.createTextNode(child.name);

            var e_img = document.createElement('img');
            e_img.src = imgPlus;
            e_img.className = 'plus';
            e_img.onclick = function() { return ToggleTOC(this); }

            var e_input = document.createElement('input');
            e_input.type = 'checkbox';
            e_input.id = child.id;
            e_input.checked = child.defaultVisibility ? true : false;
            e_input.defaultChecked = child.defaultVisibility ? true : false;
            e_input.onclick = function() { return UpdateLayerVisibility(this); }

            //Enable/disable based on parent
            if (!parentChecked)
                e_input.disabled = 'disabled';

            //Scale rendering
            SetScaleRendering1(e_input, child, e_li);

            e_li.appendChild(e_img);
            e_li.appendChild(e_input);
            e_li.appendChild(e_li_text);

            //Set nodisplay layers
            if (child.name.indexOf("nodisplay") != -1) {
                e_li.style.display = 'none';
            }

            //recursive call
            if (child.subLayerIds != null) {
                AppendChildren(layers, child, e_li, parentChecked);
            }

            e_ul.appendChild(e_li);
        }

        root.appendChild(e_ul);
    }


    //Visibility
    function UpdateTOC(element) {
        var layer = GetLayerByID(element.id);

        if (layer.subLayerIds != null) {
            for (subLyrID in layer.subLayerIds) {
                var subID = layer.subLayerIds[subLyrID];
                var subLayer = GetLayerByID(subID);
                var subItem = document.getElementById(subID);

                if (element.checked && (!element.disabled)) {
                    //Enable
                    subItem.disabled = false;
                    subItem.parentNode.className = liRootLegend;

                    //Account for scale rendering
                    SetScaleRendering(subItem, subLayer);
                } else {
                    subItem.disabled = true;
                    subItem.parentNode.className = liRootLegendDisabled;
                }

                //Recursive call
                UpdateTOC(subItem);
            }

        }
    }

    function UpdateLayerVisibility(element) {
        if (element != null) {
            UpdateTOC(element);
        }

        var visible = [];
        for (lyr in layers) {
            var layer = layers[lyr];
            var item = document.getElementById(layer.id);

            if (item.checked && (!item.disabled)) {
                if (layer.subLayerIds == null) {
                    visible.push(layer.id);
                }
            }
        }

        if (visible.length > 0) {
            esriMap.setVisibleLayers(visible);
        } else {
            esriMap.setDefaultVisibleLayers();
            //esriMap.setVisibleLayers([999]);
        }
    }

    //Scale Rendering
    function UpdateScaleRendering() {
        for (lyr in layers) {
            var layer = layers[lyr];
            var item = document.getElementById(layer.id);

            if (layer.parentLayerId == -1) {
                //Scale rendering
                SetScaleRendering(item, layer);

                //
                if (layer.subLayerIds != null) {
                    UpdateScaleRenderingChildren(layers, layer, item.checked, item.disabled);
                }
            }
        }
        UpdateLayerVisibility(null);
    }

    function UpdateScaleRenderingChildren(layers, layer, parentChecked, parentDisabled) {
        var childLayers = FindChildren(layers, layer);

        for (childLayer in childLayers) {
            var child = childLayers[childLayer];
            var item = document.getElementById(child.id);

            //Enable/disable based on parent
            if ((!parentChecked) || parentDisabled) {
                item.disabled = true;
                item.parentNode.className = liRootLegendDisabled;
            } else {
                item.disabled = false;
                item.parentNode.className = liRootLegendDisabled;
                //Scale rendering
                SetScaleRendering(item, child);
            }

            //recursive call
            if (child.subLayerIds != null) {
                UpdateScaleRenderingChildren(layers, child, item.checked, item.disabled);
            }

        }
    }

    function SetScaleRendering(item, layer) {
        if (layer.minZoom != 0) {
            if (layer.minZoom >= cosgis.map.getZoom()) {
                item.disabled = true;
            } else {
                item.disabled = false;
            }
        }
        if (layer.maxZoom != 0) {
            if (layer.maxZoom <= cosgis.map.getZoom()) {
                item.disabled = true;
            } else {
                item.disabled = false;
            }
        }

        if (item.disabled)
            item.parentNode.className = liRootLegendDisabled;
        else
            item.parentNode.className = liRootLegend;

    }

    function SetScaleRendering1(item, layer, parentItem) {
        if (layer.minZoom != 0) {
            if (layer.minZoom >= cosgis.map.getZoom()) {
                item.disabled = true;
                parentItem.className = liRootLegendDisabled;
            } else {
                item.disabled = false;
                parentItem.className = liRootLegend;
            }
        }
        if (layer.maxZoom != 0) {
            if (layer.maxZoom <= cosgis.map.getZoom()) {
                item.disabled = true;
                parentItem.className = liRootLegendDisabled;
            } else {
                item.disabled = false;
                parentItem.className = liRootLegend;
            }
        }
    }


    //Toggle
    function ToggleTOC(imgElement) {
        var parent = imgElement.parentNode;
        var ulNode = parent.parentNode;
        var node = parent.firstChild;
        var inputNode = parent.childNodes[1];
        var layer = GetLayerByID(inputNode.id);

        while (node != null) {
            if (node.id != "ulLegend" + layer.id) {
                if (node.tagName == 'OL' || node.tagName == 'UL') {
                    if (node.className == 'closed') {
                        node.style.display = '';
                        node.className = 'open';
                        imgElement.src = imgMinus;
                        imgElement.className = 'minus';
                        if (layer.subLayerIds != null && layer.parentLayerId > -1) {
                            node.style.display = 'none';
                        }
                    } else {
                        node.style.display = 'none';
                        node.className = 'closed';
                        imgElement.src = imgPlus;
                        imgElement.className = 'plus';
                    }
                }
            }
            node = node.nextSibling;
        }

        //Get legend image
        if (layer.subLayerIds == null) {
            ToggleLegend(imgElement, parent, layer.id, null);
        } else {
            if (layer.subLayerIds != null && layer.parentLayerId > -1) {
                ToggleLegend(imgElement, parent, layer.id, layer.subLayerIds);
            }
        }

    }

    function ToggleLegend(imgElement, parentElement, layerID, subIds) {
        //alert(imgElement.className);
        var child_e = document.getElementById("ulLegend" + layerID);
        //if (imgElement.className == 'plus') {
        if (!child_e) {
            //Create elements
            var e_ul = document.createElement('ul');
            e_ul.id = "ulLegend" + layerID;
            var e_li = document.createElement('li');
            var e_img = document.createElement('img');

            //legend image
            var legend;
            if (subIds != null) {
                legend = GetCompositeLegendImage(subIds);
            } else {
                legend = GetSimpleLegendImage(layerID);
            }
            e_img.src = legend;
            e_img.id = "legend" + layerID;

            //Append nodes
            e_li.appendChild(e_img);
            e_ul.appendChild(e_li);
            parentElement.appendChild(e_ul);
            //Toggle plus/minus
            imgElement.src = imgMinus;
            imgElement.className = 'minus';
        } else {
            imgElement.src = imgPlus;
            imgElement.className = 'plus';
            child_e = document.getElementById("ulLegend" + layerID);
            if (child_e)
                parentElement.removeChild(child_e);
        }
    }

    function GetSimpleLegendImage(layerID) {
        return 'legend.ashx?type=single&layerID=' + layerID + '&op=' + _legOpacity + '&url=' + url;
    }

    function GetCompositeLegendImage(layerIDs) {
        return 'legend.ashx?type=comp1&lyrs=' + layerIDs + '&op=' + _legOpacity + '&url=' + url;
    }


    //Layer
    function FindChildren(layers, layer) {
        var childLayers = [];
        for (lyr in layers) {
            if (layers[lyr].parentLayerId == layer.id) {
                childLayers.push(layers[lyr]);
            }
        }
        return childLayers;
    }

    function FindParents(layers, layer) {
        var parentLayers = [];
        for (lyr in layers) {
            if (layers[lyr].id == layer.parentLayerId) {
                parentLayers.push(layers[lyr]);
            }
            if (layers[lyr].parentLayerId > -1)
                FindParents(layers, layers[lyr]);
        }
        return childLayers;
    }

    function ParentLayerChecked(layer) {
        if (layer.parentLayerId > -1) {
            var parent = document.getElementById(layer.parentLayerId);
            if (parent.checked)
                return true;
            else
                return false;
        } else {
            return true;
        }
    }

    function ParentLayerDisabled(layer) {
        if (layer.parentLayerId > -1) {
            var parent = document.getElementById(layer.parentLayerId);
            if (parent.disabled)
                return true;
            else
                return false;
        } else {
            return false;
        }
    }

    function GetLayerByID(id) {
        for (lyr in layers) {
            var layer = layers[lyr];
            if (layer.id == id) {
                return layer;
            }
        }
        return false;
    }

    function GetLayerByName(name) {
        for (lyr in layers) {
            var layer = layers[lyr];
            if (layer.name == name) {
                return layer;
            }
        }
        return false;
    }

    function GetLayerIDByName(name) {
        for (lyr in layers) {
            var layer = layers[lyr];
            if (layer.name == name) {
                return layer.id;
            }
        }
        return -1;
    }

    function GetVisibleLayers() {
        var visible = [];
        for (lyr in layers) {
            var layer = layers[lyr];
            var item = document.getElementById(layer.id);

            if (item.checked && (!item.disabled)) {
                if (layer.subLayerIds == null) {
                    visible.push(layer.id);
                }
            }
        }

        return visible;
    }

}

