define([
                                "dojo/_base/declare",
                                "dojo/on",
                                "dojo/json",
                                "dojo/dom",
                                "dojo/dom-class",
                                "dojo/dom-style",
                                "dojo/dom-construct",
                                "dojo/_base/Deferred",
                                "dojo/query",
                                "dijit/registry",
                                "dijit/form/HorizontalSlider",
                                "xstyle/css!Hud.Affht/Tools/AffhtTools.css"
                            ],
                            function (
                                declare,
                                on,
                                JSON,
                                dom,
                                domClass,
                                domStyle,
                                domConstruct,
                                Deferred,
                                query,
                                registry,
                                HorizontalSlider) {
                            
                                return declare(null, {
                                    //properties
                                    map: null,
                                    opacitySliders: [],
                                    containid: null,
                            
                                    /**
                            	     * Constructs a new AffhtTocController class.
                            	     * A user interface control that displays an interactive ArcGIS map.
                                     *
                                     * @class AffhtToolsController
                                     * @constructor
                            	     */
                                    constructor: function (options) {
                                        this.map = options.map;
                                        this.containid = options.containid;
                                        this.initialize(options);
                                    },
                            
                                    /**
                                       * @method initialize
                                       * @param {Object} options   
                                       */
                                    initialize: function (options) {
                            
                                        var self = this;
                                        //build the toc html
                                        var layer, checked,
                                            tocHtml = "<table>";
                                        var layerarray = [];
                                        for (var j = self.map.graphicsLayerIds.length - 1; j > -1; j--) {
                                            if (self.map.graphicsLayerIds[j] == "affht-graphics-layer") continue;
                                            layer = self.map.getLayer(self.map.graphicsLayerIds[j]);
                                            checked = ""
                                            if (layer.visible === true) checked = "checked";
                            
                                            tocHtml += "<tr id=\"toc-row-" + layer.id + "\"><td><input id=\"cb-toc-" + layer.id + "\" type=\"checkbox\" class=\"affht-toc-check\" " + checked + " value=\"" + layer.id + "\"/>&nbsp;&nbsp;</td><td class=\"affht-toc-label\">" + layer.name + "</td></tr>";
                                            tocHtml += "<tr id=\"slider-row-" + layer.id + "\"><td></td><td><div id=\"slider-" + layer.id + "\"></td></tr>";
                                            if (layer._isDotDensity === true) {
                            
                                                var fields = layer.renderer.fields,
                                                    aliasFields;
                                                //special field aliases set from the database
                                                if (layer._dotDensityTocFields) { aliasFields = layer._dotDensityTocFields; }
                                                else {
                                                    //get the field alias from the layer
                                                    aliasFields = [];
                                                    for (var i = 0, _len = fields.length; i < _len; i++) {
                                                        for (var h = 0, __len = layer.fields.length; h < __len; h++) {
                                                            if (layer.fields[h].name === fields[i].name) {
                                                                aliasFields.push({ name: layer.fields[h].alias });
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                            
                                                tocHtml += '<tr><td></td><td>';
                                                for (var x = 0, len = fields.length; x < len; x++) {
                                                    var fInfo = fields[x],
                                                        alias = ((aliasFields) ? aliasFields[x].name : fields[x].name);
                                                    
                                                    tocHtml +=
                                                        '<div>' +
                                                            '<input id="legendField' + x.toString() + '" type="checkbox" class="toc-dd-check" layerid="' + layer.id + '" value="' + fInfo.name + '" checked />&nbsp;' +
                                                            '<span>' + alias + '</span>' +
                                                        '</div>';
                                                }
                            
                                                tocHtml += '</td></tr>';
                                            }
                                            layerarray.push(layer.id);
                            
                                            //toggle opacity and disable checkbox on visibility
                                            layer.on("scale-visibility-change", function (e) {
                                                if (e.target.visibleAtMapScale === true) {
                                                    domStyle.set("toc-row-" + e.target.id, "opacity", "1");
                                                    domStyle.set("slider-row-" + e.target.id, "opacity", "1");
                                                    document.getElementById("cb-toc-" + e.target.id).disabled = false;
                                                    document.getElementById("cb-toc-" + e.target.id).checked = true;
                                                    document.getElementById("affht-dotdensity-dotvalue").disabled = false;
                                                    domStyle.set("dot-contain", "opacity", "1");
                                                }
                                                else {
                                                    domStyle.set("toc-row-" + e.target.id, "opacity", "0.5");
                                                    domStyle.set("slider-row-" + e.target.id, "opacity", "0.5");
                                                    document.getElementById("cb-toc-" + e.target.id).disabled = true;
                                                    document.getElementById("cb-toc-" + e.target.id).checked = false;
                                                    document.getElementById("affht-dotdensity-dotvalue").disabled = true;
                                                    domStyle.set("dot-contain", "opacity", "0.5");
                                                }
                                            });
                            
                                            if (layer._isDotDensity === true) {
                                                layer.on('visibility-change', function (e) {
                                                    if (e.target.visible === true) {
                                                        query('.toc-dd-check').removeAttr('disabled');
                                                    }
                                                    else {
                                                        query('.toc-dd-check').attr('disabled', 'true');
                                                    }
                                                });
                                            }
                                        }
                                        tocHtml += "</table>";
                            
                                        //destroy the existing toc and it's dijits
                                        for (var i = 0, _l = this.opacitySliders.length; i < _l; i++) {
                                            this.opacitySliders[i][0].destroy();
                                        }
                                        this.opacitySliders = [];
                            
                                        //inject the new toc
                                        domConstruct.place(tocHtml, self.containid, "only");
                            
                                        //setup check event
                                        var nl = query(".affht-toc-check");
                                        nl.on("click", function (evt) {
                                            var layerId = evt.target.value;
                            
                                            var layer = self.map.getLayer(layerId);
                                            layer.setVisibility(evt.target.checked);
                                        });
                            
                                        //setup dot density check event
                                        var nl = query('.toc-dd-check');
                                        nl.on('click', function (e) {
                                            var layerId = e.target.attributes.layerid.value,
                                                fieldName = e.target.value,
                                                checked = e.target.checked;
                                            var layer = self.map.getLayer(layerId);
                            
                                            layer._dotDensityTocCallback(fieldName, checked);
                                        });
                            
                                        for (var s = 0; s < layerarray.length; s++) {
                                            self.createslider(layerarray[s]);
                                        }
                                    },
                            
                                    createslider: function (layerid) {
                                        var self = this;
                                        var mylayer = self.map.getLayer(layerid);
                                        var sliderid = "slider-" + layerid;
                            
                                        try {
                                            var _slider = registry.byId(sliderid);
                                            if (_slider) { _slider.destroy(); }
                                        }
                                        catch (e) { }
                            
                                        var slider = new HorizontalSlider({
                                            name: "",
                                            value: mylayer.opacity,
                                            minimum: 0,
                                            maximum: 1,
                                            intermediateChanges: true,
                                            style: "width:200px;",
                                            onChange: function (value) {
                            
                                                mylayer.setOpacity(value);
                                            }
                                        }, sliderid);
                                        slider.startup();
                            
                                        domClass.add(sliderid, "claro");
                            
                                        this.opacitySliders.push([slider, sliderid]);
                                    },
                                });
                            });