Skip to content

Commit

Permalink
bug in switch between planar/geodesic measure
Browse files Browse the repository at this point in the history
The wkid for mercator SpatialReference in esri Js is NOT the EPSG code (3857) but 102100.
  • Loading branch information
jcornet authored Jan 29, 2019
1 parent 9319164 commit 005356e
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -1532,11 +1532,11 @@ function(
};

if (isPolygon) {
result.area = (wkid == 4326 || wkid == 3857) ? geometryEngine.geodesicArea(geometry, areaUnit) : geometryEngine.planarArea(geometry, areaUnit);
result.area = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicArea(geometry, areaUnit) : geometryEngine.planarArea(geometry, areaUnit);
var polyline = this._getPolylineOfPolygon(geometry);
result.length = (wkid == 4326 || wkid == 3857) ? geometryEngine.geodesicLength(polyline, lengthUnit) : geometryEngine.planarLength(polyline, lengthUnit);
result.length = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicLength(polyline, lengthUnit) : geometryEngine.planarLength(polyline, lengthUnit);
} else {
result.length = (wkid == 4326 || wkid == 3857) ? geometryEngine.geodesicLength(geometry, lengthUnit) : geometryEngine.planarLength(geometry, lengthUnit);
result.length = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicLength(geometry, lengthUnit) : geometryEngine.planarLength(geometry, lengthUnit);
}

return result;
Expand Down

2 comments on commit 005356e

@kevinsagis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeremie, you are awesome as always for fast response!~ We all love your widget and use it in all our viewers.

I tried the new widget.js. I am not seeing any measurement now though. Console says:

Uncaught TypeError: Cannot read property 'MeasureSymbol' of undefined
at Object._getTxtGraphic (Widget.js?wab_dv=2.9:1828)
at Object.addMeasure (Widget.js?wab_dv=2.9:1875)
at Object.drawBoxOnDrawEnd (Widget.js?wab_dv=2.9:1407)
at Object. (init.js:64)
at Object.c [as onDrawEnd] (init.js:120)
at Object._onDrawEnd (DrawBox.js?wab_dv=2.9:489)
at Object. (init.js:64)
at Object. (init.js:666)
at Object.c [as onDrawEnd] (init.js:120)
at Object._drawEnd (draw.js:18)
_getTxtGraphic @ Widget.js?wab_dv=2.9:1828
addMeasure @ Widget.js?wab_dv=2.9:1875
drawBoxOnDrawEnd @ Widget.js?wab_dv=2.9:1407
(anonymous) @ init.js:64
c @ init.js:120
_onDrawEnd @ DrawBox.js?wab_dv=2.9:489
(anonymous) @ init.js:64
(anonymous) @ init.js:666
c @ init.js:120
_drawEnd @ draw.js:18
_onMouseUpHandler @ draw.js:31
(anonymous) @ init.js:64
c @ init.js:120
_fire @ init.js:1363
_onDragMouseUpHandler @ init.js:1369
(anonymous) @ init.js:64

@kevinsagis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so I fixed it. I had to insert the additions and subtractions manually. I am guessing there was a slight syntax error in your widget.js. You can use this it works:

///////////////////////////////////////////////////////////////////////////
// Copyright © MAGIS NC. 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.
// limitations under the License.
///////////////////////////////////////////////////////////////////////////
define([
'dojo/_base/declare',
'dijit/_WidgetsInTemplateMixin',
'jimu/BaseWidget',
'dojo/Deferred',
'dojo/aspect',
'dojo/_base/lang',
'dojo/on',
'dojo/_base/html',
'dojo/sniff',
'dojo/_base/Color',
'dojo/_base/array',
'dojo/dom-construct',
'dojo/dom',
'dijit/form/Select',
'dijit/form/NumberSpinner',
'libs/storejs/store',
'esri/config',
'esri/InfoTemplate',
'esri/graphic',
'esri/graphicsUtils',
'esri/layers/GraphicsLayer',
'esri/toolbars/edit',
'esri/units',
'esri/SpatialReference',
'esri/geometry/Polyline',
'esri/geometry/Polygon',
'esri/geometry/geometryEngine',
'esri/geometry/projection',
'esri/symbols/SimpleMarkerSymbol',
'esri/symbols/SimpleLineSymbol',
'esri/symbols/SimpleFillSymbol',
'esri/symbols/TextSymbol',
'esri/symbols/Font',
'jimu/exportUtils',
'jimu/dijit/ViewStack',
'jimu/dijit/SymbolChooser',
'jimu/dijit/DrawBox',
'jimu/dijit/Message',
'jimu/utils',
'jimu/symbolUtils'
],
function(
declare, _WidgetsInTemplateMixin, BaseWidget,
Deferred, aspect, lang, on, html, has, Color, array, domConstruct, dom, Select, NumberSpinner, localStore,
esriConfig, InfoTemplate, Graphic, graphicsUtils, GraphicsLayer, Edit,
esriUnits, SpatialReference, Polyline, Polygon, geometryEngine, projection,
SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol, Font,
exportUtils, ViewStack, SymbolChooser, DrawBox, Message, jimuUtils, jimuSymbolUtils
) {

/*jshint unused: false*/
return declare([BaseWidget, _WidgetsInTemplateMixin], {
    name: 'eDraw',
    baseClass: 'jimu-widget-edraw',

    ////////////////////////////////////////////// GENERAL METHODS //////////////////////////////////////////////////
    ///**
    // * Set widget mode :add1 (type choice), add2 (symbology and attributes choice), edit, list
    // * @param name string Mode
    // *     - add1 : Add drawing (type choice and measure option)
    // *     - add2 : Add drawing (attributes and symbol chooser)
    // *     - edit : Edit drawing (geometry, attributes and symbol chooser)
    // *     - list : List drawings
    // */
    setMode: function(name) {
        this.editorEnableMapPreview(false);
        this.editorActivateGeometryEdit(false);
        this.allowPopup(false);

        switch (name) {
            case 'add1':
                this.setMenuState('add');

                this._editorConfig["graphicCurrent"] = false;

                this.TabViewStack.switchView(this.addSection);

                this.drawBox.deactivate();

                this.setInfoWindow(false);
                this.allowPopup(false);

                break;
            case 'add2':
                this.setMenuState('add', ['add']);

                this._editorConfig["graphicCurrent"] = false;

                this.editorPrepareForAdd(this._editorConfig["defaultSymbols"][this._editorConfig['commontype']]);

                this.TabViewStack.switchView(this.editorSection);

                this.setInfoWindow(false);
                this.allowPopup(false);

                break;
            case 'edit':
                this.setMenuState('edit', ['edit']);
                if (this._editorConfig["graphicCurrent"]) {
                    //prepare editor
                    this.editorPrepareForEdit(this._editorConfig["graphicCurrent"]);

                    //Focus
                    var extent = graphicsUtils.graphicsExtent([this._editorConfig["graphicCurrent"]]);
                    this.map.setExtent(extent.expand(2), true);
                }

                this.TabViewStack.switchView(this.editorSection);

                this.setInfoWindow(false);

                break;
            case 'list':
                this.setMenuState('list');
                this.allowPopup(true);

                //Generate list and
                this.listGenerateDrawTable();
                var nb_draws = this.drawBox.drawLayer.graphics.length;
                var display = (nb_draws > 0) ? 'block' : 'none';
                html.setStyle(this.allActionsNode, 'display', display);
                this.tableTH.innerHTML = nb_draws + ' ' + this.nls.draws;

                //Other params
                this._editorConfig["graphicCurrent"] = false;

                this.TabViewStack.switchView(this.listSection);

                break;
        }
    },

    showMessage: function(msg, type) {
        var class_icon = "message-info-icon";
        switch (type) {
            case "error":
                class_icon = "message-error-icon";
                break;
            case "warning":
                class_icon = "message-warning-icon";
                break;
        }

        var content = '<i class="' + class_icon + '">&nbsp;</i>' + msg;

        new Message({
            message: content
        });
    },

    setMenuState: function(active, elements_shown) {
        if (!elements_shown) {
            elements_shown = ['add', 'list'];
        } else if (elements_shown.indexOf(active) < 0)
            elements_shown.push(active);

        for (var button_name in this._menuButtons) {
            var menu_class = (button_name == active) ? 'menu-item-active' : 'menu-item';
            if (elements_shown.indexOf(button_name) < 0)
                menu_class = "hidden";
            if (this._menuButtons[button_name])
                this._menuButtons[button_name].className = menu_class;
        }
    },

    setInfoWindow: function(graphic) {
        if (!this.map.infoWindow)
            return false;

        if (!graphic) {
            this.map.infoWindow.hide();
            return true;
        }

        if (graphic.geometry.x)
            var center = graphic.geometry;
        else if (graphic.geometry.getCenter)
            var center = graphic.geometry.getCenter();
        else if (graphic.geometry.getExtent)
            var center = graphic.geometry.getExtent().getCenter();
        else
            return false;

        this.map.infoWindow.setFeatures([graphic]);
        this.map.infoWindow.show(center);

    },

    _clickHandler: false,
    allowPopup: function(bool) {
        this.map.setInfoWindowOnClick(bool);

        if (!bool && this._clickHandler) {
            dojo.disconnect(this._clickHandler);
        } else {
            this._clickHandler = this.drawBox.drawLayer.on("click", this._onDrawClick);
        }
    },

    saveInLocalStorage: function() {
        if (!this.config.allowLocalStorage)
            return;
        localStore.set(this._localStorageKey, this.drawingsGetJson());
    },

    getCheckedGraphics: function(returnAllIfNoneChecked) {
        var graphics = [];
        for (var i = 0, nb = this.drawBox.drawLayer.graphics.length; i < nb; i++)
            if (this.drawBox.drawLayer.graphics[i].checked)
                graphics.push(this.drawBox.drawLayer.graphics[i]);

        if (returnAllIfNoneChecked && graphics.length == 0)
            return this.drawBox.drawLayer.graphics;
        return graphics;
    },

    zoomAll: function() {
        var graphics = this.getCheckedGraphics(true);
        var nb_graphics = graphics.length;

        if (nb_graphics < 1)
            return;

        var ext = graphicsUtils.graphicsExtent(graphics);

        this.map.setExtent(ext, true);
        return true;
    },

    copy: function() {
        var graphics = this.getCheckedGraphics(false);
        var nb = graphics.length;

        if (nb == 0) {
            this.showMessage(this.nls.noSelection, 'error');
            return false;
        }

        for (var i = 0; i < nb; i++) {
            var g = new Graphic(graphics[i].toJson()); //Get graphic clone
            g.attributes.name += this.nls.copySuffix; //Suffix name
            this.drawBox.drawLayer.add(g);
            if (graphics[i].measure && graphics[i].measure.graphic) {
                this.addMeasure(g.geometry, g);
            }
        }
        this.setMode("list");
    },

    clear: function() {
        var graphics = this.getCheckedGraphics(false);
        var nb = graphics.length;

        if (nb == 0) {
            this.showMessage(this.nls.noSelection, 'error');
            return false;
        }

        if (this.config.confirmOnDelete) {
            this._confirmDeleteMessage = new Message({
                message: '<i class="message-warning-icon"></i>&nbsp;' + this.nls.confirmDrawCheckedDelete,
                buttons: [{
                    label: this.nls.yes,
                    onClick: this._removeGraphics
                }, {
                    label: this.nls.no
                }]
            });
        } else {
            this._removeGraphics(graphics);
        }
    },

    _removeClickedGraphic: function() {
        if (!this._clickedGraphic)
            return false;

        this._removeGraphic(this._clickedGraphic);
        this._editorConfig["graphicCurrent"] = false;
        this.listGenerateDrawTable();

        this._clickedGraphic = false;

        if (this._confirmDeleteMessage && this._confirmDeleteMessage.close) {
            this._confirmDeleteMessage.close();
            this._confirmDeleteMessage = false;
        }
    },

    _removeGraphics: function(graphicsOrEvent) {
        var graphics = (graphicsOrEvent.target) ? this.getCheckedGraphics(false) : graphicsOrEvent;

        var nb = graphics.length;
        for (var i = 0; i < nb; i++) {
            this._removeGraphic(graphics[i]);
        }

        if (this._confirmDeleteMessage && this._confirmDeleteMessage.close) {
            this._confirmDeleteMessage.close();
            this._confirmDeleteMessage = false;
        }

        this.setInfoWindow(false);
        if(this.drawBox.drawLayer.graphics.length > 0){
          this.setMode("list");
        }
        else{
          this.setMode("add1");
        }
    },

    _removeGraphic: function(graphic) {
        if (graphic.measure && graphic.measure.graphic) {
            // graphic.measure.graphic.measureParent = false; //Remove link between graphic and it's measure label
            this.drawBox.drawLayer.remove(graphic.measure.graphic); //Delete measure label
        } else if (graphic.measureParent) {
            graphic.measureParent.measure = false;
        }
        this.drawBox.drawLayer.remove(graphic);
    },

    drawingsGetJson: function(asString, onlyChecked) {
        var graphics = (onlyChecked) ? this.getCheckedGraphics(false) : this.drawBox.drawLayer.graphics;

        var nb_graphics = graphics.length;

        if (nb_graphics < 1)
            return (asString) ? '' : false;

        var content = {
            "features": [],
            "displayFieldName": "",
            "fieldAliases": {},
            "spatialReference": this.map.spatialReference.toJson(),
            "fields": []
        };

        var features_with_measure = [];
        var nb_graphics_ok = 0;
        for (var i = 0; i < nb_graphics; i++) {
            var g = graphics[i];
            if (g) {
                var json = g.toJson();
                //If with measure
                if (g.measure && g.measure.graphic) {
                    features_with_measure.push(nb_graphics_ok);
                }
                content["features"].push(json);
                nb_graphics_ok++;
            }
        }

        //Replace references for measure's graphic by index
        for (var k = 0, nb = features_with_measure.length; k < nb; k++) {
            var i = features_with_measure[k];
            for (var l = 0, nb_g = graphics.length; l < nb_g; l++) {
                if (graphics[l] == graphics[i].measure.graphic) {
                    content["features"][i]["measure"] = {
                        "areaUnit": graphics[i].measure.areaUnit,
                        "lengthUnit": graphics[i].measure.lengthUnit,
                        "graphic": l
                    };
                    break;
                }
            }
        }

        if (asString) {
            content = JSON.stringify(content);
        }
        return content;
    },

    ///////////////////////// MENU METHODS ///////////////////////////////////////////////////////////
    menuOnClickAdd: function() {
        this.setMode("add1");
    },
    menuOnClickList: function() {
        this.setMode("list");
    },

    onHideCheckboxClick: function() {
        var display = (this.hideCheckbox.checked) ? 'none' : 'block';

        this.drawBox.drawLayer.setVisibility(!this.hideCheckbox.checked);
        this.menu.style.display = display;
        this.settingAllContent.style.display = display;

        if (this.hideCheckbox.checked)
            this.onClose();
        else
            this.onOpen();
    },

    ///////////////////////// LIST METHODS ///////////////////////////////////////////////////////////
    listGenerateDrawTable: function() {
        //Generate draw features table
        var graphics = this.drawBox.drawLayer.graphics;
        var nb_graphics = graphics.length;

        //Table
        this.drawsTableBody.innerHTML = "";

        var name_max_len = (this.config.listShowUpAndDownButtons) ? 8 : 16;

        for (var i = nb_graphics - 1; i >= 0; i--) {
            var graphic = graphics[i];
            var num = i + 1;
            var symbol = graphic.symbol;

            var selected = (this._editorConfig["graphicCurrent"] && this._editorConfig["graphicCurrent"] == graphic);

            if (symbol.type == "textsymbol") {
                var json = symbol.toJson();
                var txt = (json.text.length > 4) ? json.text.substr(0, 4) + "..." : json.text
                var font = (json.font.size < 14) ? 'font-size:' + json.font.size + 'px;' : 'font-size:14px; font-weight:bold;';
                var color = (json.color.length == 4) ? 'rgba(' + json.color.join(",") + ')' : 'rgba(' + json.color.join(",") + ')';
                var symbolHtml = '<span style="color:' + color + ';' + font + '">' + txt + '</span>';
            } else {
                var symbolNode = jimuSymbolUtils.createSymbolNode(symbol, {
                    width: 50,
                    height: 50
                });
                var symbolHtml = symbolNode.innerHTML;
            }
            var name = (graphic.attributes && graphic.attributes['name']) ? graphic.attributes['name'] : '';
            name = (name.length > name_max_len) ? '<span title="' + name.replace('"', '&#34;') + '">' + name.substr(0, name_max_len) + "...</span>" : name;

            var actions = '<span class="edit blue-button" id="draw-action-edit--' + i + '" title="' + this.nls.editLabel + '">&nbsp;</span>' +
                '<span class="clear red-button" id="draw-action-delete--' + i + '" title="' + this.nls.deleteLabel + '">&nbsp;</span>';
            var actions_class = "list-draw-actions light";
            if (this.config.listShowUpAndDownButtons) {
                actions += '<span class="up grey-button" id="draw-action-up--' + i + '" title="' + this.nls.upLabel + '">&nbsp;</span>' +
                    '<span class="down grey-button" id="draw-action-down--' + i + '" title="' + this.nls.downLabel + '">&nbsp;</span>';
                actions_class = "list-draw-actions";
            }
            actions += '<span class="zoom grey-button" id="draw-action-zoom--' + i + '" title="' + this.nls.zoomLabel + '">&nbsp;</span>';

            var checked = (graphic.checked) ? ' checked="checked"' : '';

            var html = '<td><input type="checkbox" class="td-checkbox" id="draw-action-checkclick--' + i + '" ' + checked + '/></td>' +
                '<td>' + name + '</td>' +
                '<td class="td-center" id="draw-symbol--' + i + '">' + symbolHtml + '</td>' +
                '<td class="' + actions_class + '">' + actions + '</td>';
            var tr = domConstruct.create(
                "tr", {
                    id: 'draw-tr--' + i,
                    innerHTML: html,
                    className: (selected) ? 'selected' : '',
                    draggable: "true"
                },
                this.drawsTableBody);

            //Bind actions
            on(dom.byId('draw-action-edit--' + i), "click", this.listOnActionClick);
            on(dom.byId('draw-action-delete--' + i), "click", this.listOnActionClick);
            on(dom.byId('draw-action-zoom--' + i), "click", this.listOnActionClick);
            if (this.config.listShowUpAndDownButtons) {
                on(dom.byId('draw-action-up--' + i), "click", this.listOnActionClick);
                on(dom.byId('draw-action-down--' + i), "click", this.listOnActionClick);
            }
            on(dom.byId('draw-action-checkclick--' + i), "click", this.listOnActionClick);
            on(tr, "dragstart", this._listOnDragStart);
        }
        this.saveInLocalStorage();
        this.listUpdateAllCheckbox();
    },

    _listOnDrop: function(evt) {
        evt.preventDefault();
        var tr_id = evt.dataTransfer.getData("edraw-list-tr-id");

        var target = (evt.target) ? evt.target : evt.originalTarget;
        var target_tr = this._UTIL__getParentByTag(target, "tr");

        //If dropped on same tr, exit !
        if (!target_tr || target_tr.id == tr_id) {
            return false;
        }

        //get positions from id
        var from_i = tr_id.split("--")[tr_id.split("--").length - 1];
        var to_i = target_tr.id.split("--")[target_tr.id.split("--").length - 1];

        //Switch the 2 rows
        this.moveDrawingGraphic(from_i, to_i);
        this.listGenerateDrawTable();
    },

    _listOnDragOver: function(evt) {
        evt.preventDefault();
    },

    _listOnDragStart: function(evt) {
        evt.dataTransfer.setData("edraw-list-tr-id", evt.target.id);
    },

    switch2DrawingGraphics: function(i1, i2) {
        var g1 = this.drawBox.drawLayer.graphics[i1];
        var g2 = this.drawBox.drawLayer.graphics[i2];

        if (!g1 || !g2)
            return false;

        //Switch graphics
        this.drawBox.drawLayer.graphics[i1] = g2;
        this.drawBox.drawLayer.graphics[i2] = g1;

        //Redraw in good order
        var start_i = (i1 < i2) ? i1 : i2;
        this._redrawGraphics(start_i);
        return true;
    },

    moveDrawingGraphic: function(from_i, to_i) {
        from_i = parseInt(from_i);
        to_i = parseInt(to_i);

        if (from_i == to_i)
            return;

        //get from graphic
        var from_graphic = this.drawBox.drawLayer.graphics[from_i];

        //Move graphics up or down
        if (from_i < to_i) {
            for (var i = from_i, nb = this.drawBox.drawLayer.graphics.length; i < to_i && i < nb; i++)
                this.drawBox.drawLayer.graphics[i] = this.drawBox.drawLayer.graphics[i + 1];
        } else {
            for (var i = from_i, nb = this.drawBox.drawLayer.graphics.length; i > to_i && i > 0; i--)
                this.drawBox.drawLayer.graphics[i] = this.drawBox.drawLayer.graphics[i - 1];
        }

        //Copy from graphic in destination
        this.drawBox.drawLayer.graphics[to_i] = from_graphic;

        //Redraw in good order
        var start_i = (from_i < to_i) ? from_i : to_i;
        this._redrawGraphics(start_i);
        return true;
    },

    _redrawGraphics: function(start_i) {
        if (!start_i)
            start_i = 0;
        var nb = this.drawBox.drawLayer.graphics.length;
        for (var i = 0; i < nb; i++) {
            if (i >= start_i) {
                var g = this.drawBox.drawLayer.graphics[i];
                var shape = g.getShape();
                if (shape)
                    shape.moveToFront();
            }
        }

    },

    listUpdateAllCheckbox: function(evt) {
        //Not called by event !
        if (evt === undefined) {
            var all_checked = true;
            var all_unchecked = true;

            for (var i = 0, nb = this.drawBox.drawLayer.graphics.length; i < nb; i++) {
                if (this.drawBox.drawLayer.graphics[i].checked)
                    all_unchecked = false;
                else
                    all_checked = false;
            }

            if (all_checked) {
                this.listCheckboxAll.checked = true;
                this.listCheckboxAll.indeterminate = false;
                this.listCheckboxAll2.checked = true;
                this.listCheckboxAll2.indeterminate = false;
            } else if (all_unchecked) {
                this.listCheckboxAll.checked = false;
                this.listCheckboxAll.indeterminate = false;
                this.listCheckboxAll2.checked = false;
                this.listCheckboxAll2.indeterminate = false;
            } else {
                this.listCheckboxAll.checked = true;
                this.listCheckboxAll.indeterminate = true;
                this.listCheckboxAll2.checked = true;
                this.listCheckboxAll2.indeterminate = true;
            }
            return
        }

        //Event click on checkbox!
        var cb = evt.target;
        var check = evt.target.checked;

        for (var i = 0, nb = this.drawBox.drawLayer.graphics.length; i < nb; i++) {
            this.drawBox.drawLayer.graphics[i].checked = check;
            dom.byId('draw-action-checkclick--' + i).checked = check;
        }
        this.listCheckboxAll.checked = check;
        this.listCheckboxAll.indeterminate = false;
        this.listCheckboxAll2.checked = check;
        this.listCheckboxAll2.indeterminate = false;
    },

    listOnActionClick: function(evt) {
        if (!evt.target || !evt.target.id)
            return;

        var tab = evt.target.id.split('--');
        var type = tab[0];
        var i = parseInt(tab[1]);

        var g = this.drawBox.drawLayer.graphics[i];
        this._editorConfig["graphicCurrent"] = g;

        switch (type) {
            case 'draw-action-up':
                this.switch2DrawingGraphics(i, i + 1);
                this.listGenerateDrawTable();
                break;
            case 'draw-action-down':
                this.switch2DrawingGraphics(i, i - 1);
                this.listGenerateDrawTable();
                break;
            case 'draw-action-delete':
                this._clickedGraphic = g;
                if (this.config.confirmOnDelete) {
                    this._confirmDeleteMessage = new Message({
                        message: '<i class="message-warning-icon"></i>&nbsp;' + this.nls.confirmDrawDelete,
                        buttons: [{
                            label: this.nls.yes,
                            onClick: this._removeClickedGraphic
                        }, {
                            label: this.nls.no
                        }]
                    });
                } else {
                    this._removeClickedGraphic();
                }
                break;
            case 'draw-action-edit':
                this.setMode("edit");
                break;
            case 'draw-action-zoom':
                this.setInfoWindow(g);

                var extent = graphicsUtils.graphicsExtent([g]);
                this.map.setExtent(extent, true);
                this.listGenerateDrawTable();

                break;
            case 'draw-action-checkclick':
                g.checked = evt.target.checked;
                this.listUpdateAllCheckbox();
                break;
        }
    },

    ///////////////////////// SYMBOL EDITOR METHODS ///////////////////////////////////////////////////////////
    _editorConfig: {
        drawPlus: {
            "FontFamily": false,
            "bold": false,
            "italic": false,
            "underline": false,
            "angle": false,
            "placement": {
                "vertical": "middle",
                "horizontal": "center"
            }
        },
        phantom: {
            "point": false,
            "symbol": false,
            "layer": false,
            "handle": false
        }
    },

    editorPrepareForAdd: function(symbol) {
        this._editorConfig["graphicCurrent"] = false;

        this.editorSymbolChooserConfigure(symbol);

        this.nameField.value = this.nls.nameFieldDefaultValue;
        this.descriptionField.value = '';

        this.editorTitle.innerHTML = this.nls.addDrawTitle;
        this.editorFooterEdit.style.display = 'none';
        this.editorFooterAdd.style.display = 'block';
        this.editorAddMessage.style.display = 'block';
        this.editorEditMessage.style.display = 'none';
        this.editorSnappingMessage.style.display = 'none';

        var commontype = this._editorConfig['commontype'];

        //Mouse preview
        this._editorConfig["phantom"]["symbol"] = symbol;
        this.editorEnableMapPreview((commontype == 'point' || commontype == 'text'));

        //If text prepare symbol
        if (commontype == "text")
            this.editorUpdateTextPlus();

        this.editorActivateSnapping(true);

        //Prepare measure section
        this.editorMeasureConfigure(false, commontype);
    },

    editorPrepareForEdit: function(graphic) {
        this._editorConfig["graphicCurrent"] = graphic;

        this.nameField.value = graphic.attributes["name"];
        this.descriptionField.value = graphic.attributes["description"];

        this.editorActivateGeometryEdit(graphic);

        this.editorSymbolChooserConfigure(graphic.symbol);

        this.editorTitle.innerHTML = this.nls.editDrawTitle;
        this.editorFooterEdit.style.display = 'block';
        this.editorFooterAdd.style.display = 'none';
        this.editorAddMessage.style.display = 'none';
        this.editorEditMessage.style.display = 'block';
        this.editorSnappingMessage.style.display = 'block';

        this.editorEnableMapPreview(false);
        this.editorActivateSnapping(true);

        this.editorMeasureConfigure(graphic, false);
    },

    editorSymbolChooserConfigure: function(symbol) {
        if (!symbol)
            return;

        //Set this symbol in symbol chooser
        this.editorSymbolChooser.showBySymbol(symbol);
        this.editorSymbolChooser.showByType(this.editorSymbolChooser.type);
        this._editorConfig['symboltype'] = this.editorSymbolChooser.type;

        var type = symbol.type;

        //Draw plus and specific comportment when line symbol.
        if (type == "simplelinesymbol") {
            this.editorSymbolLinePlusNode.style.display = 'block';
            if (symbol.marker && symbol.marker.placement) {
                this.editorLinePlusArrow.set("value", symbol.marker.placement);
            } else {
                this.editorLinePlusArrow.set("value", '');
            }
        } else {
            this.editorSymbolLinePlusNode.style.display = 'none';
        }

        //Draw plus and specific comportment when text symbol.
        if (type == "textsymbol") {
            //Force editorSymbolChooser _init to walk around jimu.js bug (initTextSection doesn't pass symbol to _initTextSettings)
            this.editorSymbolChooser._initTextSettings(symbol);

            //show draw plus
            this.editorSymbolTextPlusNode.style.display = 'block';

            //Hide text label input (use name instead of)
            var tr = this._UTIL__getParentByTag(this.editorSymbolChooser.inputText, 'tr');
            if (tr)
                tr.style.display = 'none';

            //Draw plus configuration
            this._editorConfig["drawPlus"]["bold"] = (symbol.font.weight == esri.symbol.Font.WEIGHT_BOLD);
            this._editorConfig["drawPlus"]["italic"] = (symbol.font.style == esri.symbol.Font.STYLE_ITALIC);
            this._editorConfig["drawPlus"]["underline"] = (symbol.font.decoration == 'underline');
            this._editorConfig["drawPlus"]["placement"]["horizontal"] = (symbol.horizontalAlignment) ? symbol.horizontalAlignment : "center";
            this._editorConfig["drawPlus"]["placement"]["vertical"] = (symbol.verticalAlignment) ? symbol.verticalAlignment : "middle";
            this.editorTextPlusFontFamilyNode.set("value", symbol.font.family);
            this.editorTextPlusAngleNode.set("value", symbol.angle);
            this._UTIL__enableClass(this.editorTextPlusBoldNode, 'selected', this._editorConfig["drawPlus"]["bold"]);
            this._UTIL__enableClass(this.editorTextPlusItalicNode, 'selected', this._editorConfig["drawPlus"]["italic"]);
            this._UTIL__enableClass(this.editorTextPlusUnderlineNode, 'selected', this._editorConfig["drawPlus"]["underline"]);
            for (var i = 0, len = this._editorTextPlusPlacements.length; i < len; i++) {
                var title_tab = this._editorTextPlusPlacements[i].title.split(" ");
                var selected =
                    (
                        title_tab[0] == this._editorConfig["drawPlus"]["placement"]["vertical"] &&
                        title_tab[1] == this._editorConfig["drawPlus"]["placement"]["horizontal"]
                    );
                this._UTIL__enableClass(this._editorTextPlusPlacements[i], 'selected', selected);
            }
        } else {
            //Hide draw plus
            this.editorSymbolTextPlusNode.style.display = 'none';
        }
    },

    editorActivateSnapping: function(bool) {
        //If disable
        if (!bool) {
            this.map.disableSnapping();
            return;
        }

        //If enable
        this.map.enableSnapping({
            "layerInfos": [{
                "layer": this.drawBox.drawLayer
            }],
            "tolerance": 20
        });
    },

    editorUpdateTextPlus: function() {
        //Only if text
        if (this.editorSymbolChooser.type != "text") {
            return;
        }

        //Get parameters
        var text = this.nameField.value;
        var family = this.editorTextPlusFontFamilyNode.value;
        var angle = this.editorTextPlusAngleNode.value;
        var weight = this._editorConfig["drawPlus"]["bold"] ? esri.symbol.Font.WEIGHT_BOLD : esri.symbol.Font.WEIGHT_NORMAL;
        var style = this._editorConfig["drawPlus"]["italic"] ? esri.symbol.Font.STYLE_ITALIC : esri.symbol.Font.STYLE_NORMAL;
        var decoration = this._editorConfig["drawPlus"]["underline"] ? 'underline' : 'none';
        var horizontal = this._editorConfig["drawPlus"]["placement"]["horizontal"];
        var vertical = this._editorConfig["drawPlus"]["placement"]["vertical"];

        //Prepare symbol
        var symbol = this.editorSymbolChooser.getSymbol();
        this.editorSymbolChooser.inputText.value = text;
        symbol.text = text;
        symbol.font.setFamily(family);
        symbol.setAngle(angle);
        symbol.setHorizontalAlignment(horizontal);
        symbol.setVerticalAlignment(vertical);
        symbol.font.setWeight(weight);
        symbol.font.setStyle(style);
        symbol.font.setDecoration(decoration);

        //Set in symbol chooser
        this.editorSymbolChooser.inputText.value = text;
        this.editorSymbolChooser.showBySymbol(symbol);

        //Update in drawBox
        this.drawBox.setTextSymbol(symbol);

        //Update preview
        this.editorSymbolChooser.textPreview.innerHTML = text;
        this.editorSymbolChooser.textPreview.style.fontFamily = family;
        this.editorSymbolChooser.textPreview.style['font-style'] = (this._editorConfig["drawPlus"]["italic"]) ? 'italic' : 'normal';
        this.editorSymbolChooser.textPreview.style['font-weight'] = (this._editorConfig["drawPlus"]["bold"]) ? 'bold' : 'normal';
        this.editorSymbolChooser.textPreview.style['text-decoration'] = (this._editorConfig["drawPlus"]["underline"]) ? 'underline' : 'none';

        //Update angle preview
        this.editorTextAnglePreviewNode.style.transform = 'rotate(' + angle + 'deg)';
        this.editorTextAnglePreviewNode.style['-ms-transform'] = 'rotate(' + angle + 'deg)';

        //Update symbol on map if on modification
        if (this._editorConfig["graphicCurrent"])
            this._editorConfig["graphicCurrent"].setSymbol(symbol);
        else {
            //Update phantom symbol
            this.editorUpdateMapPreview(symbol);
        }
    },

    editorMeasureConfigure: function(graphicIfUpdate, commonTypeIfAdd) {
        this.measureSection.style.display = 'block';

        //Manage if fields are shown or not
        if (graphicIfUpdate && graphicIfUpdate.measureParent) {
            this.fieldsDiv.style.display = 'none';
            this.isMeasureSpan.style.display = 'block';
        } else {
            this.fieldsDiv.style.display = 'block';
            this.isMeasureSpan.style.display = 'none';
        }

        //add Mode
        if (commonTypeIfAdd) {
            //No measure supported for this types
            if (commonTypeIfAdd == "text") {
                this.measureSection.style.display = 'none';
                return;
            }

            this.distanceUnitSelect.set('value', this.configDistanceUnits[0]['unit']);
            this.areaUnitSelect.set('value', this.configAreaUnits[0]['unit']);
            this.pointUnitSelect.set('value', 'map');

            this.showMeasure.checked = (this.config.measureEnabledByDefault);
            this._setMeasureVisibility();

            return;
        }

        //edit mode
        if (!graphicIfUpdate) {
            this.measureSection.style.display = 'none';
            return;
        }

        var geom_type = graphicIfUpdate.geometry.type;

        //If no measure for this type of graphic
        if (geom_type == "point" && graphicIfUpdate.symbol && graphicIfUpdate.symbol.type == 'textsymbol') {
            this.measureSection.style.display = 'none';
            return;
        }

        var checked = (graphicIfUpdate.measure);

        var lengthUnit = (graphicIfUpdate.measure && graphicIfUpdate.measure.lengthUnit) ? graphicIfUpdate.measure.lengthUnit : this.configDistanceUnits[0]['unit'];
        this.distanceUnitSelect.set('value', lengthUnit);

        if (geom_type == "polygon") {
            var areaUnit = (graphicIfUpdate.measure && graphicIfUpdate.measure.areaUnit) ? graphicIfUpdate.measure.areaUnit : this.configAreaUnits[0]['unit'];
            this.areaUnitSelect.set('value', areaUnit);
        }

        this.showMeasure.checked = checked;
        this._setMeasureVisibility();
    },

    editorSetDefaultSymbols: function() {
        var symbol = this.editorSymbolChooser.getSymbol();
        switch (symbol.type.toLowerCase()) {
            case "simplemarkersymbol":
                this.drawBox.setPointSymbol(symbol);
                break;
            case "picturemarkersymbol":
                this.drawBox.setPointSymbol(symbol);
                break;
            case "textsymbol":
                this.drawBox.setTextSymbol(symbol);
                break;
            case "simplelinesymbol":
                this.drawBox.setLineSymbol(symbol);
                break;
            case "cartographiclinesymbol":
                this.drawBox.setLineSymbol(symbol);
                break;
            case "simplefillsymbol":
                this.drawBox.setPolygonSymbol(symbol);
                break;
            case "picturefillsymbol":
                this.drawBox.setPolygonSymbol(symbol);
                break;
        }
    },

    ///////////////////////// IMPORT/EXPORT METHODS ///////////////////////////////////////////////////////////
    importMessage: false,
    importInput: false,
    launchImportFile: function() {
        if (!window.FileReader) {
            this.showMessage(this.nls.importErrorMessageNavigator, 'error');
            return false;
        }

        // var dragAndDropSupport = ()

        var content = '<div class="eDraw-import-message" id="' + this.id + '___div_import_message">' +
            '<input class="file" type="file" id="' + this.id + '___input_file_import"/>' +
            '<div class="eDraw-import-draganddrop-message">' + this.nls.importDragAndDropMessage + '</div>' +
            '</div>';
        this.importMessage = new Message({
            message: content,
            titleLabel: this.nls.importTitle,
            buttons: [{
                label: this.nls.importCloseButton
            }]
        });
        this.importInput = dojo.byId(this.id + '___input_file_import');

        //Init file's choice up watching
        on(this.importInput, "change", this.importFile);

        //Init drag & drop
        var div_message = dojo.byId(this.id + '___div_import_message');
        on(div_message, "dragover", function(e) {
            e.stopPropagation();
            e.preventDefault();
            e.dataTransfer.dropEffect = 'copy';
        });
        on(div_message, "drop", lang.hitch(this, function(e) {
            e.stopPropagation();
            e.preventDefault();
            var files = e.dataTransfer.files;

            if (!files[0])
                return;
            var reader = new FileReader();
            reader.onload = this.importOnFileLoad;
            var txt = reader.readAsText(files[0]);
        }));
    },

    importFile: function() {
        if (!this.importInput) {
            this.showMessage(this.nls.importErrorWarningSelectFile, 'warning');
            if (this.importMessage)
                this.importMessage.close();
            return false;
        }

        var input_file = this.importInput.files[0];
        if (!input_file) {
            this.showMessage(this.nls.importErrorWarningSelectFile, 'warning');
            return false;
        }
        var reader = new FileReader();
        reader.onload = this.importOnFileLoad;
        var txt = reader.readAsText(input_file);
    },

    importOnFileLoad: function(evt) {
        var content = evt.target.result;
        this.importJsonContent(content);
        this.importMessage.close();
    },

    importJsonContent: function(json, nameField, descriptionField) {
        try {
            if (typeof json == 'string') {
                json = JSON.parse(json);
            }

            if (!json.features) {
                this.showMessage(this.nls.importErrorFileStructure, 'error');
                return false;
            }

            if (json.features.length < 1) {
                this.showMessage(this.nls.importWarningNoDrawings, 'warning');
                return false;
            }

            if (!nameField) {
                var g = json.features[0];
                var fields_possible = ["name", "title", "label"];
                if (g.attributes) {
                    for (var i in fields_possible) {
                        if (g.attributes[fields_possible[i]]) {
                            nameField = fields_possible[i];
                            break;
                        }
                    }
                }
            }
            if (!descriptionField) {
                var g = json.features[0];
                var fields_possible = ["description", "descript", "desc", "comment", "comm"];
                if (g.attributes) {
                    for (var i = 0, len = fields_possible.length; i < len; i++) {
                        if (g.attributes[fields_possible[i]]) {
                            descriptionField = fields_possible[i];
                            break;
                        }
                    }
                }
            }

            var measure_features_i = [];
            var graphics = [];
            for (var i = 0, len = json.features.length; i < len; i++) {
                var json_feat = json.features[i];

                var g = new Graphic(json_feat);

                if (!g)
                    continue;

                if (!g.attributes)
                    g.attributes = {};

                g.attributes["name"] = (!nameField || !g.attributes[nameField]) ? 'n°' + (i + 1) : g.attributes[nameField];
                if (g.symbol && g.symbol.type == "textsymbol")
                    g.attributes["name"] = g.symbol.text;
                g.attributes["description"] = (!descriptionField || !g.attributes[descriptionField]) ? '' : g.attributes[descriptionField];

                if (!g.symbol) {
                    var symbol = false;
                    switch (g.geometry.type) {
                        case 'point':
                            var symbol = new SimpleMarkerSymbol();
                            break;
                        case 'polyline':
                            var symbol = new SimpleLineSymbol();
                            break;
                        case 'polygon':
                            var symbol = new SimpleFillSymbol();
                            break;
                    }
                    if (symbol) {
                        g.setSymbol(symbol);
                    }
                }

                //If is with measure
                if (json_feat.measure) {
                    g.measure = json_feat.measure;
                    measure_features_i.push(i);
                }
                graphics.push(g);
            }

            //Treat measures
            for (var k = 0, k_len = measure_features_i.length; k < k_len; k++) {
                var i = measure_features_i[k]; //Indice to treat
                var label_graphic = (graphics[i].measure && graphics[i].measure.graphic && graphics[graphics[i].measure.graphic]) ?
                    graphics[graphics[i].measure.graphic] :
                    false;
                if (label_graphic) {
                    graphics[i].measure.graphic = label_graphic
                    label_graphic.measureParent = graphics[i];
                } else {
                    graphics[i].measure = false;
                }
            }

            //Add graphics
            for (var i = 0, nb = graphics.length; i < nb; i++) {
                if (graphics[i])
                    this.drawBox.drawLayer.add(graphics[i]);
            }

            //Show list
            this.setMode("list");
        } catch (e) {
            this.showMessage(this.nls.importErrorFileStructure, 'error');
            return false;
        }
    },

    exportInFile: function() {
        this.launchExport(false);
    },

    exportSelectionInFile: function(evt) {
        if (evt && evt.preventDefault)
            evt.preventDefault();
        this.launchExport(true);
    },

    launchExport: function(only_graphics_checked) {
        var drawing_json = this.drawingsGetJson(false, only_graphics_checked);

        // Control if there are drawings
        if (!drawing_json) {
            this.showMessage(this.nls.importWarningNoExport0Draw, 'warning');
            return false;
        }

        //We could use FeatureSet (which is required) but this workaround keeps symbols !
        var drawing_seems_featureset = {
            toJson: function() {
                return drawing_json;
            }
        };

        //Create datasource and download !
        var ds = exportUtils.createDataSource({
            "type": exportUtils.TYPE_FEATURESET,
            "data": drawing_seems_featureset,
            "filename": (this.config.exportFileName) ? (this.config.exportFileName) : 'myDrawings'
        });
        ds.setFormat(exportUtils.FORMAT_FEATURESET)
        ds.download();

        return false;
    },

    ///////////////////////// EDIT METHODS ///////////////////////////////////////////////////////////
    editorOnClickEditSaveButon: function() {
        if (this.editorSymbolChooser.type == "text") {
            this.editorUpdateTextPlus();
        }

        this._editorConfig["graphicCurrent"].attributes["name"] = this.nameField.value;
        this._editorConfig["graphicCurrent"].attributes["description"] = this.descriptionField.value;


        if (this.editorSymbolChooser.type != "text") {
            var geom = this._editorConfig["graphicCurrent"].geometry;
            this.addMeasure(geom, this._editorConfig["graphicCurrent"]);
        }

        this.setMode("list");
    },
    editorOnClickEditCancelButon: function() {
        this.editorResetGraphic();
        this.editorActivateGeometryEdit(false);
        this.setMode("list");
    },
    editorOnClickResetCancelButon: function() {
        this.editorResetGraphic();
        this.setMode("edit");
    },

    editorResetGraphic: function() {
        if (this._editorConfig["graphicSaved"] && this._editorConfig["graphicCurrent"]) {
            var g = new Graphic(this._editorConfig["graphicSaved"]);
            this._editorConfig["graphicCurrent"].setGeometry(g.geometry);
            this._editorConfig["graphicCurrent"].setSymbol(g.symbol);
        }
    },

    _showShadowMeasure: false,
    _shadowMeasureTextGraphic: null,
    showShadowMeasure: function(event) {
        if (this._shadowMeasureTextGraphic) {
            this.map.graphics.remove(this._shadowMeasureTextGraphic);
            this._shadowMeasureTextGraphic = null;
        }

        if (!this.showMeasure.checked || this._editorConfig['commontype'] == "text") {
            return;
        }

        if (!event.graphic || !event.graphic.geometry) return;

        var point = this._getLabelPoint(event.graphic.geometry);
        var txt = this.getMeasureText(event.graphic.geometry);

        if(txt && point){
          this._shadowMeasureTextGraphic = this._getTxtGraphic(point, txt);
          this.map.graphics.add(this._shadowMeasureTextGraphic);
        }

        return;
    },

    editorActivateGeometryEdit: function(graphic) {
        if (!graphic) {
            this.editorActivateSnapping(false);
            this._showShadowMeasure = false;
        }


        if (!graphic && this._editorConfig["editToolbar"]) {
            this._editorConfig["editToolbar"].deactivate();
            return;
        }

        this._showShadowMeasure = true;

        this._editorConfig["graphicSaved"] = graphic.toJson();

        var tool = 0 | Edit.MOVE;
        if (graphic.geometry.type != "point")
            tool = tool | Edit.EDIT_VERTICES | Edit.SCALE | Edit.ROTATE;

        var options = {
            allowAddVertices: true,
            allowDeleteVertices: true,
            uniformScaling: true
        };
        this._editorConfig["editToolbar"].activate(tool, graphic, options);
    },

    ///////////////////////// ADD METHODS ///////////////////////////////////////////////////////////
    drawBoxOnTypeSelected: function(target, geotype, commontype) {
        if (!this._editorConfig["defaultSymbols"])
            this._editorConfig["defaultSymbols"] = {};
        this._editorConfig['commontype'] = commontype;

        var symbol = this._editorConfig["defaultSymbols"][commontype];
        if (!symbol) {
            switch (commontype) {
                case "point":
                    var options =
                        (this.config.defaultSymbols && this.config.defaultSymbols.SimpleMarkerSymbol) ?
                        this.config.defaultSymbols.SimpleMarkerSymbol :
                        null;
                    symbol = new SimpleMarkerSymbol(options);
                    break;
                case "polyline":
                    var options =
                        (this.config.defaultSymbols && this.config.defaultSymbols.SimpleLineSymbol) ?
                        this.config.defaultSymbols.SimpleLineSymbol :
                        null;
                    symbol = new SimpleLineSymbol(options);
                    break;
                case "polygon":
                    var options =
                        (this.config.defaultSymbols && this.config.defaultSymbols.SimpleFillSymbol) ?
                        this.config.defaultSymbols.SimpleFillSymbol :
                        null;
                    symbol = new SimpleFillSymbol(options);
                    break;
                case "text":
                    var options =
                        (this.config.defaultSymbols && this.config.defaultSymbols.TextSymbol) ?
                        this.config.defaultSymbols.TextSymbol :
                        {
                            "verticalAlignment": "middle",
                            "horizontalAlignment": "center"
                        };
                    symbol = new TextSymbol(options);
                    break;
            }
        }
        this._showShadowMeasure = true;

        if (symbol) {
            this._editorConfig["defaultSymbols"][commontype] = symbol;
            this.setMode('add2');
        }
    },

    extent2Polygon:function(extent){
        var polygon = new Polygon(extent.spatialReference || this.map.spatialReference);
        var r = [
            [extent.xmin, extent.ymin],
            [extent.xmin, extent.ymax],
            [extent.xmax, extent.ymax],
            [extent.xmax, extent.ymin],
            [extent.xmin, extent.ymin]
        ];
        polygon.addRing(r);
        return polygon
    },

    rect2Polygon: function(rect){
      return this.extent2Polygon(rect.getExtent());
    },

    drawBoxOnDrawEnd: function(graphic, geotype, commontype) {
        var geometry = graphic.geometry;

        this.editorEnableMapPreview(false);

        graphic.attributes = {
            "name": this.nameField.value,
            "description": this.descriptionField.value
        }

        if (geometry.type === 'extent') {
            var polygon = this.extent2Polygon(geometry);

            graphic.setGeometry(polygon);

            var layer = graphic.getLayer();
            layer.remove(graphic);
            layer.add(graphic);

            commontype = 'polygon';
        }

        if (commontype != 'text' && this.showMeasure.checked) {
            this.addMeasure(geometry, graphic);
        }
        if (commontype == 'text' && this.editorSymbolChooser.inputText.value.trim() == "") {
            //Message
            this.showMessage(this.nls.textWarningMessage, 'warning');

            //Remove empty feature (text symbol without text)
            graphic.getLayer().remove(graphic);
        }

        this.saveInLocalStorage();
        this._editorConfig["graphicCurrent"] = graphic;
        this._editorConfig["defaultSymbols"][this._editorConfig['commontype']] = graphic.symbol;
        this.setMode("list");
    },

    editorEnableMapPreview: function(bool) {
        //if deactivate
        if (!bool) {
            //Hide layer
            if (this._editorConfig["phantom"]["layer"])
                this._editorConfig["phantom"]["layer"].setVisibility(false);

            this._editorConfig["phantom"]["symbol"] = false;

            //Remove map handlers
            if (this._editorConfig["phantom"]["handle"]) {
                dojo.disconnect(this._editorConfig["phantom"]["handle"]);
                this._editorConfig["phantom"]["handle"] = false;
            }
            return;
        }

        //Create layer if doesn't exist
        if (!this._editorConfig["phantom"]["layer"]) {
            this._editorConfig["phantom"]["layer"] = new GraphicsLayer({
                id: this.id + "__phantomLayer"
            });
            // this._editorConfig["phantom"]["point"]
            var center = this.map.extent.getCenter();
            this._editorConfig["phantom"]["point"] = new Graphic(center, this._editorConfig["phantom"]["symbol"], {});
            this._editorConfig["phantom"]["layer"].add(this._editorConfig["phantom"]["point"]);
            this._editorConfig["phantom"]["point"].hide();

            this.map.addLayer(this._editorConfig["phantom"]["layer"]);
        } else {
            this._editorConfig["phantom"]["layer"].setVisibility(true);
            this._editorConfig["phantom"]["point"].setSymbol(this._editorConfig["phantom"]["symbol"]);
        }

        //Track mouse on map
        if (!this._editorConfig["phantom"]["handle"]) {
            this._editorConfig["phantom"]["handle"] = on(this.map, 'mouse-move, mouse-out', lang.hitch(this, function(evt) {
                if (this.state === 'opened' || this.state === 'active') {
                    switch (evt.type) {
                        case 'mousemove':
                            if (this._editorConfig["phantom"]["point"]) {
                                this._editorConfig["phantom"]["point"].setGeometry(evt.mapPoint);
                                this._editorConfig["phantom"]["point"].show();
                                this.showShadowMeasure({
                                    graphic: {
                                        geometry: evt.mapPoint
                                    }
                                });
                            }
                            break;
                        case 'mouseout':
                            if (this._editorConfig["phantom"]["point"]) {
                                this._editorConfig["phantom"]["point"].hide();
                            }
                            break;
                        case 'mouseover':
                            if (this._editorConfig["phantom"]["point"]) {
                                this._editorConfig["phantom"]["point"].setGeometry(evt.mapPoint);
                                this._editorConfig["phantom"]["point"].show();
                            }
                            break;
                    }
                }
            }));
        }

    },

    editorUpdateMapPreview: function(symbol) {
        if (this.editorSymbolChooser.type != "text" && this.editorSymbolChooser.type != "marker") {
            return;
        }

        if (this._editorConfig["phantom"]["handle"] && this._editorConfig["phantom"]["point"]) {
            this._editorConfig["phantom"]["symbol"] = symbol;
            this._editorConfig["phantom"]["point"].setSymbol(symbol);
        }

    },

    editorOnClickAddCancelButon: function() {
        this.setMode("add1");
    },

    ////////////////////////////////////// Measure methods     //////////////////////////////////////////////
    _getLengthAndArea: function(geometry, isPolygon) {
        var def = new Deferred();
        var defResult = {
            length: null,
            area: null
        };
        var wkid = (geometry.spatialReference) ? geometry.spatialReference.wkid : this.map.spatialReference.wkid;
        var areaUnit = this.areaUnitSelect.value;
        var esriAreaUnit = esriUnits[areaUnit];
        var lengthUnit = this.distanceUnitSelect.value;
        var esriLengthUnit = esriUnits[lengthUnit];

        defResult = this._getLengthAndAreaGeometryEngine(geometry, isPolygon, areaUnit, lengthUnit, wkid);
        def.resolve(defResult);
        return def;
    },

    _getLengthAndAreaGeometryEngine: function(geometry, isPolygon, areaUnit, lengthUnit, wkid) {
        areaUnit = areaUnit.toLowerCase().replace("_", "-");
        lengthUnit = lengthUnit.toLowerCase().replace("_", "-");

        var result = {
            area: null,
            length: null
        };


		
		        if (isPolygon) {
            
				 result.area = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicArea(geometry, areaUnit) : geometryEngine.planarArea(geometry, areaUnit);
            var polyline = this._getPolylineOfPolygon(geometry);
				
				var polyline = this._getPolylineOfPolygon(geometry);
              
				
				     result.length = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicLength(polyline, lengthUnit) : geometryEngine.planarLength(polyline, lengthUnit);
        } else {
				
			  result.length = (wkid == 4326 || wkid == 3857 || wkid == 102100) ? geometryEngine.geodesicLength(geometry, lengthUnit) : geometryEngine.planarLength(geometry, lengthUnit);
                    
			}

            return result;
        },


		


    _getPolylineOfPolygon: function(polygon) {
        var polyline = new Polyline(polygon.spatialReference);
        var points = polygon.rings[0];
        points = points.slice(0, points.length - 1);
        polyline.addPath(points);
        return polyline;
    },

    _resetUnitsArrays: function() {
        this.defaultDistanceUnits = [];
        this.defaultAreaUnits = [];
        this.configDistanceUnits = [];
        this.configAreaUnits = [];
        this.distanceUnits = [];
        this.areaUnits = [];
    },

    _getDefaultDistanceUnitInfo: function(unit) {
        for (var i = 0; i < this.defaultDistanceUnits.length; i++) {
            var unitInfo = this.defaultDistanceUnits[i];
            if (unitInfo.unit === unit) {
                return unitInfo;
            }
        }
        return null;
    },

    _getDefaultAreaUnitInfo: function(unit) {
        for (var i = 0; i < this.defaultAreaUnits.length; i++) {
            var unitInfo = this.defaultAreaUnits[i];
            if (unitInfo.unit === unit) {
                return unitInfo;
            }
        }
        return null;
    },

    _getDistanceUnitInfo: function(unit) {
        for (var i = 0; i < this.distanceUnits.length; i++) {
            var unitInfo = this.distanceUnits[i];
            if (unitInfo.unit === unit) {
                return unitInfo;
            }
        }
        return null;
    },

    _getAreaUnitInfo: function(unit) {
        for (var i = 0; i < this.areaUnits.length; i++) {
            var unitInfo = this.areaUnits[i];
            if (unitInfo.unit === unit) {
                return unitInfo;
            }
        }
        return null;
    },

    _setMeasureVisibility: function() {

        var display_point = 'none';
        var display_line = 'none';
        var display_area = 'none';

        if (this._editorConfig['symboltype']) {
            ////marker,line,fill,text
            switch (this._editorConfig['symboltype']) {
                case 'text':
                    display_point = 'none';
                    display_line = 'none';
                    display_area = 'none';
                    break;
                case 'marker':
                    display_point = 'block';
                    display_line = 'none';
                    display_area = 'none';
                    break;
                case 'line':
                    display_point = 'none';
                    display_line = 'block';
                    display_area = 'none';
                    break;
                case 'fill':
                    display_point = 'none';
                    display_line = 'block';
                    display_area = 'block';
                    break;
            }
        }

        html.setStyle(this.pointMeasure, 'display', display_point);
        html.setStyle(this.distanceMeasure, 'display', display_line);
        html.setStyle(this.areaMeasure, 'display', display_area);
    },

    _getGraphicIndex: function(g) {
        for (var i = 0, nb = this.drawBox.drawLayer.graphics.length; i < nb; i++) {
            if (this.drawBox.drawLayer.graphics[i] == g)
                return parseInt(i);
        }
        return false;
    },

    _getLabelPoint: function(geometry) {
        // point
        if(geometry.type == "point"){
           return geometry;
        }

        // polygon
        if(geometry.type == "polygon" && geometry.getCendroid){
             return geometry.getCendroid();
        }

        //Polyline ( + hack for "drawing segment")
        if(geometry.type == "polyline" || geometry.commonType == "polyline"){
             var extent_center = geometry.getExtent().getCenter();

              //geometryEngine -> replace point (extent center) on geometry
              var res = geometryEngine.nearestCoordinate(geometry, extent_center);
              if (res && res.coordinate)
                  return res.coordinate;

              return extent_center;
        }

        // rectangle
        if(geometry.type == "rect" && geometry.getCenter){
           return geometry.getExtent().getCenter();
        }

        // extent
        if(geometry.type == "extent" && geometry.getCenter){
           return geometry.getCenter();
        }

        // Unknown but centroid method
        if (geometry.getCendroid)
            return geometry.getCendroid();

        // Unknown but center method
        if (geometry.getCenter)
            return geometry.getCenter();

        // Unknown but extent method
        if (geometry.getExtent)
            return geometry.getExtent().getCenter();

        return false;
    },

    getMeasureText: function(geometry){

      var wkid = (geometry.spatialReference) ? geometry.spatialReference.wkid : this.map.spatialReference.wkid;

      var pointUnit = this.pointUnitSelect.value;

      var lengthUnit = this.distanceUnitSelect.value;
      var esriLengthUnit = esriUnits[lengthUnit];

      var areaUnit = this.areaUnitSelect.value;
      var esriAreaUnit = esriUnits[areaUnit];

      // For extent, force polygon !
      if(geometry.type == "extent"){
          geometry = this.extent2Polygon(geometry);
      }
      else if(geometry.type == "rect"){
          geometry = this.rect2Polygon(geometry);
      }

      switch(geometry.type){
        case 'point':

            var coords = {
                "x": this._round(geometry.x, 2),
                "y": this._round(geometry.y, 2)
            };

            if(pointUnit != "map"){
                var coords = null;
                if (wkid == 4326) {
                    coords = {
                        "x": geometry.x,
                        "y": geometry.y
                    };
                } else if (projection.isLoaded()) {
                    var point_wgs84 = projection.project(geometry, new SpatialReference({
                        wkid: 4326
                    }));
                    coords = {
                        "x": point_wgs84.x,
                        "y": point_wgs84.y
                    };
                }
                if (!coords){
                  return;
                }
                coords = this._prepareLonLat(coords, pointUnit == "DMS");
            }

            var pointPattern = (this.config.measurePointLabel) ? this.config.measurePointLabel : "{{x}} {{y}}";
            return pointPattern.replace("{{x}}", coords.x).replace("{{y}}", coords.y);
            break;
        case 'polyline':
            var measure = this._getLengthAndAreaGeometryEngine(geometry, false, areaUnit, lengthUnit, wkid);
            var polylinePattern = (this.config.measurePolylineLabel) ? this.config.measurePolylineLabel : "{{length}} {{lengthUnit}}";

            var localeLength = jimuUtils.localizeNumber(measure.length.toFixed(1));
            var lengthUnit = this.distanceUnitSelect.value;
            var localeLengthUnit = this._getDistanceUnitInfo(lengthUnit).label;

            return polylinePattern.replace("{{length}}", localeLength).replace("{{lengthUnit}}", localeLengthUnit);

            break;
        case 'polygon':
            var measure = this._getLengthAndAreaGeometryEngine(geometry, true, areaUnit, lengthUnit, wkid);
            var polygonPattern = (this.config.measurePolygonLabel) ? this.config.measurePolygonLabel : "{{area}} {{areaUnit}}    {{length}} {{lengthUnit}}";

            var localeLength = jimuUtils.localizeNumber(measure.length.toFixed(1));
            var lengthUnit = this.distanceUnitSelect.value;
            var localeLengthUnit = this._getDistanceUnitInfo(lengthUnit).label;

            var areaUnit = this.areaUnitSelect.value;
            var localeAreaUnit = this._getAreaUnitInfo(areaUnit).label;
            var localeArea = jimuUtils.localizeNumber(measure.area.toFixed(1));

            return polygonPattern.replace("{{length}}", localeLength).replace("{{lengthUnit}}", localeLengthUnit)
                        .replace("{{area}}", localeArea).replace("{{areaUnit}}", localeAreaUnit);

            break;

      }

      return null;

    },

    _prepareLonLat: function(point, as_dms) {
        if (!as_dms)
            return {
                x: this._round(point.x, 5),
                y: this._round(point.y, 5)
            };

        var coords = {
            x: point.x,
            y: point.y
        };
        if (coords.x < 0) {
            coords.x = -coords.x;
            var cardinal_point = this.nls.west;
        } else {
            var cardinal_point = this.nls.east;
        }
        var degres = Math.floor(coords.x);
        var minutes_float = (coords.x - degres) * 60;
        var minutes = Math.floor(minutes_float);
        var seconds = (minutes_float - minutes) * 60;
        coords.x = degres + "°" + minutes + '"' + this._round(seconds, 2) + "'" + cardinal_point;

        if (coords.y < 0) {
            coords.y = -coords.y;
            var cardinal_point = this.nls.south;
        } else {
            var cardinal_point = this.nls.north;
        }
        var degres = Math.floor(coords.y);
        var minutes_float = (coords.y - degres) * 60;
        var minutes = Math.floor(minutes_float);
        var seconds = (minutes_float - minutes) * 60;
        coords.y = degres + "°" + minutes + '"' + this._round(seconds, 2) + "'" + cardinal_point;
        return coords;
    },

    _round: function(my_number, decimals) {
        if (!decimals)
            return Math.round(my_number);
        else
            return Math.round(my_number * Math.pow(10, decimals)) / Math.pow(10, decimals);
    },

    _getTxtGraphic:function(point, text, bottomAlignment){
        var a = Font.STYLE_ITALIC;
        var b = Font.VARIANT_NORMAL;
        var c = Font.WEIGHT_BOLD;
        var symbolFont = new Font("16px", a, b, c, "Courier");
        var fontColor = new Color([0, 0, 0, 1]);
        var textSymbol = new TextSymbol(text, symbolFont, fontColor);

        if (bottomAlignment) {
            textSymbol.setVerticalAlignment('bottom');
        }

        return new Graphic(point, textSymbol, {
            "name": text,
            "description": ""
        }, null);

    },

    addMeasure: function(geometry, graphic){
        //Remove shadow measure
        if (this._shadowMeasureTextGraphic) {
            this.map.graphics.remove(this._shadowMeasureTextGraphic);
            this._shadowMeasureTextGraphic = null;
        }

        var text = this.getMeasureText(geometry);

        var existingMeasureGraphic = (graphic.measure && graphic.measure.graphic && graphic.measure.graphic.measureParent) ? graphic.measure.graphic : false;

        //Get label point
        var point = this._getLabelPoint(geometry);

        if (existingMeasureGraphic) {
            var labelGraphic = existingMeasureGraphic;
            labelGraphic.symbol.setText(text);
            labelGraphic.attributes["name"] = text;
            labelGraphic.geometry.update(point.x, point.y);
            labelGraphic.draw();
        }
        else {

            var labelGraphic = this._getTxtGraphic(point, text, (geometry.type == "point") );
            this.drawBox.drawLayer.add(labelGraphic);

            //Replace measure label on top of measured graphic
            var measure_index = this._getGraphicIndex(graphic);
            var label_index = this.drawBox.drawLayer.graphics.length - 1;
            if (label_index > (measure_index + 1))
                this.moveDrawingGraphic(label_index, measure_index + 1);
        }

        //Reference
        labelGraphic.measureParent = graphic;
        graphic.measure = {
            "graphic": labelGraphic,
            "pointUnit": this.pointUnitSelect.value,
            "lengthUnit": this.distanceUnitSelect.value,
            "areaUnit": this.areaUnitSelect.value
        };
        return labelGraphic;
    },

    ////////    INIT METHODS ////////////////////////////////////////////////////////////////////////////////////////////////////////
    _bindEvents: function() {
        //bind DrawBox
        this.own(on(this.drawBox, 'IconSelected', lang.hitch(this, this.drawBoxOnTypeSelected)));
        this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this.drawBoxOnDrawEnd)));

        //Bind symbol chooser change
        this.own(on(this.editorSymbolChooser, 'change', lang.hitch(this, function() {
            this.editorSetDefaultSymbols();

            //If text plus
            if (this.editorSymbolChooser.type == "text") {
                this.editorUpdateTextPlus();
            } else if (this._editorConfig["graphicCurrent"]) {
                //If in modification, update graphic symbology
                this._editorConfig["graphicCurrent"].setSymbol(this.editorSymbolChooser.getSymbol());
            }

            //Phantom for marker
            if (this.editorSymbolChooser.type == "marker")
                this.editorUpdateMapPreview(this.editorSymbolChooser.getSymbol());
        })));

        //bind unit events
        this.own(on(this.showMeasure, 'click', lang.hitch(this, this._setMeasureVisibility)));

        //hitch list event
        this.listOnActionClick = lang.hitch(this, this.listOnActionClick);
        //hitch import file loading
        this.importFile = lang.hitch(this, this.importFile);
        this.importOnFileLoad = lang.hitch(this, this.importOnFileLoad);

        //Bind delete method
        this._removeGraphics = lang.hitch(this, this._removeGraphics);
        this._removeClickedGraphic = lang.hitch(this, this._removeClickedGraphic);

        //Bind draw plus event
        on(this.editorLinePlusArrow, "change", lang.hitch(this, function(evt) {
            this._editorConfig["drawPlus"]["arrow"] = this.editorLinePlusArrow.value;
            var symbol = this.editorSymbolChooser.getSymbol();
            if (this.editorLinePlusArrow.value) {
                symbol.setMarker({
                    style: "arrow",
                    placement: this.editorLinePlusArrow.value
                });
            } else {
                symbol.marker = null;
            }

            this.editorSymbolChooser.showBySymbol(symbol);
            this.drawBox.setLineSymbol(symbol);

            //Update symbol on map if on modification
            if (this._editorConfig["graphicCurrent"])
                this._editorConfig["graphicCurrent"].setSymbol(symbol);
            else {
                //Update phantom symbol
                this.editorUpdateMapPreview(symbol);
            }
        }));

        this.editorUpdateTextPlus = lang.hitch(this, this.editorUpdateTextPlus);
        this.editorTextPlusFontFamilyNode.on("change", this.editorUpdateTextPlus);
        this.editorTextPlusAngleNode.on("change", this.editorUpdateTextPlus);
        on(this.editorTextPlusBoldNode, "click", lang.hitch(this, function(evt) {
            this._editorConfig["drawPlus"]["bold"] = !this._editorConfig["drawPlus"]["bold"];
            this._UTIL__enableClass(this.editorTextPlusBoldNode, 'selected', this._editorConfig["drawPlus"]["bold"]);
            this.editorUpdateTextPlus();
        }));
        on(this.editorTextPlusItalicNode, "click", lang.hitch(this, function(evt) {
            this._editorConfig["drawPlus"]["italic"] = !this._editorConfig["drawPlus"]["italic"];
            this._UTIL__enableClass(this.editorTextPlusItalicNode, 'selected', this._editorConfig["drawPlus"]["italic"]);
            this.editorUpdateTextPlus();
        }));
        on(this.editorTextPlusUnderlineNode, "click", lang.hitch(this, function(evt) {
            this._editorConfig["drawPlus"]["underline"] = !this._editorConfig["drawPlus"]["underline"];
            this._UTIL__enableClass(this.editorTextPlusUnderlineNode, 'selected', this._editorConfig["drawPlus"]["underline"]);
            this.editorUpdateTextPlus();
        }));
        this.onEditorTextPlusPlacementClick = lang.hitch(this, function(evt) {
            if (!evt.target)
                return;

            var selected = false;
            for (var i = 0, len = this._editorTextPlusPlacements.length; i < len; i++) {
                var is_this = (evt.target == this._editorTextPlusPlacements[i]);

                this._UTIL__enableClass(this._editorTextPlusPlacements[i], 'selected', is_this);

                if (is_this)
                    selected = this._editorTextPlusPlacements[i];
            }
            if (!selected.title)
                return;
            var tab = selected.title.split(" ");
            this._editorConfig["drawPlus"]["placement"] = {
                "vertical": tab[0],
                "horizontal": tab[1]
            }
            this.editorUpdateTextPlus();
        });
        this._editorTextPlusPlacements = [
            this.editorTextPlusPlacementTopLeft,
            this.editorTextPlusPlacementTopCenter,
            this.editorTextPlusPlacementTopRight,
            this.editorTextPlusPlacementMiddleLeft,
            this.editorTextPlusPlacementMiddleCenter,
            this.editorTextPlusPlacementMiddleRight,
            this.editorTextPlusPlacementBottomLeft,
            this.editorTextPlusPlacementBottomCenter,
            this.editorTextPlusPlacementBottomRight
        ];
        for (var i = 0, len = this._editorTextPlusPlacements.length; i < len; i++)
            on(this._editorTextPlusPlacements[i], "click", this.onEditorTextPlusPlacementClick);


        //Prepare Shadow measure for Edit!
        this.showShadowMeasure = lang.hitch(this, this.showShadowMeasure);

        //For shadow measure on Add, spy with dojo.aspect some private methods of drawBox Draw
        var showShadowMeasureOnDraw = lang.hitch(this, function(result) {
            // this.drawBox.drawToolBar._graphic -> graphic
            // this.drawBox.drawToolBar._tGraphic-> part currently drawn
            if(this.drawBox.drawToolBar._graphic && this.drawBox.drawToolBar._graphic.geometry){
                // if part part currently drawn must merge this geom part with other
                if(this.drawBox.drawToolBar._tGraphic && this.drawBox.drawToolBar._tGraphic.geometry){
                    var mergedGeom = geometryEngine.union([this.drawBox.drawToolBar._graphic.geometry, this.drawBox.drawToolBar._tGraphic.geometry]);

                    this.showShadowMeasure({
                        graphic: {
                          geometry: mergedGeom
                        }
                    });
                    console.log("showShadowMeasureOnDraw -> merge previous and current part", mergedGeom);
                }
                else{
                  this.showShadowMeasure({
                      graphic: this.drawBox.drawToolBar._graphic.clone()
                  });
                  console.log("showShadowMeasureOnDraw -> allready drawn", this.drawBox.drawToolBar._graphic.geometry);
                }
            }
            else if(this.drawBox.drawToolBar._tGraphic && this.drawBox.drawToolBar._tGraphic.geometry){
                this.showShadowMeasure({
                    graphic: this.drawBox.drawToolBar._tGraphic.clone()
                });
                console.log("showShadowMeasureOnDraw -> only current part", this.drawBox.drawToolBar._tGraphic.geometry);
            }
            else{
              console.log("No geom INFO", this.drawBox.drawToolBar);
            }
            return result;
        });
        aspect.after(this.drawBox.drawToolBar, "_onClickHandler", showShadowMeasureOnDraw);
        aspect.after(this.drawBox.drawToolBar, "_onDblClickHandler", showShadowMeasureOnDraw);
        aspect.after(this.drawBox.drawToolBar, "_onMouseDragHandler", showShadowMeasureOnDraw);
        aspect.after(this.drawBox.drawToolBar, "_onMouseMoveHandler", showShadowMeasureOnDraw);
        aspect.after(this.drawBox.drawToolBar, "activate", lang.hitch(this, function() {
            this._showShadowMeasure = true;
        }));
        /*this.drawBox.on("drawActivate", lang.hitch(this, function(){
            this._showShadowMeasure = true;
        }));
        this.drawBox.on("drawDeactivate", lang.hitch(this, function(){
            this._showShadowMeasure = false;
        }));*/
    },

    _menuInit: function() {
        this._menuButtons = {
            "add": this.menuAddButton,
            "edit": this.menuEditButton,
            "list": this.menuListButton,
            "importExport": this.menuListImportExport
        };

        var views = [this.addSection, this.editorSection, this.listSection];

        this.TabViewStack = new ViewStack({
            viewType: 'dom',
            views: views
        });
        html.place(this.TabViewStack.domNode, this.settingAllContent);
    },

    _initLocalStorage: function() {
        if (!this.config.allowLocalStorage)
            return;

        this._localStorageKey =
            (this.config.localStorageKey) ? 'WebAppBuilder.2D.eDraw.' + this.config.localStorageKey : 'WebAppBuilder.2D.eDraw';

        var content = localStore.get(this._localStorageKey);

        if (!content || !content.features || content.features.length < 1)
            return;

        //Closure with timeout to be sure widget is ready
        (function(widget) {
            setTimeout(
                function() {
                    widget.importJsonContent(content, "name", "description");
                    widget.showMessage(widget.nls.localLoading);
                }, 200);
        })(this);

    },

    _initDrawingPopupAndClick: function() {
        //Set popup template
        var infoTemplate = new esri.InfoTemplate("${name}", "${description}");
        this.drawBox.drawLayer.setInfoTemplate(infoTemplate);

        //Set draw click
        this._onDrawClick = lang.hitch(this, function(evt) {
            if (!evt.graphic)
                return;

            this._editorConfig["graphicCurrent"] = evt.graphic;
            this.setMode("list");
        });

        //Allow click
        this.allowPopup(true);

    },

    _initListDragAndDrop: function() {
        this._listOnDragOver = lang.hitch(this, this._listOnDragOver);
        this._listOnDragStart = lang.hitch(this, this._listOnDragStart);
        this._listOnDrop = lang.hitch(this, this._listOnDrop);

        //Bind actions
        on(this.drawsTableBody, "dragover", this._listOnDragOver);
        on(this.drawsTableBody, "drop", this._listOnDrop);
    },

    _initUnitSelect: function() {
        this._initDefaultUnits();
        this._initConfigUnits();
        var a = this.configDistanceUnits;
        var b = this.defaultDistanceUnits;
        this.distanceUnits = a.length > 0 ? a : b;
        var c = this.configAreaUnits;
        var d = this.defaultAreaUnits;
        this.areaUnits = c.length > 0 ? c : d;
        array.forEach(this.distanceUnits, lang.hitch(this, function(unitInfo) {
            var option = {
                value: unitInfo.unit,
                label: unitInfo.label
            };
            this.distanceUnitSelect.addOption(option);
        }));

        array.forEach(this.areaUnits, lang.hitch(this, function(unitInfo) {
            var option = {
                value: unitInfo.unit,
                label: unitInfo.label
            };
            this.areaUnitSelect.addOption(option);
        }));
    },

    _initDefaultUnits: function() {
        this.defaultDistanceUnits = [{
            unit: 'KILOMETERS',
            label: this.nls.kilometers
        }, {
            unit: 'MILES',
            label: this.nls.miles
        }, {
            unit: 'METERS',
            label: this.nls.meters
        }, {
            unit: 'NAUTICAL_MILES',
            label: this.nls.nauticals
        }, {
            unit: 'FEET',
            label: this.nls.feet
        }, {
            unit: 'YARDS',
            label: this.nls.yards
        }];

        this.defaultAreaUnits = [{
            unit: 'SQUARE_KILOMETERS',
            label: this.nls.squareKilometers
        }, {
            unit: 'SQUARE_MILES',
            label: this.nls.squareMiles
        }, {
            unit: 'ACRES',
            label: this.nls.acres
        }, {
            unit: 'HECTARES',
            label: this.nls.hectares
        }, {
            unit: 'SQUARE_METERS',
            label: this.nls.squareMeters
        }, {
            unit: 'SQUARE_FEET',
            label: this.nls.squareFeet
        }, {
            unit: 'SQUARE_YARDS',
            label: this.nls.squareYards
        }];
    },

    _initConfigUnits: function() {
        array.forEach(this.config.distanceUnits, lang.hitch(this, function(unitInfo) {
            var unit = unitInfo.unit;
            if (esriUnits[unit]) {
                var defaultUnitInfo = this._getDefaultDistanceUnitInfo(unit);
                unitInfo.label = defaultUnitInfo.label;
                this.configDistanceUnits.push(unitInfo);
            }
        }));

        array.forEach(this.config.areaUnits, lang.hitch(this, function(unitInfo) {
            var unit = unitInfo.unit;
            if (esriUnits[unit]) {
                var defaultUnitInfo = this._getDefaultAreaUnitInfo(unit);
                unitInfo.label = defaultUnitInfo.label;
                this.configAreaUnits.push(unitInfo);
            }
        }));
    },

    //////////////////////////// WIDGET CORE METHODS ///////////////////////////////////////////////////////////////////////////////////////

    postMixInProperties: function() {
        this.inherited(arguments);
        this._resetUnitsArrays();
    },

    postCreate: function() {
        this.inherited(arguments);

        // load projection module
        projection.load();

        //Create symbol chooser
        this.editorSymbolChooser = new SymbolChooser({
                "class": "full-width",
                "type": "text",
                "symbol": new SimpleMarkerSymbol()
            },
            this.editorSymbolChooserDiv);

        this.drawBox.setMap(this.map);

        //Initialize menu
        this._menuInit();

        //Init measure units
        this._initUnitSelect();

        //Bind and hitch events
        this._bindEvents();

        //Prepare text plus
        this._prepareTextPlus();

        //load if drawings in localStorage
        this._initLocalStorage();

        //Popup or click init
        this._initDrawingPopupAndClick();

        //Create edit dijit and listen it
        this._editorConfig["editToolbar"] = new Edit(this.map);
        this._editorConfig["editToolbar"].on("graphic-move", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("graphic-move-stop", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("scale", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("scale-stop", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("vertex-add", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("vertex-delete", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("vertex-move", this.showShadowMeasure);
        this._editorConfig["editToolbar"].on("vertex-move-stop", this.showShadowMeasure);

        //Init list Drag & Drop
        this._initListDragAndDrop();

    },

    _prepareTextPlus: function() {
        //Select central position in UI (text placement)
        this._UTIL__enableClass(this._editorTextPlusPlacements[4], 'selected', true);

        //Manage availaible FontFamily
        if (this.config.drawPlus && this.config.drawPlus.fontFamilies) {
            if (this.config.drawPlus.fontFamilies.length > 0) {
                this.editorTextPlusFontFamilyNode.set("options", this.config.drawPlus.fontFamilies).reset();
            }
        }

    },

    onOpen: function () {
        ///kevin m - resize to make it a little bit wider ////
        var panel = this.getPanel();
        panel.position.width = 420;
        panel.position.height = 430;

            panel.setPosition(panel.position);
            panel.panelManager.normalizePanel(panel);
        

        if (this.drawBox.drawLayer.graphics.length > 0)
            this.setMode("list");
        else
            this.setMode("add1");
    },

    onClose: function() {
        this.editorResetGraphic();
        this.drawBox.deactivate();
        this.setInfoWindow(false);
        this.editorEnableMapPreview(false);
        this.editorActivateGeometryEdit(false);
        this.map.infoWindow.hide();
        this.allowPopup(true);
    },

    destroy: function() {
        if (this.drawBox) {
            this.drawBox.destroy();
            this.drawBox = null;
        }
        if (this.editorSymbolChooser) {
            this.editorSymbolChooser.destroy();
            this.editorSymbolChooser = null;
        }
        this.inherited(arguments);
    },

    ///////////////////////// UTILS METHODS ////////////////////////////////////////////////////////////////////////////
    _UTIL__enableClass: function(elt, className, bool) {
        if (elt.classList) {
            if (bool)
                elt.classList.add(className);
            else
                elt.classList.remove(className);
            return;
        }
        elt.className = elt.className.replace(className, "").replace("  ", " ").trim();
        if (bool)
            elt.className += className;
    },

    _UTIL__getParentByTag: function(el, tagName) {
        tagName = tagName.toLowerCase();
        while (el && el.parentNode) {
            el = el.parentNode;
            if (el.tagName && el.tagName.toLowerCase() == tagName) {
                return el;
            }
        }
        return null;
    }

});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

});

Please sign in to comment.