Source: widgets/SpwMapDataController.js

Retour à la documentation
/**
 * @class spw.widgets.SpwMapDataController
 */
define([
        "dojo/_base/declare", "spw/api/SpwBaseWidget", "dijit/Menu", "dojo/_base/array",
        "dijit/MenuItem", "dojo/_base/lang", "dojo/dom-construct", "dijit/PopupMenuItem",
        "dijit/DropDownMenu", "dojo/on", "dojo/dom-class", "dojo/aspect", "dijit/popup",
        "spw/api/SpwBaseTemplatedWidget", "spw/widgets/SpwServiceOrLayerTools",
        "dojo/dom-geometry", "spw/widgets/SpwQuerySearch", "spw/api/StateManager", "dojo/dom-style",
        "dijit/Dialog", "spw/widgets/SpwLegend", "spw/api/ConfigLoader", "spw/api/LocalStorageManager",
        "spw/api/Utils", "spw/api/MapServiceFactory", "dojo/query", "dijit/Tooltip", "dijit/form/ValidationTextBox",
        "spw/widgets/SpwIWantTo", "dojo/touch", "esri/request", "dijit/form/HorizontalSlider", "dijit/form/Button", "dojo/_base/config",
        "spw/api/DataMapService"],
    function (declare, SpwBaseWidget, Menu, array, MenuItem, lang, domConstruct,
              PopupMenuItem, DropDownMenu, on, domClass, aspect, popup,
              SpwBaseTemplatedWidget, SpwServiceOrLayerTools, domGeom, SpwQuerySearch, StateManager, domStyle,
              Dialog, SpwLegend, ConfigLoader, LocalStorageManager, Utils, MapServiceFactory, query,
              Tooltip, ValidationTextBox, SpwIWantTo, touch, request, HorizontalSlider, Button, dojoConfig, DataMapService) {

        var SpwMapDataController = declare("spw.widgets.SpwMapDataController", [SpwBaseWidget], /** @lends spw.widgets.SpwMapDataController.prototype */{

            serviceNameSuffix: '<span style="color: #f00; padding-left: 5px;"><br>(Édition en cours)</span>',

            watchHandlers: null,
            allowSelectionEmpty: true,
            preselectedServices: null,
            
            actions: ['tools', /*'legend',*/'visibility', 'remove', 'sort'],
            customActions: null,
            layerActions: ['tools', 'legend', 'visibility'],
            customLayerActions: null,

            simplifiedQuery: false,
            showQueryInAdvancedQueryTool: false,
            forceDeleteOnRemoveAll: true,

            "activated": true,
            "timeTravelWidth": '500px',
            "timeTravelHeight": '220px',
            "timeTravelPosition": null,
            "timeTravelMobile": null,
            "position": "left",
            "reportUrl": dojoConfig.geoviewerApiUrl + "/Report",
            "style": {
                "width": "100%",
                "height": "100%",
                "backgroundColor": "white"
            },
            "launcher": {
                "items": [
                	{
                        "label": "Ajouter des données",
                        "content": [{
                        	"widgetId": "SpwAddDataFromIframeId",
                            "integrated": true
                        }]
                	},
                    {
                        "label": "Ajouter des données",
                        "content": [
                            {
                                "label": "Ajouter des données du Géoportail de la Wallonie",
                                "content": [
                                    
                                ]
                            },
                            {
                                "label": "Ajouter un service<br/>(ArcGIS, WMS, ...)",
                                "content": [
                                    {
                                        "widgetId": "SpwAddMapServiceId",
                                        "popupDim": {
                                            "width": "610px",
                                            "height": "480px"
                                        },
                                        "integrated": true
                                    }
                                ]
                            },
                            {
                                "label": "Ajouter un fichier",
                                "content": [
                                    {
                                        "widgetId": "SpwAddDataFromFileId",
                                        "integrated": true,
                                        "popupDim": {
                                            "width": "580px",
                                            "height": "300px"
                                        }
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },

            /**
             * @constructs
             * @param config
             */
            constructor: function (config) {
                StateManager.getInstance().register(StateManager.MAP_SERVICES_ID,
                    lang.hitch(this, this.getMapServicesState)
                );
                this.watchHandlers = [];
            },

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

            unwatchAll: function () {
                array.forEach(this.watchHandlers, function (h) {
                    h.unwatch();
                });

                this.watchHandlers = [];
            },

            /**
             * Obtenir l'état des services sur base du catalogue
             * @returns {String} état des services du catalogue
             */
            getMapServicesState: function (opts) {

                opts = opts || [];

                var mapServices = this.spwViewer.get('spwMap').getMapServices({
                    isBaseMap: false,
                    inTOC: true
                });

                // on récupère tous les ids présents dans le catalog.json
                // pour savoir quels services il faut stocker en localstorage
                var catalog = ConfigLoader.getInstance().get('catalog');
                var idsInCatalog = [];

                array.forEach(catalog, lang.hitch(this, function (serviceGroup) {
                    if (serviceGroup.code === 'ADDITIONAL_SERVICES') {
                        return;
                    }

                    var services = this.spwViewer.get('spwMap').getServicesFromGroup(serviceGroup);

                    return array.forEach(services, lang.hitch(this, function (service) {
                        idsInCatalog.push(service.serviceId);
                    }));
                }));

                var arrayOfCfg = [];
                var ko = false;

                array.forEach(mapServices, lang.hitch(this,
                    function (mapService) {
                        var cfg = mapService.getServiceConfig();
                        var idx = -1;

                        // si présent dans le catalogue, pas besoin de stocker le tout dans le storage
                        if ((idx = idsInCatalog.indexOf(mapService.get('serviceId'))) >= 0) {
                            idsInCatalog.splice(idx, 1);
                            arrayOfCfg.push(cfg);
                        }
                        else if (cfg.url) {
                            arrayOfCfg.push(cfg);
                        }
                        else if (opts.full) {

                            if (opts.storage == null) {
                                arrayOfCfg.push(cfg);
                            }
                            else if (opts.storage === 'local') {
                                // store in localStorage + add to config
                                var guid = Utils.guid();

                                if (LocalStorageManager.instance().storeItem(guid, cfg)) {
                                    arrayOfCfg.push({
                                        serviceId: guid,
                                        storage: 'local'
                                    });
                                }
                                else {
                                    ko = true;
                                }
                            }
                        }
                    })
                );

                if (ko) {
                    return null;
                }

                array.forEach(idsInCatalog, function (id) {
                    arrayOfCfg.push({
                        serviceId: id,
                        deleted: true
                    });
                });

                return JSON.stringify(arrayOfCfg);
            },

            buildRendering: function (config) {
                this.inherited(arguments);

                on(document, 'focusout', function (evt) {
                    evt.cancelBubble = true;
                    evt.stopPropagation();
                });

                this.loadLauncher();

                this.selection = domConstruct.create("div", {"className": "mapDataControllerSelection"}, this.domNode);
                this.selectionPreText = domConstruct.create("span", {
                    "className": "mapDataControllerSelPreText",
                    innerHTML: "Ma sélection ("
                }, this.selection);
                this.selectionNumber = domConstruct.create("span", {
                    "className": "mapDataControllerSelNumber",
                    innerHTML: "0"
                }, this.selection);
                this.selectionPostText = domConstruct.create("span", {
                    "className": "mapDataControllerSelPostText",
                    innerHTML: ") "
                }, this.selection);
                this.selectionWarningText = domConstruct.create("div", { "class":"warningImg", style:"width:18px;height:15px;background-size:18px 15px;display:inline-block;vertical-align:bottom;", title:"La superposition de données qui n'ont pas été élaborées à partir de la même référence peut mener à des interprétations erronées !" }, this.selection);
                if(this.allowSelectionEmpty){
                    this.selectionEmpty = domConstruct.create("button", {
                        "className": "mapDataControllerSelEmpty",
                        innerHTML: "Vider"
                    }, this.selection);
                    domConstruct.create("img", {
                        "className": "mapDataControllerSelEmptyIcs",
                        src: this.imagesPath + "/empty-selection.png"
                    }, this.selectionEmpty);
                    on(this.selectionEmpty, touch.press, lang.hitch(this, this.removeAllServices));
                }

                this.servicesContainer = domConstruct.create("div", {"className": "mapDataControllerServices"}, this.domNode);

                this.loadPreselectedServices();
                
                this.syncViewServices();
            },

            loadLauncher: function() {
                if (this.launcher && this.launcher.items && this.launcher.items.length == 1) {
                    if (this.menu) {
                        domConstruct.destroy(this.menu.domNode);
                    }
                    this.menu = new SpwIWantTo({
                        spwViewer: this.spwViewer,
                        className: "mapDataControllerMenu",
                        dropDownPosition: ['after'],
                        label: this.launcher.items[0].label,
                        popupClass: "dijitMenuPopup menuControllerMenuPopup",
                        content: this.launcher.items[0].content
                    }, domConstruct.create("div", null, this.domNode));

                    this.menu.startup();

                } else if (this.launcher && this.launcher.items && this.launcher.items.length > 1) {
                    var divContainer = domConstruct.create('div', {
                        'class': 'mapDataControllerTopMenu multiple'
                    }, this.domNode);

                	array.forEach(this.launcher.items, lang.hitch(this, function(i){
                		if(i.content && i.content.length && i.content.length > 1){
                			new SpwIWantTo({
                                spwViewer: this.spwViewer,
                                className: "mapDataControllerMenu multiple",
                                dropDownPosition: ['after'],
                                label: i.label,
                                popupClass: "dijitMenuPopup menuControllerMenuPopup multiple",
                                content: i.content
                            }, domConstruct.create("div", { style: "display: inline-block; width: 100%;"}, divContainer));
                		} else if (i.content) {
                			var btn = new Button({
                                className: "mapDataControllerMenu multiple",
                                label: i.label
                            }, domConstruct.create("div", { style: "display: inline-block; width: 100%;"}, divContainer));
                			domStyle.set(btn.domNode, {
                				"padding": "0 5px 0",
	                		    "width": "100%",
	                		    "boxSizing": "border-box",
	                		    "margin": "0"
                			});
                			domStyle.set(query('.dijitButtonNode', btn.domNode)[0], {"border":"none", "width": "100%", "textAlign": "left"});
                			btn.on('click', lang.hitch(this, function(){
                                var widget = this.spwViewer.spwWidgetsManager.getWidgets({widgetId: i.content[0].widgetId})[0];
                            	if (widget.get('activated')) {
                                    widget.onDeactivate();
                                } else {
                                    widget.onActivate();
                                    if (widget.get('isOneShot')) {
                                        //listItem.set('checked', false);
                                        widget.set('activated', false);
                                    }
                                }
                        	}));

                            var widget = this.spwViewer.spwWidgetsManager.getWidgets({widgetId: i.content[0].widgetId})[0];
                            if (widget) {
                                widget._closeOnSolitary = true;
                            }
                		}
                		else if (i.label) {
                		    domConstruct.create('div', {
                		        innerHTML: i.label,
                                'class': 'mapDataControllerTitleLabel multiple'
                            }, divContainer);
                        }
                	}));
                } else if (this.launcher && this.launcher.items && this.launcher.items.widgetId) {
                    var widget = this.spwViewer.spwWidgetsManager.getWidgets({widgetId: this.launcher.items.widgetId})[0];
                    if (widget) {
                        widget.placeAt(domConstruct.create("div", null, this.domNode));
                        widget._closeOnSolitary = true;
                    }
                }
            },
            
            loadPreselectedServices: function() {
            	if(!this.preselectedServices){
            		return;
            	}
                array.forEach(this.preselectedServices.reverse(), lang.hitch(this, function(ps){
                	var s = null;
                	if(ps instanceof Object && ps.serviceId){
                        var service = this.spwViewer.get('spwMap').getMapServices({ isBaseMap: false, serviceId: ps.serviceId })[0];
                        if(service){
                        	service.moveLayer(100);

                        	if(service.spwMap){
                        		service.spwMap.removeMapService(service.serviceId);
                        		s = lang.mixin(service, ps);
                        	}
                        }
                        else {
                            s = ConfigLoader.getInstance().getServicesAsArray({serviceId: ps.serviceId})[0];
                    		lang.mixin(s, ps);
                        }
                	}
                	else if(ps) {
                        var service = this.spwViewer.get('spwMap').getMapServices({ isBaseMap: false, serviceId: ps })[0];

                        if(service)
                        {
                        	service.moveLayer(100);
                        }
                        else {
                        	s = ConfigLoader.getInstance().getServicesAsArray({serviceId: ps})[0];
                        }
                	}
                	
                	if(s){
                        this.spwViewer.get('spwMap').addMapService(s);
                	}
                }));
            },

            postCreate: function () {
                this.inherited(arguments);
                this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.MapServiceAdded, lang.hitch(this, this.onMapServiceAdded));
                this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.MapServiceRemoved, lang.hitch(this, this.onMapServiceRemoved));
                this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.MapServiceVisibilityChanged, lang.hitch(this, this.waitAndThenSynchronizeServiceView));
                this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.MapExtentChanged, lang.hitch(this, this.syncViewServices));
            },

            waitAndThenSynchronizeServiceView: function() {
                if (this.mapServiceVisibilityChangedTimeOut) {
                    clearTimeout(this.mapServiceVisibilityChangedTimeOut);
                }
                this.mapServiceVisibilityChangedTimeOut = setTimeout(lang.hitch(this, function() {
                    this.onMapServiceVisibilityChanged();
                }, 50))
            },

            onMapServiceAdded: function () {
                this.syncViewServices();
            },

            onMapServiceRemoved: function () {
                this.syncViewServices();
            },

            onMapServiceVisibilityChanged: function () {
                this.syncViewServices();
            },

            removeAllServices: function () {
                var services = this.spwViewer.get('spwMap').getMapServices({isBaseMap: false, inTOC: true});
                array.forEach(services, lang.hitch(this, this.removeService));
            },

            removeService: function (service) {
                if (service.removable != false || this.forceDeleteOnRemoveAll) {
                    this.spwViewer.get('spwMap').removeMapService(service.get("serviceId"));
                }
            },

            syncViewServices: function (serviceToFullyUpdate) {
            	if(!this.get('activated')) return;

            	if(this.spwViewer.get('spwMap')){
	                var services = this.spwViewer.get('spwMap').getMapServices({
	                    isBaseMap: false,
	                    inTOC: true
	                });
	
	                this.unwatchAll();
	                // CECI DETRUIT LES ENFANTS SUR IE11 !!! domConstruct.empty(this.servicesContainer);
	                for(var c; c = this.servicesContainer.lastChild;) {
	                    this.servicesContainer.removeChild(c);
	                }
	
	                if (services.length > 0) {
	                    var cpt = 0;
	
	                    array.forEach(services, lang.hitch(this, function (service, idx) {
	                        // if (service.get('inTOC')) {
	                            // parce qu'on ajoute à l'envers
	                            lang.mixin(service, {
	                                last: service.first, //(idx == 0 && !service.get('inError')) || (services[idx - 1] && services[idx - 1].get('inError') && !service.get('inError')),
	                                first: service.last//(idx == services.length - 1 && !service.get('inError')) || (services[idx + 1] && services[idx + 1].get('inError'))
	                            });
	
	                            if (serviceToFullyUpdate === service) {
	                                this.createServiceDiv(service);
	                            }
	                            else if (service.mapDataControllerService) {
	                                domConstruct.place(service.mapDataControllerService, this.servicesContainer, 'last');
                                    this.syncServiceVisibility(service);
	                            }
	                            else {
	                                this.createServiceDiv(service);
	                            }
	
	                            if (service.mapDataControllerService) {
	                                domClass.remove(service.mapDataControllerService, "first last");
	                                domClass.add(service.mapDataControllerService, service.first ? "first" : "");
	                                domClass.add(service.mapDataControllerService, service.last ? "last" : "");
	                            }
	                            ++cpt;
	                        // }
	
	                        var updateLabel = function (name, old, val) {
	                            if (service.mapDataControllerService == null) {
	                                return;
	                            }
	
	                            var node = query('.mapDataControllerServiceLbl', service.mapDataControllerService);
	
	                            if (service.get('type') === MapServiceFactory.types.DRAW_LAYER && service.get('currentDrawing')) {
	                                if (service.mapDataControllerService.labelSuffix == null) {
	                                    service.mapDataControllerService.labelSuffix = domConstruct.place(this.serviceNameSuffix.trim(), node[0], 'after');
	                                }
	                            }
	                            else if (service.mapDataControllerService.labelSuffix) {
	                                domConstruct.destroy(service.mapDataControllerService.labelSuffix);
	                                service.mapDataControllerService.labelSuffix = null;
	                            }
	
	                            node.every(function (n) {
	                                n.innerHTML = service.get('label');
	                            });
	                            //}
	                        };
	
	                        this.watchHandlers.push(service.watch('label', lang.hitch(this, updateLabel)));
	
	                        this.watchHandlers.push(service.watch('currentDrawing', lang.hitch(this, updateLabel)));
	
	                        this.watchHandlers.push(service.watch('inTOC', lang.hitch(this, function (name, old, val) {
	                            this.syncViewServices();
	                        })));
	
	                        var layers = service.get('mapServiceLayers');
	
	                        array.forEach(layers, lang.hitch(this, function (l) {
	                            this.watchHandlers.push(l.watch('inTOC', lang.hitch(this, function () {
	                                this.syncViewServices(service);
	                            })));
	                        }));
	
	                        if (service.get('inError')) {
	                            this.serviceInError(service);
	                        }
	                        else {
                                this.watchHandlers.push(service.watch('inError', lang.hitch(this, function() {
                                    if (service.get('inError')) {
                                        this.serviceInError(service);
                                    }
                                })));
                            }
	                    }));
	
	                    this.selectionNumber.innerHTML = cpt;
	                } else {
	                    domConstruct.create("div", {
	                        "className": "mapDataControllerNoService",
	                        innerHTML: "Aucune donnée sélectionnée"
	                    }, this.servicesContainer, 'first');
	                    this.selectionNumber.innerHTML = 0;
	                }
	                if(services.length > 1){
	                	this.selectionWarningText.style.display = "inline-block";
	                } else {
	                	this.selectionWarningText.style.display = "none";
	                }
            	}
            },

            createServiceDiv: function (service) {
                var expanded = service.expanded;
                var serviceWrapperDiv = domConstruct.create("div", {"className": "mapDataControllerService disabled" + (expanded ? ' expanded': '')}, this.servicesContainer, 'first');

                var serviceDiv = domConstruct.create("div", {"className": "service"}, serviceWrapperDiv, 'first');
                serviceWrapperDiv.serviceDiv = serviceDiv;

                lang.mixin(service, {mapDataControllerService: serviceWrapperDiv});

                var layers = service.get('mapServiceLayers');

                // collapser
                var collapser = domConstruct.create("span", {
                    "className": "serviceCollapser"
                }, serviceDiv);

                on(collapser, touch.press, lang.hitch(this, this.collapserClicked, service, collapser));

                if (service.openLayersLegend) {
                    this.openCollapser(service);
                }

                if (service.editable && service instanceof DataMapService) {
                    domClass.add(collapser, 'drawLayer');

                    new Tooltip({
                        connectId: [collapser],
                        label: 'Éditer le dessin',
                        position: ['below', 'after']
                    });

                    if (service.get('currentDrawing')) {
                        var tmpSpan = domConstruct.create("span", {
                            "className": "mapDataControllerServiceLbl",
                            innerHTML: service.get('label')
                        }, serviceDiv);

                        service.mapDataControllerService.labelSuffix = domConstruct.place(this.serviceNameSuffix.trim(), tmpSpan, 'after');
                    }
                    else {
                        domConstruct.create("span", {
                            "className": "mapDataControllerServiceLbl",
                            innerHTML: service.get('label')
                        }, serviceDiv);
                    }
                }
                else {
                    domConstruct.create("span", {
                        "className": "mapDataControllerServiceLbl",
                        innerHTML: service.get('label')
                    }, serviceDiv);
                }

                var icons = domConstruct.create("span", {"className": "mapDataControllerServiceIcons"}, serviceDiv);

                array.forEach(this.customActions, lang.hitch(this, function(customAction) {
                    var customIcon = domConstruct.create("span", {
                        "className": "mapDataControllerServiceIcon",
                        "style": customAction.style
                    }, icons);

                    var launcher = new SpwIWantTo({
                        spwViewer: this.spwViewer,
                        className: "customActionDataController",
                        dropDownPosition: ['after'],
                        label: customAction.items[0].label,
                        popupClass: "dijitMenuPopup menuControllerMenuPopup customAction",
                        content: customAction.items[0].content
                    });

                    launcher.startup();

                    on(customIcon, touch.press, lang.hitch(this, function (e) {
                        launcher._button._aroundNode = customIcon;
                        launcher._button.openDropDown();
                    }));
                }));

                if (this.actions) {
                    if (this.actions.indexOf('tools') > -1) {
                        var toolsIcon = domConstruct.create("span", {"className": "mapDataControllerServiceIcon gearIcon"}, icons);

                        on(toolsIcon, touch.press, lang.hitch(this, function (e) {
                            this.serviceToolsClicked(service, toolsIcon, e);
                        }));
                    }
                    
                    if (service.type == 'TIMER') {
                        var timerNode = domConstruct.create('span', {
                            'className': 'mapDataControllerServiceIcon timerIcon'
                        }, icons);

                        on(timerNode, touch.press, lang.hitch(this, this.serviceTimerClicked, service));
                    }

                    if (this.actions.indexOf('legend') > -1 && service.hasLegend) {
                        var legendNode = domConstruct.create('span', {
                            'className': 'mapDataControllerServiceIcon legendIcon'
                        }, icons);

                        on(legendNode, touch.press, lang.hitch(this, this.serviceLegendClicked, service));
                    }

                    if (this.actions.indexOf('visibility') > -1) {
                        var eyeNode = domConstruct.create("span", {
                            "className": "mapDataControllerServiceIcon eyeIcon"
                        }, icons);

                        on(eyeNode, touch.press, lang.hitch(this, this.serviceVisibilityClicked, service));

                        if (!service.get('visible')) {
                            domClass.add(service.mapDataControllerService, 'invisible');
                        }
                    }

                    if (this.actions.indexOf('remove') > -1 && service.removable !== false) {
                        on(domConstruct.create("span", {
                            "className": "mapDataControllerServiceIcon trashIcon"
                        }, icons), touch.press, lang.hitch(this, this.removeService, service));
                    }

                    if (this.actions.indexOf('sort') > -1) {
                        var updown = domConstruct.create("div", {"className": "mapDataControllerServiceUpDown"}, icons);

                        on(domConstruct.create("span", {
                            "className": "mapDataControllerServiceIconUp"
                        }, updown), touch.press, lang.hitch(this, this.serviceUpClicked, service));

                        on(domConstruct.create("span", {
                            "className": "mapDataControllerServiceIconDown"
                        }, updown), touch.press, lang.hitch(this, this.serviceDownClicked, service));
                    }
                }

                var hdls = [];

                if (service.get('loaded') && service.mapServiceLayers) {
                    if (service.get('inError')) {
                        this.serviceInError(service);
                    } else {
                        hdls = hdls.concat(this.createServiceView(service));
                    }
                } else if (service.mapServiceLayers) {
                    hdls.push(service.on(service.events.MapServiceLoaded, lang.hitch(this, function () {
                        hdls = hdls.concat(this.createServiceView(service));
                    })));

                    hdls.push(service.on(service.events.MapServiceError, lang.hitch(this, function () {
                        this.serviceInError(service);
                    })));

                    if (service.get('inError')) {
                        this.serviceInError(service);
                    }
                }

                on.once(this.spwViewer.get('spwMap'), this.spwViewer.get('spwMap').events.MapCreated, lang.hitch(this, function (map) {
                    array.forEach(hdls, function (h) {
                        h.remove();
                    });
                }));
            },

            serviceLegendClicked: function(service) {
            	if(service.get('legendUrl')){
            		window.open(service.get('legendUrl'));
            	} else if (!service.get('legendLoaded')) {
                    on.once(service, service.events.MapServiceLegendLoaded, lang.hitch(this, this.buildServiceLegend, service));
                    service.loadLegend();
                }
                else {
                    this.buildServiceLegend(service);
                }
            },
            
            serviceTimerClicked: function(service) {
            	require(["spw/widgets/SpwTimeTravel"], lang.hitch(this, function(SpwTimeTravel){
            		if(!service.timeTravelWidget){
                		service.timeTravelWidget = new SpwTimeTravel({
                            service: service,
                            spwViewer: this.spwViewer,
                            width: this.timeTravelWidth,
                            height: this.timeTravelHeight,
                            position: this.timeTravelPosition || 'panel-light',
                            mobile: this.timeTravelMobile
                        });
            		}
            		
            		if(service.timeTravelWidget._shown) {
                		service.timeTravelWidget.hide();
            		} else {
                		service.timeTravelWidget.show();
            		}
            	}));
            },

            buildServiceLegend: function(service) {
                service.mapDataControllerLegendEnabled = !service.mapDataControllerLegendEnabled;

                for (k in service.mapServiceLayers) {
                    if (service.mapServiceLayers[k].get('inTOC') && !service.mapServiceLayers[k].parentLayer) {
                        this.buildLayerLegend(service.mapServiceLayers[k], service.mapDataControllerLegendEnabled);
                    }
                }
                
            },

            buildLayerLegend: function(mapServiceLayer, legendService) {
            	if(mapServiceLayer.get('legendUrl')){
            		window.open(mapServiceLayer.get('legendUrl'));
            		return;
            	}
            		
                if (typeof legendService !== 'boolean') {
                    legendService = null;
                }

                var container = mapServiceLayer.mapDataControllerLayer;

                if (container == null) {
                    return;
                }

                var subLayers = array.filter(mapServiceLayer.subLayers, function (l) {
                    return l.get('inTOC');
                });

                if (subLayers && subLayers.length > 0) {
                    array.forEach(subLayers, lang.hitch(this, this.buildLayerLegend));
                    return;
                }

                if (container.legendCreated !== true) {
                    array.forEach(mapServiceLayer.legends, lang.hitch(this, function(leg, idx) {

                        var newId = mapServiceLayer.id + '-legend' + idx;

                        var legendContainer = domConstruct.create('div', {
                            'class': 'legendContainer'
                        }, container);

                        legendContainer.style.height = leg.height + 'px';

                        var style = '"width:'+leg.width+'px; height:'+leg.height+'px; padding-right: 10px; float: left;"';

                        var label = '<img class="legendSymbol" style='+style +
                            'src="data:' + leg.contentType + ';base64,' + leg.imageData + '"/> ' +
                            (leg.label ? leg.label : mapServiceLayer.name);

                        if (leg.url && leg.url.indexOf("http") === 0){
                            label = '<img class="legendSymbol" style='+style +
                                'src="' + leg.url + '"/> ';
                        }

                        domConstruct.place(label, legendContainer);
                    }));

                    // if (mapServiceLayer.legends && mapServiceLayer.legends.length > 0) {
                    //     var collapser = domConstruct.create("span", {
                    //         "className": "layerCollapser"
                    //     }, mapServiceLayer.mapDataControllerLayerDiv, 'first');
                    //
                    //     on(collapser, touch.press, lang.hitch(this, this.layerCollapserClicked, mapServiceLayer));
                    // }
                }

                if (legendService === true) {
                    domClass.add(mapServiceLayer.mapDataControllerLayer, "expanded")
                    domClass.add(container, 'showLegend');
                }
                else if (legendService === false) {
                    domClass.remove(container, 'showLegend');
                }
                else {
                    domClass.toggle(container, 'showLegend');
                    if (domClass.contains(container, 'showLegend')) {
                        domClass.add(mapServiceLayer.mapDataControllerLayer, "expanded");
                    }
                }
                container.legendCreated = true;
            },

            serviceInError: function (service) {
                if (service.mapDataControllerService == null) {
                    return;
                }

                if (domClass.contains(service.mapDataControllerService, 'error')) {
                    if (!domClass.contains(service.mapDataControllerService, 'disabled')) {
                        domClass.add(service.mapDataControllerService, 'disabled')
                    }
                    return;
                }

                domClass.add(service.mapDataControllerService, "error");

                domConstruct.create("div", {
                    "className": "mapDataControllerServiceInfo",
                    innerHTML: service.get('errorMessage') ? service.get('errorMessage') : 'Ce service est en erreur.'
                }, service.mapDataControllerService.children[0], 'last');
            },

            getScaleMessage: function (service) {
                var scaleMsg = "";

                if (service.minScale !== 0 && service.maxScale !== 0) {
                    scaleMsg = "Donnée visible entre les échelles 1:" + service.maxScale + " et 1:" + service.minScale + "."
                } else if (service.minScale === 0 && service.maxScale !== 0) {
                    scaleMsg = "Donnée visible en dessous de l'échelle 1:" + service.maxScale + "."
                } else if (service.minScale !== 0 && service.maxScale === 0) {
                    scaleMsg = "Donnée visible au-dessus de l'échelle 1:" + service.minScale + "."
                } else {
                    scaleMsg = "Donnée visible à toutes les échelles."
                }
                return scaleMsg;
            },

            createServiceView: function (service) {
                var scaleMsg = this.getScaleMessage(service);

                var layers = service.get('mapServiceLayers');

                domConstruct.create("div", {
                    "className": "mapDataControllerServiceInfo",
                    innerHTML: scaleMsg
                }, service.mapDataControllerService.children[0], 'last');

                var layersDiv = domConstruct.create("div", {"className": "mapDataControllerLayers"}, service.mapDataControllerService, 'last');

                for (k in service.mapServiceLayers) {
                    if (service.mapServiceLayers[k].get('inTOC') && !service.mapServiceLayers[k].parentLayer) {
                        this.createLayerDiv(service.mapServiceLayers[k], layersDiv, service);
                    }
                }
                
                if(service.type === "TIMER"){
                	for(var i = 0; i < service.mapServices.length ; i++) {
                    	this.createLayerDiv(service.mapServices[i], layersDiv, service);
                	}
                }

                var hdls = [];

                if (service.layer._map) {
                    this.syncServiceVisibility(service);
                } else {
                    hdls.push(this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.LayerAdd, lang.hitch(this, function (evt) {
                        if (evt.layer.id === service.layer.id) {
                            this.syncServiceVisibility(service);
                        }
                    })));
                }

                return hdls;
            },

            syncServiceVisibility: function (service) {
                if (service == null || service.mapDataControllerService == null) {
                    return;
                }

                if (service.layer && service.layer.visibleAtMapScale) {
                    domClass.remove(service.mapDataControllerService, "disabled");
                }
                else {
                    domClass.add(service.mapDataControllerService, "disabled");
                }

                if(service.visible == false){
                    domClass.add(service.mapDataControllerService, "invisible");
                }else{
                    domClass.remove(service.mapDataControllerService, "invisible");
                }

                var syncVisibilityFunc = function(mapServiceLayer, doIt) {
                    if (mapServiceLayer.mapDataControllerLayer == null || !mapServiceLayer.get('inTOC') || mapServiceLayer.visibleAtCurrentScale == null) {
                        return;
                    }

                    // CHANGED ON THE 12/04 AFTER BAD MEP: service visibility not sync with map while added from catalog on a scale where the layer isnt visible
                    if (mapServiceLayer.get('visible')) {
                        // domClass.remove(mapServiceLayer.mapDataControllerLayer, "disabled");
                        domClass.remove(mapServiceLayer.mapDataControllerLayer, "invisible");
                    } else {
                        // domClass.add(mapServiceLayer.mapDataControllerLayer, "disabled");
                        domClass.add(mapServiceLayer.mapDataControllerLayer, "invisible");
                    }

                    if (mapServiceLayer.visibleAtCurrentScale()) {
                        domClass.remove(mapServiceLayer.mapDataControllerLayer, "disabled");
                    } else {
                        domClass.add(mapServiceLayer.mapDataControllerLayer, "disabled");
                    }

                    array.forEach(mapServiceLayer.subLayers, lang.hitch(this, syncVisibilityFunc));
                };

                for (var k in service.mapServiceLayers) {
                    syncVisibilityFunc(service.mapServiceLayers[k], false);
                }
            },

            createLayerDiv: function (layer, layersDiv, service) {
                var expanded = service.layersExpanded[layer.layerId];
                var layerWrapperDiv = domConstruct.create("div", {"className": "mapDataControllerLayer" + (expanded ? ' expanded' : '')}, layersDiv);
                var layerDiv = domConstruct.create("div", {"className": "layer"}, layerWrapperDiv);

                lang.mixin(layer, {mapDataControllerLayer: layerWrapperDiv, mapDataControllerLayerDiv: layerDiv});

                var subLayers = array.filter(layer.subLayers, function (l) {
                    return l.get('inTOC');
                });

                if (subLayers && subLayers.length > 0) {
                    var collapser = domConstruct.create("span", {
                        "className": "layerCollapser"
                    }, layerDiv);

                    on(collapser, touch.press, lang.hitch(this, this.layerCollapserClicked, layer));

                    if (service.openLayersLegend && layer.get('visible') && !expanded) {
                    	if(service.openLayersLegend.indexOf){
                    		if(service.openLayersLegend.indexOf(layer.layerId) > -1){
                                this.layerCollapserClicked(layer);
                    		}
    					} else {
                            this.layerCollapserClicked(layer);
    					}
                    }
                } else {
                    domClass.add(layerWrapperDiv, "leaf");
                }

                if(service.type !== "TIMER"){
                    domConstruct.create("span", {
                        "className": "mapDataControllerLayerLbl",
                        innerHTML: layer.get('name')
                    }, layerDiv);

                    var icons = domConstruct.create("span", {"className": "mapDataControllerLayerIcons"}, layerDiv);
	
	                array.forEach(this.customLayerActions, lang.hitch(this, function(customAction) {
	                    var customIcon = domConstruct.create("span", {
	                        "className": "mapDataControllerServiceIcon",
	                        "style": customAction.style
	                    }, icons);
	
	                    var launcher = new SpwIWantTo({
	                        spwViewer: this.spwViewer,
	                        className: "customActionDataController",
	                        dropDownPosition: ['after'],
	                        label: customAction.items[0].label,
	                        popupClass: "dijitMenuPopup menuControllerMenuPopup customAction",
	                        content: customAction.items[0].content
	                    });
	
	                    launcher.startup();
	
	                    on(customIcon, touch.press, lang.hitch(this, function (e) {
	                        launcher._button._aroundNode = customIcon;
	                        launcher._button.openDropDown();
	                    }));
	                }));
	
	                if (this.layerActions) {
	                    if (this.layerActions.indexOf('tools') > -1) {
	                        var toolsIcon = domConstruct.create("span", {"className": "mapDataControllerLayerIcon gearIcon"}, icons);
	
	                        on(toolsIcon, touch.press, lang.hitch(this, function (e) {
	                            this.layerToolsClicked(layer, toolsIcon, e);
	                        }));
	                    }

	                    if (this.layerActions.indexOf('legend') > -1
                            && (subLayers == null || subLayers.length < 1)) {
	                        if(layer.mapService.get('legendUrl') == null) {
                                var legendNode = domConstruct.create('span', {
                                    'className': 'mapDataControllerServiceIcon legendIcon'
                                }, icons);
                                on(legendNode, touch.press, lang.hitch(this, this.buildLayerLegend, layer));
                            }
	                    }
	                    if(subLayers == null || subLayers.length < 1) {
	                        var autoOpenLegend = lang.hitch(this, function(){
	                            if(service.openLayersLegend){
	                            	if(service.openLayersLegend.indexOf){
	                            		if(service.openLayersLegend.indexOf(layer.layerId) > -1){
	                            			this.buildLayerLegend(layer, true);
	                            		}
	            					} else {
	                            		this.buildLayerLegend(layer, true);
	            					}
	                            }
	                        });
	                        if(service.legendLoaded) {
	                        	autoOpenLegend();
	                        } else {
	                        	service.on(service.events.MapServiceLegendLoaded, autoOpenLegend);
	                        }
	                    }
	                    if (this.layerActions.indexOf('visibility') > -1 && layer.mapService.type!="AGS_TILED") {
	                        var eyeNode = domConstruct.create("span", {
	                            "className": "mapDataControllerLayerIcon eyeIcon"
	                        }, icons);
	
	                        on(eyeNode, touch.press, lang.hitch(this, this.layerVisibilityClicked, layer));
	                        if (!layer.get('visibility')) {
	                            domClass.add(layer.mapDataControllerLayer, 'invisible');
	                        }
	                    }
	                }
                } else {
                    domConstruct.create("span", {
                        "className": "mapDataControllerLayerLbl",
                        innerHTML: layer.get('description')
                    }, layerDiv);
                }

                var scaleMsg = this.getScaleMessage(layer);

                domConstruct.create("div", {
                    "className": "mapDataControllerLayerInfo",
                    innerHTML: scaleMsg
                }, layerDiv, 'last');

                if (subLayers && subLayers.length > 0) {
                    var subLayersDiv = domConstruct.create("div", {"className": "mapDataControllerLayers"}, layerWrapperDiv, 'last');
                    for (var i = 0; i < subLayers.length; i++) {
                        this.createLayerDiv(subLayers[i], subLayersDiv, service);
                    }
                }
            },

            serviceToolsClicked: function (service, toolsIcon, e) {
                var tools = service.toolsWidget;
                if (!tools) {
                    tools = service.toolsWidget = new SpwServiceOrLayerTools({
                        minScale: service.minScale,
                        maxScale: service.maxScale,
                        opacity: service.get('alpha'),
                        imagesPath: this.imagesPath,
                        spwViewer: this.spwViewer,
                        service: service,
                        reportUrl: this.reportUrl,
                        simplifiedQuery: this.simplifiedQuery,
                        showQuery: this.showQueryInAdvancedQueryTool
                    });
                }
                popup.open({
                    parent: this,
                    popup: tools,
                    around: toolsIcon,
                    orient: ["after-centered"],
                    onExecute: function () {
                        popup.close(tools);
                    },
                    onCancel: function () {
                        popup.close(tools);
                    },
                    onClose: function () {
                        tools._closeOnClickListener.remove();
                    }
                });
                setTimeout(function () {
                    tools._closeOnClickListener = on(document, touch.press, function (e) {
                        if (!tools._mouseInside) {
                            popup.close(tools);
                        }
                    });
                });
                on(tools.domNode, 'mouseover', function (e) {
                    tools._mouseInside = true;
                });
                on(tools.domNode, 'mouseout', function (e) {
                    tools._mouseInside = false;
                });
                domClass.add(tools._popupWrapper, "toolsPopup");
            },

            layerToolsClicked: function (layer, toolsIcon, e) {
                var tools = layer.toolsWidget;
                if (!tools) {
                    tools = layer.toolsWidget = new SpwServiceOrLayerTools({
                        minScale: layer.minScale,
                        maxScale: layer.maxScale,
                        opacity: 100/*layer.get('alpha')*/,
                        imagesPath: this.imagesPath,
                        spwViewer: this.spwViewer,
                        layer: layer,
                        parentWidget: this,
                        reportUrl: this.reportUrl,
                        simplifiedQuery: this.simplifiedQuery
                    });
                }
                popup.open({
                    parent: this,
                    popup: tools,
                    around: toolsIcon,
                    orient: ["after-centered"],
                    onExecute: function () {
                        popup.close(tools);
                    },
                    onCancel: function () {
                        popup.close(tools);
                    },
                    onClose: function () {
                        tools._closeOnClickListener.remove();
                    }
                });
                setTimeout(function () {
                    tools._closeOnClickListener = on(document, touch.press, function (e) {
                        if (!tools._mouseInside) {
                            popup.close(tools);
                        }
                    });
                });
                on(tools.domNode, 'mouseover', function (e) {
                    tools._mouseInside = true;
                });
                on(tools.domNode, 'mouseout', function (e) {
                    tools._mouseInside = false;
                });
                domClass.add(tools._popupWrapper, "toolsPopup");
            },

            openCollapser: function (service) {
                if (!domClass.contains(service.mapDataControllerService, "expanded")) {
                    domClass.add(service.mapDataControllerService, "expanded");
                    service.expanded = true;
                }
            },

            collapserClicked: function (service, collapser) {
                if (domClass.contains(collapser, 'drawLayer')) {
                    this.spwViewer.get('spwMap').editService(service);
                    return;
                }

                if (domClass.contains(service.mapDataControllerService, "expanded")) {
                    domClass.remove(service.mapDataControllerService, "expanded");
                    service.expanded = false;
                } else {
                    domClass.add(service.mapDataControllerService, "expanded");
                    service.expanded = true;
                }
            },

            layerCollapserClicked: function (layer) {
                if (domClass.contains(layer.mapDataControllerLayer, "expanded")) {
                    domClass.remove(layer.mapDataControllerLayer, "expanded");
                    layer.mapService.layersExpanded[layer.layerId] = false;
                } else {
                    domClass.add(layer.mapDataControllerLayer, "expanded");
                    layer.mapService.layersExpanded[layer.layerId] = true;
                }
            },

            serviceVisibilityClicked: function (service) {
                if (!domClass.contains(service.mapDataControllerService, "disabled")) {
                    if (domClass.contains(service.mapDataControllerService, "invisible")) {
                        domClass.remove(service.mapDataControllerService, "invisible");
                        service.show();
                    } else {
                        domClass.add(service.mapDataControllerService, "invisible");
                        service.hide();
                    }
                }
            },

            layerVisibilityClicked: function (layer) {
                if (!domClass.contains(layer.mapDataControllerLayer, "disabled")) {
                    var syncLayerVisibilityFunc = function(mapServiceLayer) {
                        if (domClass.contains(mapServiceLayer.mapDataControllerLayer, "invisible")) {
                            domClass.remove(mapServiceLayer.mapDataControllerLayer, "invisible");
                            mapServiceLayer.show();
                        } else {
                            domClass.add(mapServiceLayer.mapDataControllerLayer, "invisible");
                            mapServiceLayer.hide();
                        }

                        // array.forEach(mapServiceLayer.subLayers, lang.hitch(this, syncLayerVisibilityFunc));
                    };

                    syncLayerVisibilityFunc(layer);
                }
            },

            serviceUpClicked: function (service) {
                if (!service.first) {
                    service.moveUp();
                    this.syncViewServices();
                }
            },

            serviceDownClicked: function (service) {
                if (!service.last) {
                    service.moveDown();
                    this.syncViewServices();
                }
            },

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

            onActivate: function () {
                this.inherited(arguments);
                
                this.syncViewServices();
            },

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

            destroy: function () {
                this.inherited(arguments);
            }
        });

        return SpwMapDataController;
    });