///////////////////////////////////////////////////////////////////////////
// Copyright © Esri. All Rights Reserved.
//
// Licensed under the Apache License Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////

define(['dojo/_base/declare',
  'dojo/_base/lang',
  'dojo/_base/html',
  'dojo/_base/array',
  "dojo/_base/json",
  "dojo/dom",
  'dojo/on',
  'dojo/promise/all',
  'dijit/_WidgetsInTemplateMixin',
  "dijit/form/Textarea",
  "dijit/form/SimpleTextarea",
  "dijit/form/Button",
  "esri/geometry/Extent",
  "esri/geometry/Point",
  "esri/geometry/webMercatorUtils",
  'esri/symbols/SimpleMarkerSymbol',
  'esri/symbols/SimpleLineSymbol',
  'esri/symbols/SimpleFillSymbol',
  'esri/symbols/jsonUtils',
  "esri/tasks/PrintTask",
  "esri/tasks/PrintParameters",
  'esri/tasks/GPMessage',
  'esri/tasks/Geoprocessor',
  'esri/tasks/JobInfo',
  "esri/tasks/GeometryService",
  'esri/graphicsUtils',
  "esri/SpatialReference",
  'esri/Color',
  'esri/request',
  'jimu/dijit/Message',
  'jimu/utils',
  'jimu/BaseWidget',
  'jimu/WidgetManager',
  'jimu/dijit/ViewStack',
  'jimu/dijit/FeatureSetChooserForMultipleLayers',
  'jimu/LayerInfos/LayerInfos',
  'jimu/SelectionManager',
  'jimu/dijit/FeatureActionPopupMenu',
  './layerUtil',
  './SelectableLayerItem',
  './FeatureItem',
  'jimu/dijit/LoadingShelter'
],
function (declare, lang, html, array, JSON, dom, on, all, _WidgetsInTemplateMixin, Textarea, SimpleTextarea, Button, Extent, Point, webMercatorUtils, SimpleMarkerSymbol,
SimpleLineSymbol, SimpleFillSymbol, SymbolJsonUtils, PrintTask, PrintParameters, GPMessage, Geoprocessor, JobInfo, GeometryService, graphicsUtils,
SpatialReference, Color, esriRequest, Message, utils, BaseWidget, WidgetManager, ViewStack,
FeatureSetChooserForMultipleLayers, LayerInfos, SelectionManager, PopupMenu, layerUtil,
SelectableLayerItem, FeatureItem) {
    return declare([BaseWidget, _WidgetsInTemplateMixin], {
        baseClass: 'jimu-widget-ExistCondWidget',
        messageInterval: null,
        jodId: '',

        postMixInProperties: function () {
            this.inherited(arguments);
            lang.mixin(this.nls, window.jimuNls.common);
        },

        postCreate: function () {
            this.inherited(arguments);
            var selectionColor = new Color(this.config.selectionColor);
            this.defaultPointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,
          16, null, selectionColor);
            this.defaultLineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
          selectionColor, 2);
            this.defaultFillSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
          this.defaultLineSymbol,
          new Color([selectionColor.r, selectionColor.g, selectionColor.b, 0.3]));
            this.popupMenu = PopupMenu.getInstance();
            /**
            * Helper object to keep which layer is selectable.
            */
            this.layerMapper = {};
            this.layerObjectArray = [];
            this.layerItems = [];
            this.loctxtarea = null;
            this.acctxtarea = null;
            this.notestxtarea = null;
            this.acctHidden = null;
            this.gpButton = null;
            this.item = null;
            this.taskURL = "https://mcatlas.org/arcgis5/rest/services/tools/ExistingConditionsPrintTask/GPServer/ExistingConditionsPrintTask";
            this.sr = new SpatialReference(2248);
            this.gp = new Geoprocessor(this.taskURL);
            this.gp.setOutSpatialReference(this.sr);  // (this.map.spatialReference);
            this.gs = new GeometryService("https://mcatlas.org/arcgis5/rest/services/Utilities/Geometry/GeometryServer");
            this.resultNodes = [];
            //alert("sp = " + this.sr.wkid);
            //Fires when an asynchronous GP task using submitJob is complete.
            this.own(on(this.gp, 'job-complete', lang.hitch(this, this.onJobComplete)));

            this.own(on(this.gp, 'job-cancel', lang.hitch(this, this.onJonCancel)));

            //Fires when a job status update is available.
            this.own(on(this.gp, 'status-update', lang.hitch(this, this.onStatusUpdate)));

            //Fires when the result of an asynchronous GP task execution is available.
            this.own(on(this.gp, 'get-result-data-complete',
                lang.hitch(this, this.onGetResultDataComplate)));

            this.own(on(this.gp, 'error', lang.hitch(this, this.onError)));

            // create select dijit
            this.selectDijit = new FeatureSetChooserForMultipleLayers({
                map: this.map,
                updateSelection: true,
                fullyWithin: this.config.selectionMode === 'wholly',
                geoTypes: this.config.geometryTypes || ['EXTENT']
            });

            html.place(this.selectDijit.domNode, this.selectDijitNode);
            this.selectDijit.startup();

            //alert("select startup");
            //var printTask = new PrintTask();
            //var params = new PrintParameters();
            //params.map = this.map;
            //var Web_Map_as_JSON = JSON.toJson(printTask._getPrintDefinition(this.map, params));
            //alert("json = " + Web_Map_as_JSON);

            this.own(on(this.selectDijit, 'user-clear', lang.hitch(this, this._clearAllSelections)));
            this.own(on(this.selectDijit, 'loading', lang.hitch(this, function () {
                this.shelter.show();
            })));
            this.own(on(this.selectDijit, 'unloading', lang.hitch(this, function () {
                this.shelter.hide();
            })));

            this.viewStack = new ViewStack({
                viewType: 'dom',
                views: [this.layerListNode, this.detailsNode]
            });
            html.place(this.viewStack.domNode, this.domNode);

            this.own(on(this.switchBackBtn, 'click', lang.hitch(this, this._switchToLayerList)));
            if (window.isRTL) {
                html.addClass(this.switchBackIcon, 'icon-arrow-forward');
            } else {
                html.addClass(this.switchBackIcon, 'icon-arrow-back');
            }

            //var spanNotes = dom.byId("notesInstHeader");
            //            var divNotes = dom.byId("notesInst");
            //            var arrowUp = dom.byId("notesArrowUp");
            //            var arrowDown = dom.byId("notesArrowDown");
            this.own(on(this.notesInstHeader, 'click', lang.hitch(this, function () {
                var src = dom.byId("notesArrow").src;
                if (src.indexOf("more2") > -1) {
                    //                if (dom.byId("notesArrowDown").style.display != 'none') {
                    dom.byId("notesInst").style.display = 'block';
                    dom.byId("notesArrow").src = src.replace("more2", "arrow_up");
                    //                    dom.byId("notesArrowDown").style.display = 'none';
                    //                    dom.byId("notesArrowUp").style.display = 'block';
                                    }
                                    else {
                                        dom.byId("notesInst").style.display = 'none';
                                        dom.byId("notesArrow").src = src.replace("arrow_up", "more2");
                    //                    dom.byId("notesArrowDown").style.display = 'block';
                    //                    dom.byId("notesArrowUp").style.display = 'none';
                }
            })));

            this.loctxtarea = new Textarea({
                name: "mylocArea",
                id: "mylocArea",
                value: "",
                readOnly: "readOnly",
                style: "width:90%;height:80px;background-color:#DFDCDC"
            });  //, this.locArea
            html.place(this.loctxtarea.domNode, this.locArea);
            this.loctxtarea.startup();

            this.acctxtarea = new Textarea({
                name: "myacctArea",
                id: "myacctArea",
                value: "",
                readOnly: "readOnly",
                style: "width:90%;min-height:100px;background-color:#DFDCDC"
            });  //, this.locArea
            html.place(this.acctxtarea.domNode, this.acctArea);
            this.acctxtarea.startup();

            this.notestxtarea = new Textarea({
                name: "mynotesArea",
                id: "mynotesArea",
                //cols: "54",
                //rows: "10",
                //wrap: "soft",
                value: "",
                style: "width:90%;height:100px;min-height:100px"
            });  //, this.locArea
            html.place(this.notestxtarea.domNode, this.notesArea);
            this.notestxtarea.startup();

            this.acctHidden = new Textarea({
                name: "myacctHidden",
                id: "myacctHidden",
                value: "",
                style: "width:60%;"
            });  //, this.locArea
            html.place(this.acctHidden.domNode, this.acctAreaHidden);
            this.acctHidden.startup();


            //var urlTask = dom.byId("locText");
            //alert("taskURL = " + this.config.taskURL);

            this._switchToLayerList();

            var layerInfosObject = LayerInfos.getInstanceSync();

            layerUtil.getLayerInfoArray(layerInfosObject).then(lang.hitch(this, function (layerInfoArray) {
                //First loaded, reset selectableLayerIds
                this._initLayers(this._filterLayerInfo(layerInfoArray));
            }));

            this.own(on(layerInfosObject, 'layerInfosChanged', lang.hitch(this, function () {
                this.shelter.show();

                layerUtil.getLayerInfoArray(layerInfosObject)
          .then(lang.hitch(this, function (layerInfoArray) {
              this._initLayers(this._filterLayerInfo(layerInfoArray));
          }));
            })));

            this.own(on(layerInfosObject, 'layerInfosIsShowInMapChanged',
        lang.hitch(this, this._layerVisibilityChanged)));

            this.own(on(this.map, 'zoom-end', lang.hitch(this, this._layerVisibilityChanged)));
            this.own(on(this.settingNode, 'click', lang.hitch(this, function (event) {
                event.stopPropagation();
                var position = html.position(event.target);
                this.showPopup(position);
            })));

            //this._turnOnAllLayers();
        },

        showPopup: function (position) {
            var actions = [{
                iconClass: 'no-icon',
                label: this.nls.turnonAll,
                data: {},
                onExecute: lang.hitch(this, this._turnOnAllLayers)
            },
      {
          iconClass: 'no-icon',
          label: this.nls.turnoffAll,
          data: {},
          onExecute: lang.hitch(this, this._turnOffAllLayers)
      },
      {
          iconClass: 'no-icon',
          label: this.nls.toggleSelect,
          data: {},
          onExecute: lang.hitch(this, this._toggleAllLayers)
      }];
            this.popupMenu.setActions(actions);
            this.popupMenu.show(position);
        },

        onDeActive: function () {
            if (this.selectDijit.isActive()) {
                this.selectDijit.deactivate();
            }
            this._restoreSelectionSymbol();
        },

        onActive: function () {
            this._setSelectionSymbol();
        },

        onOpen: function () {
            WidgetManager.getInstance().activateWidget(this);
        },

        onDestroy: function () {
            if (this.selectDijit.isActive()) {
                this.selectDijit.deactivate();
            }
            this._clearAllSelections();
        },

        _onExecuteClick: function () {
            //alert("url = " + window.location + " w = " + window.innerWidth + " h = " + window.innerHeight);
            if (html.hasClass(this.exeNode, 'jimu-state-disabled')) {
                return;
            }
            var selectedFeatures = this.layerObjectArray[0].getSelectedFeatures();
            if (selectedFeatures.length == 0) {
                alert("Please click the Select button and choose a Parcel on the map");
                return;
            }
            var res = confirm("COMCOR:  Section C:\n " +
 "A waiver from the requirement to provide a Natural Resources Inventory with an exemption request may be granted for:\n" +
      "(1)   single lot exemptions per subsection 22A-5(a) of the Forest Conservation Law if a site plan which shows existing and proposed topography and forest boundaries is submitted with the exemption request; and\n" +
      "(2)   applications for other exemptions, if the site being developed does not contain any forest or natural features, and a plan showing existing features and topography is submitted with the exemption request.")
            if (res == true)
                this.executeGP();
        },

        executeGP: function () {
            this._clearLastResult();
            html.addClass(this.exeNode, 'jimu-state-disabled');
            dom.byId("pdfURL").href = "";
            //dom.byId("pdfURL").style = "display:none";
            dom.byId("pdfURL").innerHTML = "";
            this.shelter.show();
            //this.layerItems.push(item);
            //            this.layerObjectArray.push(layerObject);
            var selectedFeatures = this.layerObjectArray[0].getSelectedFeatures();
            if (selectedFeatures.length > 0) {
                //alert("widget.js acct = " + selectedFeatures[0].attributes.ACCT + " , " + this.taskURL + " , " + this.sr.wkid);
                var selExtent = graphicsUtils.graphicsExtent(selectedFeatures);
                //alert("ext = " + selExtent.xmin + " , " + selExtent.ymin + " , " + selExtent.xmax + " , " + selExtent.ymax + " , " + selExtent.spatialReference.wkid);
                var strExtent = selExtent.xmin + "," + selExtent.ymin + "," + selExtent.xmax + "," + selExtent.ymax;
                //alert("ext = " + dijit.byId("mynotesArea").get("value"));
                //selExtent.setSpatialReference(this.sr);
                //                var point = new Point([selExtent.xmin, selExtent.ymin], new SpatialReference({ wkid: this.map.spatialReference.wkid }));
                //                if (webMercatorUtils.canProject(point, this.sr)) {
                //                    selExtent2 = webMercatorUtils.project(selExtent, this.sr);
                //                    alert("ext2 = " + selExtent2.xmin + " , " + selExtent2.ymin + " , " + selExtent2.xmax + " , " + selExtent2.ymax + " , " + selExtent2.spatialReference.wkid);
                //                }
                //                else
                //                    alert("can not project");
                //                var sr = new SpatialReference(102685);
                //                var project = this.gs.project(point, sr);
                //                project.then(this.success, this.failure);

                //                var extent = new Extent({
                //                    "xmin": 13075362, "ymin": 485690, "xmax": 1308617, "ymax": 486955,
                //                    "spatialReference": { "wkid": 2248 }
                //                });
                //var Web_Map_as_JSON = JSON.toJson(printTask._getPrintDefinition(this.map, params));
                var params = {
                    //"Web_Map_as_JSON": Web_Map_as_JSON,
                    //"Feature_Set": selectedFeatures[0].geometry,
                    "Location": dijit.byId("mylocArea").get("value"),
                    "Acct": dijit.byId("myacctArea").get("value"),
                    "Acct_Actual": dijit.byId("myacctHidden").get("value"),
                    "Notes": dijit.byId("mynotesArea").get("value"),
                    "Selected_Extent": strExtent
                };
                //this.gp.submitJob(params);
                //alert("subnitted");
                //array.forEach(selectedFeatures, lang.hitch(this, function (feature) {

                //alert("clicked " + this.item.onItemSelected(selectedFeat));
                //            this._getInputParamValues().then(lang.hitch(this, function (inputValues) {
                //                this._showLoading();

                // Send a request to service url to make it added to corsEnabledServers.
                esriRequest({
                    url: this.taskURL,
                    content: {
                        f: 'json'
                    },
                    handleAs: "json",
                    callbackParamName: 'callback'
                }).then(lang.hitch(this, function () {
                    //                        if (this.config.isSynchronous) {
                    //                            this.gp.execute(inputValues);
                    //                            this.infoTextNode.innerHTML = this.nls.executing;
                    //                        } else {
                    //                            var printTask = new PrintTask();
                    //                            var params = new PrintParameters();
                    //                            params.map = this.map;
                    //                            params.outSpatialReference = new SpatialReference(2248);
                    //                            var Web_Map_as_JSON = JSON.toJson(printTask._getPrintDefinition(this.map, params));
                    //                            alert("json = " + Web_Map_as_JSON);
                    //                            console.log(Web_Map_as_JSON);
                    this.gp.submitJob(params);
                    //                        }
                }), lang.hitch(this, function () {
                    html.removeClass(this.exeNode, 'jimu-state-disabled');
                    //                    }));
                }), lang.hitch(this, function () {
                    html.removeClass(this.exeNode, 'jimu-state-disabled');
                }));
            }
        },

        //        success: function (result) {
        //            // console.log("project successful: ", result);
        //            if (result.length) {

        //                //var bounds = result[0];
        //                //b = bounds.extent;
        //                alert("got result ");
        //                //      buildMap(bounds);
        //                //      showInfo(bounds);
        //            } else {
        //                console.log("Project was successful, but no results were returned.");
        //            }
        //        },

        //        failure: function (err) {
        //            alert("Failed, probably an invalid WKID. Check the console for more info.");
        //            //            dom.byId("extent").innerHTML = "Failed, probably an invalid WKID. Check the console for more info.";
        //            //            dom.byId("center").innerHTML = "&nbsp;";
        //            //            console.log("Project failed:  ", err);
        //        },

        onJobComplete: function (jobInfo) {
            this._hideLoading();
            this._clearMessageInterval();
            //this.shelter.hide();
            html.removeClass(this.exeNode, 'jimu-state-disabled');
            //alert("stat = " + jobInfo.jobInfo.jobStatus);
            //onJobComplete is invoked even if jobStatus is STATUS_FAILED.
            //It hides this.infoNode so user can not see the error message!
            if (jobInfo.jobInfo.jobStatus !== JobInfo.STATUS_SUCCEEDED) {
                this._createErrorMessages(jobInfo.jobInfo.messages);
                return;
            }

            //            this._createOutputPlaceholders();

            //            if (this.config.useResultMapServer) {
            //                //only when GP task is async and the GP service publish the result map service,
            //                //the option "useResultMapServer" may be true. This will be guaranteed in builder
            //                var imageParameters = new ImageParameters({
            //                    imageSpatialReference: this.map.spatialReference
            //                });
            //                var resultMapServiceParam = this._getResultMapServiceParam();
            //                if (this.visibleOutputNames.indexOf(resultMapServiceParam.name) >= 0) {
            //                    this.gp.getResultImageLayer(jobInfo.jobInfo.jobId, null, imageParameters);
            //                }
            //                // add outputs whose type is not geo dataset
            //                array.forEach(this.config.outputParams, function (param) {
            //                    if (param.ignore !== true &&
            //            param.dataType !== 'GPFeatureRecordSetLayer' &&
            //            param.dataType !== 'GPRasterDataLayer' &&
            //            param.dataType !== 'GPRecordSet') {
            //                        this.gp.getResultData(jobInfo.jobInfo.jobId, param.name);
            //                    }
            //                }, this);
            //            } else {
            //                array.forEach(this.config.outputParams, function (param) {
            //                    if (param.ignore !== true) {
            this.gp.getResultData(jobInfo.jobInfo.jobId, "Output_File");
            //                    }
            //                }, this);
            //            }
        },

        _clearLastResult: function () {
            html.empty(this.infoTextNode);
            array.forEach(this.resultNodes, function (node) {
                html.destroy(node.labelNode);
                if (node.resultRenderer) {
                    node.resultRenderer.destroy();
                }
                html.destroy(node);
            });
            //            array.forEach(this.resultLayers, function (layer) {
            //                if (layer !== null) {
            //                    this.map.removeLayer(layer);
            //                }
            //            }, this);

            this.resultNodes = [];
            //this.resultLayers = [];
            //this.resultExtentMap = {};
        },

        _createErrorMessages: function (messages) {
            this.infoTextNode.innerHTML = '';

            var ulNode = html.create('ul', {
                'class': 'output-node'
            }, this.outputSectionNode);

            this.resultNodes.push(ulNode);

            array.forEach(messages, lang.hitch(this, function (msg) {
                var msgType = 'normal';
                if (msg.type === GPMessage.TYPE_WARNING) {
                    msgType = 'warning';
                } else if (msg.type === GPMessage.TYPE_ERROR) {
                    msgType = 'error';
                }
                html.create('li', {
                    'class': 'job-message ' + msgType,
                    innerHTML: utils.sanitizeHTML(msg.description)
                }, ulNode);
            }));
        },

        onJonCancel: function () {
            //            this.loading.hide();
            //            this.infoTextNode.innerHTML = 'Canceled';

            //            html.removeClass(this.exeNode, 'jimu-state-disabled');
            //            this._clearMessageInterval();
        },

        onStatusUpdate: function (jobInfo) {
            this.jobId = jobInfo.jobInfo.jobId;
            if (jobInfo.jobInfo.jobStatus === JobInfo.STATUS_SUCCEEDED) {
                this._hideLoading();
                this._clearMessageInterval();
            } else {
                this._showLoading(jobInfo.jobInfo.jobStatus);
            }
            if (!this.messageInterval && this.jobId) {
                this._setupMessageInterval();
            }
        },

        onError: function (error) {
            //this.loading.hide();
            this.shelter.hide();
            html.empty(this.infoTextNode);
            html.create('div', {
                'class': 'job-message error',
                innerHTML: utils.sanitizeHTML(error.error.message)
            }, this.infoTextNode);

            html.removeClass(this.exeNode, 'jimu-state-disabled');
            this._clearMessageInterval();
        },

        _updateJobMessage: function () {
            // Send request to get job messages
            esriRequest({
                url: this.taskURL + '/jobs/' + this.jobId,
                content: {
                    f: 'json',
                    returnMessages: true
                },
                handleAs: "json",
                callbackParamName: 'callback'
            }).then(lang.hitch(this, function (res) {
                if (res.messages && res.messages.length > 0) {
                    html.empty(this.infoTextNode);
                    array.forEach(res.messages, function (message) {
                        var msgType = 'normal';
                        if (message.type === GPMessage.TYPE_WARNING) {
                            msgType = 'warning';
                        } else if (message.type === GPMessage.TYPE_ERROR) {
                            msgType = 'error';
                        }
                        html.create('div', {
                            'class': 'job-message ' + msgType,
                            innerHTML: utils.sanitizeHTML(message.description)
                        }, this.infoTextNode);
                    }, this);
                }
            }));
        },

        _setupMessageInterval: function () {
            this.messageInterval = setInterval(lang.hitch(this, this._updateJobMessage), 3000);
        },

        _clearMessageInterval: function () {
            this.jobId = '';
            if (this.messageInterval) {
                clearInterval(this.messageInterval);
                this.messageInterval = null;
            }
        },


        _showLoading: function () {
            //this.loading.show();
            this.shelter.show();
            html.setStyle(this.infoNode, 'display', 'block');
        },

        _hideLoading: function () {
            html.setStyle(this.infoNode, 'display', 'none');
            //this.loading.hide();
            this.shelter.hide();
        },


        onGetResultDataComplate: function (result) {
            //alert("got result");
            //the result.result contains only one ParameterValue
            //alert("param = " + result.result.paramName + " , " + result.result.value.url);
            dom.byId("pdfURL").href = result.result.value.url;
            dom.byId("pdfURL").style = "color:#B40404;font-size:20px;font-weight:bold;background-color:lightgray";
            dom.byId("pdfURL").innerHTML = "Open PDF";
            //this._updateOutputNode(this._getOutputParamByName(result.result.paramName), result.result);
        },

        _filterLayerInfo: function (layerInfoArray) {
            if (!this.config.layerState) {
                return layerInfoArray;
            }
            var layerInfosObject = LayerInfos.getInstanceSync();
            var webmapLayerInfos = layerInfosObject.getLayerInfoArrayOfWebmap();
            return array.filter(layerInfoArray, lang.hitch(this, function (layerInfo) {
                var inBlackList = this.config.layerState[layerInfo.id] &&
            this.config.layerState[layerInfo.id].selected === false;
                if (!inBlackList) {
                    return true;
                } else if (this.config.includeRuntimeLayers !== false) {
                    return array.every(webmapLayerInfos, function (webmapLayerInfo) {
                        return layerInfo.getRootLayerInfo().id !== webmapLayerInfo.id;
                    });
                }
                return false;
            }));
        },

        _initLayers: function (layerInfoArray) {
            this.layerObjectArray = [];
            this.layerItems = [];
            this.selectionSymbols = {};

            html.empty(this.layerItemsNode);
            this.shelter.show();

            all(this._obtainLayerObjects(layerInfoArray)).then(lang.hitch(this, function (layerObjects) {
                array.forEach(layerObjects, lang.hitch(this, function (layerObject, index) {
                    // hide from the layer list if layerobject is undefined or there is no objectIdField
                    if (layerObject && layerObject.objectIdField && layerObject.geometryType && layerObject.name.toUpperCase().indexOf("PROPERTY_POLY") > -1) {
                        //alert("lyr added = " + layerObject.name + " , ind = " + index);
                        var layerInfo = layerInfoArray[index];
                        var visible = layerInfo.isShowInMap() && layerInfo.isInScale();

                        var item = new SelectableLayerItem({
                            layerInfo: layerInfo,
                            checked: true,   //visible,  Melissa changed to make layer selectable on startup
                            layerVisible: visible,
                            folderUrl: this.folderUrl,
                            allowExport: this.config ? this.config.allowExport : false,
                            map: this.map,
                            nls: this.nls
                        });
                        //this.item = item;
                        this.own(on(item, 'switchToDetails', lang.hitch(this, this._switchToDetails)));
                        this.own(on(item, 'stateChange', lang.hitch(this, function (itemStatus) {
                            this.shelter.show();
                            if ('visible' in itemStatus) {
                                this.selectDijit.setDisplayLayerVisibility(itemStatus.featureLayer, itemStatus.visible);
                            }
                            this.selectDijit.setFeatureLayers(this._getSelectableLayers());
                            this.shelter.hide();
                        })));
                        item.init(layerObject);
                        html.place(item.domNode, this.layerItemsNode);
                        item.startup();

                        this.layerItems.push(item);
                        this.layerObjectArray.push(layerObject);

                        if (!layerObject.getSelectionSymbol()) {
                            this._setDefaultSymbol(layerObject);
                        }

                        var symbol = layerObject.getSelectionSymbol();
                        this.selectionSymbols[layerObject.id] = symbol.toJson();
                    }
                }));
                this.selectDijit.setFeatureLayers(this._getSelectableLayers());
                this._setSelectionSymbol();
                this.shelter.hide();
            }));
        },

        _turnOffAllLayers: function () {
            this.shelter.show();
            array.forEach(this.layerItems, lang.hitch(this, function (layerItem) {
                layerItem.turnOff();
            }));
            this.selectDijit.setFeatureLayers([]);
            this.shelter.hide();
        },

        _turnOnAllLayers: function () {
            alert("turning on");
            this.shelter.show();
            array.forEach(this.layerItems, lang.hitch(this, function (layerItem) {
                layerItem.turnOn();
            }));
            this.selectDijit.setFeatureLayers(this._getSelectableLayers());
            this.shelter.hide();
        },

        _toggleAllLayers: function () {
            this.shelter.show();
            array.forEach(this.layerItems, lang.hitch(this, function (layerItem) {
                layerItem.toggleChecked();
            }));
            this.selectDijit.setFeatureLayers(this._getSelectableLayers());
            this.shelter.hide();
        },

        _setSelectionSymbol: function () {
            array.forEach(this.layerObjectArray, function (layerObject) {
                this._setDefaultSymbol(layerObject);
            }, this);
        },

        _setDefaultSymbol: function (layerObject) {
            if (layerObject.geometryType === 'esriGeometryPoint' ||
          layerObject.geometryType === 'esriGeometryMultipoint') {
                layerObject.setSelectionSymbol(this.defaultPointSymbol);
            } else if (layerObject.geometryType === 'esriGeometryPolyline') {
                layerObject.setSelectionSymbol(this.defaultLineSymbol);
            } else if (layerObject.geometryType === 'esriGeometryPolygon') {
                layerObject.setSelectionSymbol(this.defaultFillSymbol);
            } else {
                console.warn('unknown geometryType: ' + layerObject.geometryType);
            }
        },

        _restoreSelectionSymbol: function () {
            array.forEach(this.layerObjectArray, function (layerObject) {
                var symbolJson = this.selectionSymbols[layerObject.id];
                if (symbolJson) {
                    layerObject.setSelectionSymbol(SymbolJsonUtils.fromJson(symbolJson));
                }
            }, this);
        },

        _layerVisibilityChanged: function () {
            array.forEach(this.layerItems, function (layerItem) {
                layerItem.updateLayerVisibility();
            }, this);
        },

        _getSelectableLayers: function () {
            var layers = [];
            array.forEach(this.layerItems, function (layerItem) {
                if (layerItem.isLayerVisible() && layerItem.isChecked()) {
                    layers.push(layerItem.featureLayer);
                }
            }, this);

            return layers;
        },

        _clearAllSelections: function () {
            var selectionMgr = SelectionManager.getInstance();
            array.forEach(this.layerObjectArray, function (layerObject) {
                selectionMgr.clearSelection(layerObject);
            });
        },

        _obtainLayerObjects: function (layerInfoArray) {
            return array.map(layerInfoArray, function (layerInfo) {
                return layerInfo.getLayerObject();
            });
        },

        _switchToDetails: function (layerItem) {
            //alert("switchtodetails");
            html.empty(this.featureContent);
            this.viewStack.switchView(1);
            this.selectedLayerName.innerHTML = layerItem.layerName;
            this.selectedLayerName.title = layerItem.layerName;

            layerItem.layerInfo.getLayerObject().then(lang.hitch(this, function (layerObject) {
                var selectedFeatures = layerObject.getSelectedFeatures();
                if (selectedFeatures.length > 0) {
                    array.forEach(selectedFeatures, lang.hitch(this, function (feature) {
                        var item = new FeatureItem({
                            graphic: feature,
                            map: this.map,
                            featureLayer: layerObject,
                            displayField: layerObject.displayField,
                            objectIdField: layerObject.objectIdField,
                            allowExport: this.config ? this.config.allowExport : false,
                            nls: this.nls
                        });
                        html.place(item.domNode, this.featureContent);
                        item.startup();
                    }));
                }
            }));
        },

        _switchToLayerList: function () {
            this.viewStack.switchView(0);
        }
    });
});
