'use strict';
define(function() {
  var calageRaster = function(
    gcPropertiesLayers,
    gclayers,
    ParametersFactory,
    FilesFactory,
    ngDialog,
    extendedNgDialog,
    RasterFactory,
    $filter,
    gcPopup,
    gcInteractions,
    PortalsFactory
  ) {
    return {
      templateUrl: 'js/XG/widgets/mapapp/rastercalage/views/calageraster.html',
      restrict: 'A',

      link: function(scope, elt, attrs, ctrl) {
        var mode = '';
        var map = scope.map;

        var portalid = angular.module('gcMain').portalid;

        if (portalid == undefined || portalid == '') {
          portalid = PortalsFactory.getPortalId();
        }
        scope.res = [];
        //Extent en pixel de l'image
        scope.extent = [0, 0, 1024, 968];
        //systeme de projection en pixel
        scope.projection = new ol.proj.Projection({
          code: 'xkcd-image',
          units: 'pixels',
          extent: scope.extent,
        });
        scope.imgHeight = 0;
        scope.imgWidth = 0;

        // définition du style de dessin du feature
        var styleDraw = new ol.style.Style({
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)',
          }),
          stroke: new ol.style.Stroke({
            color: '#ffcc33',
            width: 2,
          }),
          image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
              color: '#ffcc33',
            }),
          }),
        });

        // gestion des points d'edition ps
        scope.source = new ol.source.Vector({ wrapX: false });
        scope.featureOverlay = new ol.layer.Vector({
          source: scope.source,
          style: styleDraw,
        });

        /**
         * Ineraction draw du dessin px
         * @type {ol}
         */
        scope.draw = new ol.interaction.Draw({
          source: scope.source,
          type: /** @type {ol.geom.GeometryType} */ ('Point'),
        });

        scope.draw.set('gctype', 'kis');
        scope.draw.set('interaction', 'Draw');
        scope.draw.set('widget', 'calageraster');

        /**
         * Fonction drawend du dessin px
         * @param  evt
         * @returns {undefined}
         */
        scope.draw.on('drawend', function(evt) {
          //scope.features = evt.feature;
          var format = new ol.format.GeoJSON();
          var feature = format.writeFeatureObject(evt.feature);
          if (scope.radiomode) {
            map.removeInteraction(scope.drawinteraction);
          }
          var resgeometry = feature.geometry;
          var x = resgeometry.coordinates[0];
          var y = scope.imgHeight - resgeometry.coordinates[1];
          scope.res.push({
            Xp: x,
            Yp: y,
            Xg: null,
            Yg: null,
            srid: 'EPSG:3857',
            feat: evt.feature,
            featGeo: null,
          });
          try {
            scope.$apply();
          } catch(err) {}
        });

        scope.mappx = null;
        /////MAP ACTION

        /**
         * Interaction draw Geo
         * @type {ol}
         */
        scope.drawGeo = new ol.interaction.Draw({
          source: scope.sourceGeo,
          type: /** @type {ol.geom.GeometryType} */ ('Point'),
        });
        scope.drawGeo.set('gctype', 'kis');
        scope.drawGeo.set('interaction', 'Draw');
        scope.drawGeo.set('widget', 'calageraster');
        scope.map.addLayer(scope.featureOverlayGeo);

        scope.$on('removelayerraster', function(event) {
          scope.map.removeLayer(scope.layer_preview);
        });

        /**
         * Fonction drawend Geo
         * @param  evt
         * @returns {undefined}
         */
        scope.drawGeo.on('drawend', function(evt) {
          //scope.features = evt.feature;
          var format = new ol.format.GeoJSON();
          var feature = format.writeFeatureObject(evt.feature);
          if (scope.radiomode) {
            map.removeInteraction(scope.drawinteraction);
          }
          var resgeometry = feature.geometry;
          var x = resgeometry.coordinates[0];
          var y = resgeometry.coordinates[1];
          scope.currentFeat.Xg = x;
          scope.currentFeat.Yg = y;
          scope.currentFeat.featGeo = evt.feature;
          //scope.res.push({'Xpx':x,'Ypx':y ,'Xgeo':null,'Ygeo':null,'feat':evt.feature });
          try {
            scope.$apply();
          } catch(err) {}
          scope.map.removeInteraction(scope.drawGeo);
        });

        //FONCTION IHM
        //opacity
        scope.theOpacity = 1.0;
        scope.layeropacity = {
          value: Math.round((1 - scope.theOpacity) * 100 * 2) / 2,
        };
        scope.$watch(
          'layeropacity',
          function(opacity) {
            //console.log(scope.layeropacity.value);
            scope.theOpacity = 1 - scope.layeropacity.value / 100;
            if (
              scope.layer_preview &&
              typeof scope.layer_preview.setOpacity === 'function'
            ) {
              scope.layer_preview.setOpacity(scope.theOpacity);
            }
            //$rootScope.$broadcast('gcOperationalLayerChange',scope.currlayer,"opacity");
          },
          1
        );

        /**
         * [removeFile fonction de suppression de l'image]
         * @returns {undefined}
         */
        scope.removeFile = function() {
          scope.map.removeLayer(scope.layer_preview);
          scope.mappx.setTarget(null);
          scope.source.clear();
          scope.sourceGeo.clear();
          scope.res = [];
          scope.mappx = null;
          scope.staticFileName = null;
          scope.layeropacity.value = 0;
        };
        /**
         * [removeFeat supprime le feature selectionné]
         * @param   index (index du feature)
         * @param   a     (feature)
         * @returns {undefined}
         */
        scope.removeFeat = function(index, a) {
          scope.source.removeFeature(a.feat);
          if (a.featGeo != null) {
            scope.sourceGeo.removeFeature(a.featGeo);
          }
          scope.res.splice(index, 1);
        };
        scope.currentFeat = null;
        /**
         * [addGeo ajoute le featGeo à la map (correspondant au feat de la mappx)]
         * @param index (index du feature)
         * @param  a     (feature)
         */
        scope.addGeo = function(index, a) {
          if (a.featGeo != null) {
            scope.sourceGeo.removeFeature(a.featGeo);
          }

          a.Xg = null;
          a.Yg = null;
          scope.currentFeat = a;
          gcInteractions.setCurrentToolBar(scope.toolBarWidget);
          scope.drawGeo.setActive(true);
          scope.map.addInteraction(scope.drawGeo);
        };

        /**
         * [mouseHighlight mise en évidence du feature au survol de la ligne]
         * @param   index
         * @returns {undefined}
         */
        scope.mouseHighlight = function(index) {
          //// définition du style de mise en évidence du feature
          var index1 = index.toString();
          var styleHighlight = new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'rgba(240, 240, 174, 1)',
              width: 5,
            }),
            fill: new ol.style.Fill({
              color: 'rgba(240,248,255,1)',
            }),
            image: new ol.style.Circle({
              radius: 9,
              fill: new ol.style.Fill({
                color: '#ff0000',
              }),
            }),

            text: new ol.style.Text({
              font: '15px sans-serif,helvetica',
              text: index1,
              textAlign: 'right',
              offsetY: 20,
              offsetX: -5,
              rotation: 0,
              textBaseline: 'alphabetic',
              fill: new ol.style.Fill({
                color: '#ff0000',
              }),
              stroke: new ol.style.Stroke({
                color: '#ddd',
                width: 1,
              }),
            }),
          });
          scope.res[index].feat.setStyle(styleHighlight);
          if (scope.res[index].featGeo != null) {
            scope.res[index].featGeo.setStyle(styleHighlight);
          }
        };

        /**
         * [mouseLeave définition du style hors survol de la ligne ]
         * @param   index
         * @returns {undefined}
         */
        scope.mouseLeave = function(index) {
          var index1 = index.toString();
          var styleLeave = new ol.style.Style({
            fill: new ol.style.Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new ol.style.Stroke({
              color: '#ffcc33',
              width: 2,
            }),
            image: new ol.style.Circle({
              radius: 7,
              fill: new ol.style.Fill({
                color: '#ffcc33',
              }),
            }),
            text: new ol.style.Text({
              font: '15px sans-serif,helvetica',
              text: index1,
              textAlign: 'right',
              offsetY: 20,
              offsetX: -5,
              rotation: 0,
              textBaseline: 'alphabetic',
              fill: new ol.style.Fill({
                color: '#ffcc33',
              }),
              stroke: new ol.style.Stroke({
                color: '#ddd',
                width: 1,
              }),
            }),
          });
          scope.res[index].feat.setStyle(styleLeave);
          if (scope.res[index].featGeo != null) {
            scope.res[index].featGeo.setStyle(styleLeave);
          }
        };
        /**
         * [save le projet]
         * @param  name_project
         * @returns {undefined}
         */
        scope.save = function(name_project) {
          if (name_project.length < 3) {
            alert('le nom du projet doit contenir au moins 3 caractere ');
          } else {
            scope.current_image.name = name_project;
            //console.log(scope.current_image);
            //scope.project.push(angular.copy(scope.current_image));
            ParametersFactory.add(
              angular.copy(scope.current_image),
              'calageraster',
              scope.current_image.name
            ).then(function(res) {
              require('toastr').success($filter('translate')('common.saved'));
              scope.project.push(res.data);
            });
          }
        };
        scope.current_image = {};

        /**
         * [preview affiche l'image sur la carte (map)]
         * @param  a
         */
        scope.preview = function(a) {
          var senddata = [];
          angular.forEach(scope.res, function(c) {
            senddata.push({
              Xp: c.Xp,
              Yp: c.Yp,
              Xg: c.Xg,
              Yg: c.Yg,
              srid: 'EPSG:3857',
            });
          });
          RasterFactory.georeferenceraster(senddata, scope.staticFileName).then(
            function(data) {
              //console.log(data);
              var indx = data.data.url.lastIndexOf('\\');
              var myurl = data.data.url.substring(indx);
              scope.resetLayer();
              scope.current_image.url = data.data.url;
              scope.current_image.extent = data.data.extent;
              scope.layer_preview = new ol.layer.Image({
                source: new ol.source.ImageStatic({
                  // url: '/services/'+portalid+'/files/getfile?f=json' +'&fileName=' +  data.data.url,
                  // on recupere directement le nom de l'image géoréférencé
                  url:
                    '/services/' +
                    portalid +
                    '/files/getfile?f=json' +
                    '&fileName=' +
                    myurl,
                  /*projection: scope.projection,*/
                  imageExtent: data.data.extent,
                }),
              });
              scope.map.addLayer(scope.layer_preview);
            }
          );
        };
        /**
         * [removePreviewLayer supprimer le dernier layer de la map]
         */
        scope.removePreviewLayer = function() {
          scope.map.removeLayer(scope.layer_preview);
        };
        /**
         * [resetLayer supprime le dernier layer de la map]
         *
         */
        scope.resetLayer = function() {
          scope.map.removeLayer(scope.layer_preview);
        };

        /**
         * Fonction defini lors du changement de nom
         * @param   a
         * ]
         */
        scope.fileNameChanged = function(a) {
          //scope.reset();
          scope.staticFile = a.files[0];
          scope.staticFileName = scope.staticFile.name;
          var fd = new FormData();
          fd.append('file', scope.staticFile);
          FilesFactory.uploadprocess(fd).then(function(data) {
            scope.myImg = new Image();
            scope.myImg.onload = function() {
              //Extent en pixel de l'image en fonction de l'image charge
              scope.extent = [0, 0, scope.myImg.width, scope.myImg.height];
              scope.projection = new ol.proj.Projection({
                code: 'xkcd-image',
                units: 'pixels',
                extent: scope.extent,
              });
              // definition de la layyer
              scope.layer_pixel = new ol.layer.Image({
                source: new ol.source.ImageStatic({
                  url:
                    '/services/' +
                    portalid +
                    '/files/getfile?f=json' +
                    '&fileName=' +
                    scope.staticFileName,
                  projection: scope.projection,
                  imageExtent: scope.extent,
                }),
              });
              // defintion de la carte en pixel pour positionner les point de calage
              scope.mappx = new ol.Map({
                layers: [scope.layer_pixel],
                target: 'mappx',
                controls: ol.control.defaults({
                  attribution: false,
                }),
                view: new ol.View({
                  projection: scope.projection,
                  center: ol.extent.getCenter(scope.extent),
                  zoom: 2,
                }),
              });
              scope.imgHeight = scope.myImg.height;
              scope.imgWidth = scope.myImg.width;
              scope.mappx.addInteraction(scope.draw);
              scope.mappx.addLayer(scope.featureOverlay);
            };
            scope.myImg.src =
              '/services/' +
              portalid +
              '/files/getfile?f=json' +
              '&fileName=' +
              scope.staticFileName;
          });
        };
      },
    };
  };

  calageRaster.$inject = [
    'gcPropertiesLayers',
    'gclayers',
    'ParametersFactory',
    'FilesFactory',
    'ngDialog',
    'extendedNgDialog',
    'RasterFactory',
    '$filter',
    'gcPopup',
    'gcInteractions',
    'PortalsFactory',
  ];
  return calageRaster;
});
