﻿if (!Poseidon.Controls) {
    Poseidon.Controls = {};
}

Poseidon.Controls.LayerSwitcher = Ext.extend(Ext.Window, {
    layout: 'fit',
    resizable: true,
    collapsible: true,
    closeAction: 'hide',
    shadow: false,
    plain: true,


    initComponent: function () {
        this.layerNodes = [];

        this.map.events.register('zoomend', this, this.toggleLayerAccessability);

        var layerTreeRoot = this.createLayerTree();

        var LayerSwitcherTree = new Ext.tree.TreePanel(
        {
            border: true,
            autoScroll: true,
            root: layerTreeRoot,
            rootVisible: false,
            lines: true,
            enableDD: false,
            listeners: {
                checkChange: function (node, checked) {
                    var tree = node.getOwnerTree();
                    var source = false;
                    if (!node.getOwnerTree().searchDirection) {
                        source = true;
                        tree.searchDirection = 'down';
                    }

                    // Check downstream.
                    if (tree.searchDirection === 'down') {
                        // Validate all my children.
                        for (var i = 0; i < node.childNodes.length; i++) {
                            var childNode = node.childNodes[i];
                            // Ignore base layers.
                            if (childNode.attributes.nodeType !== 'gx_baselayer') {
                                node.childNodes[i].getUI().toggleCheck(checked);
                            }
                        }
                    }

                    if (source === true) {
                        tree.searchDirection = 'up';
                    }

                    // Check upstream.
                    if (tree.searchDirection === 'up') {
                        var allSistersChecked = true;
                        if (node.parentNode) {
                            // Determine if any of the sisters are false.
                            for (var i = 0; i < node.parentNode.childNodes.length; i++) {
                                var sisterNode = node.parentNode.childNodes[i];
                                // Base layers doesn't count.
                                if (sisterNode.attributes.nodeType !== 'gx_baselayer' &&
                                sisterNode.getUI().isChecked() === false) {
                                    allSistersChecked = false;
                                    break;
                                }
                            }

                            // Set the parent to true if all childrens are true, or false.
                            node.parentNode.getUI().toggleCheck(allSistersChecked);
                        }
                    }

                    if (source === true) {
                        tree.searchDirection = undefined;
                    }
                },
                dblClick: function (node, event) {
                    var a = 1;
                },
                scope: this
            }
        });

        this.controls = {
            LayerSwitcherTree: LayerSwitcherTree
        }

        this.items = [
            LayerSwitcherTree
        ];

        Poseidon.Controls.LayerSwitcher.superclass.initComponent.apply(this, arguments);
    },

    createLayerTree: function () {

        var rootGroup;

        for (var i = 0; i < this.layerGroups.length; i++) {
            if (this.layerGroups[i].parentID === 0) {
                rootGroup = this.layerGroups[i];
            }
        }

        return this.createTreeNode(rootGroup);
    },


    createTreeNode: function (group) {
        var folders = [];
        var layers = [];

        for (var i = 0; i < this.layerGroups.length; i++) {
            //Does the group have any folder children
            if (this.layerGroups[i].parentID === group.ID) {

                folders.push(this.createTreeNode(this.layerGroups[i]));
            }
        }

        for (var i = 0; i < this.layerGroupReferences.length; i++) {
            if (this.layerGroupReferences[i].layerGroupID === group.ID) {
                var layerNode = this.createLayerNode(this.layerGroupReferences[i]);
                layers.push(layerNode);
                this.layerNodes.push(layerNode);
            }
        }

        // Determine if any overlays are among the layers and if any of them are not checked.
        var allChecked = true;
        var hasOverlayChildren = false;
        for (var i = 0; i < layers.length; i++) {
            if (layers[i].attributes.nodeType === 'gx_layer') {
                hasOverlayChildren = true;
                // Check if the layer is NOT visible.
                if (layers[i].attributes.layer.visibility === false) {
                    allChecked = false;
                }
            }
        }

        var useCheckbox = hasOverlayChildren;
        if (!useCheckbox) {
            for (var i = 0; i < folders.length; i++) {
                if (folders[i].attributes.checked) {
                    useCheckbox = true;
                    if (folders[i].attributes.checked === false) {
                        allChecked = false;
                    }
                }
            }
        }

        var root = new Ext.tree.TreeNode(
        {
            text: group.title,
            cls: 'x-tree-node-collapsed',
            checked: useCheckbox === true ? allChecked : undefined
        });

        root.appendChild(folders);
        root.appendChild(layers);

        return root;
    },

    createLayerNode: function (layerReference) {

        var layer = layerReference.layer;

        if (layer) {
            var node = new GeoExt.tree.LayerNode({
                nodeType: layer.isBaseLayer ? 'gx_baselayer' : 'gx_layer',
                leaf: true,
                //id: 'layer_' + layerReferenceID,
                iconCls: layer.options["legend"] ? null : 'icon-map',
                icon: layer.options["legend"] ? layer.options['legend'] : '/Images/Icons/map.png',
                text: layer.name,
                layer: layer
            });

            return node;
        }

    },

    collapseAll: function (node) {
        if (node.hasChildNodes()) {
            for (var i = 0; i < node.childNodes.length; i++) {
                this.collapseAll(node.childNodes[i]);
            }
            node.collapse();
        }
    },

    expandAll: function (node) {
        if (node.hasChildNodes()) {
            node.expand();
            for (var i = 0; i < node.childNodes.length; i++) {
                this.expandAll(node.childNodes[i]);
            }
        }
    },

    toggleLayerAccessability: function () {
        var currentZoomID = this.map.zoom;
        var currentZoomValue = this.map.getResolutionForZoom(currentZoomID);
        // Go through the list of LayerNode
        for (var i = 0; i < this.layerNodes.length; i++) {
            var currentLayerNode = this.layerNodes[i];

            // If a node was found, work on it.
            if (currentLayerNode) {
                // If the current zoom level is greater than the one for the current layer,
                // then hide the layer and disable it from the list.                
                var minResolution = currentLayerNode.layer.minResolution;
                var maxResolution = currentLayerNode.layer.maxResolution;

                if (currentZoomValue >= minResolution && currentZoomValue <= maxResolution) {
                    currentLayerNode.enable();
                } else {
                    currentLayerNode.disable();
                }
            }
        }
    },

    hide: function () {
        // Call parent hide.
        Poseidon.Controls.LayerSwitcher.superclass.hide.call(this);
        if (Ext.getCmp(this.toolbar_item).pressed) {
            Ext.getCmp(this.toolbar_item).toggle();
        }
    },

    show: function () {
        // Call parent show.
        Poseidon.Controls.LayerSwitcher.superclass.show.call(this);
        // Expand and collapse the tree - to make sure that a check propagates throught the children.
        this.expandAll(this.controls.LayerSwitcherTree.getRootNode());
        this.collapseAll(this.controls.LayerSwitcherTree.getRootNode());

        // Move the window.
        this.alignTo(Ext.getBody(), this.alignWindowPosition + "-" + this.alignBodyPosition, [this.alignOffsetX, this.alignOffsetY]);
    }
});
