'use strict';
define(function() {
  var gcelement = function(
    gclayers,
    $timeout,
    gcRestrictionProvider,
    gcInteractions,
    FeatureTypeFactory,
    $http,
    PortalsFactory
  ) {
    return {
      templateUrl: 'js/XG/widgets/utilities/edit/views/gceditmultiple.html',
      restrict: 'A',
      scope: {
        map: '=map',
        res: '=res',
        resselection: '=resselection',
        ftisid: '=ftisid',
        onclick: '&?onclick',
        onfinish: '&?onfinish',
        drawinteraction: '=?drawinteraction',
        isActive: '=?isactive',
        toolbarwidget: '=?toolbarwidget',
      },
      link: function(scope, element, attrs, ctrl) {
        scope.ftis = [];
        for (var i in scope.ftisid) {
          //     console.log(scope.ftisid[i]);
          scope.ftis.push(FeatureTypeFactory.getFeatureByUid(scope.ftisid[i]));
        }
        scope.isActive = false;
        scope.editpolygoninfo = { active: scope.isActive };
        scope.geom = {};
        // scope.drawinteraction = {};
        scope.feature = '';

        function sqr(a) {
          return a * a;
        }
        /**
         * [createEllipsePointCoords fonction de calcul des coordonnées d'un ellipse]
         * @param  {number} ellipseCenterX [description]
         * @param  {number} ellipseCenterY [description]
         * @param  {number} ellipseRadius  [description]
         * @param  {number} pointsToFind  [description]
         * @return {[array]}               [description]
         */
        scope.createEllipsePointCoords = function(
          ellipseCenterX,
          ellipseCenterY,
          ellipseRadius,
          pointsToFind
        ) {
          var angleToAdd = 360 / pointsToFind;
          var coords = [];
          // on choisit un deuxième rayon de l'ellipse égale à la moitié du premier
          var ellipseRadius2 = ellipseRadius / 2;
          var angle = 0;
          for (var i = 0; i < pointsToFind; i++) {
            angle = angle + angleToAdd;
            var coordX =
              ellipseCenterX +
              ellipseRadius * Math.cos((angle * Math.PI) / 180);
            var coordY =
              ellipseCenterY +
              ellipseRadius2 * Math.sin((angle * Math.PI) / 180);
            coords.push([coordX, coordY]);
          }
          return coords;
        };

        function updateEditpolygonInfo(newvalue, oldvalue, scope) {
          scope.editpolygoninfo.active = scope.isActive;
        }

        scope.$watch(scope.isActive, updateEditpolygonInfo);

        /**
         * [removefeatures description]
         * @return {No} [description]
         */
        scope.removefeatures = function() {
          gclayers
            .getDrawLayer()
            .getSource()
            .clear();
          scope.features = {};
        };

        /**
         * [add description]
         */
        scope.add = function() {
          var map = scope.map;
          map.removeInteraction(scope.drawinteraction);

          if (
            scope.isActive &&
            scope.drawinteraction &&
            scope.drawinteraction.getActive()
          ) {
            if (
              scope.drawinteraction &&
              scope.drawinteraction instanceof ol.interaction.Draw
            )
              scope.drawinteraction.setActive(false);
            map.removeInteraction(scope.drawinteraction);
            scope.removefeatures();
            scope.isActive = false;
          } else {
            scope.isActive = true;
          }

          scope.$watch('typePoly', function(newval, oldval) {
            if (newval !== oldval) {
              map.removeInteraction(scope.drawinteraction);
              scope.isActive = false;
              scope.add();
            }
          });
          //definition de la geom selon valeur selectionné
          var value1;
          var geometryFunction, maxPoints;
          if (scope.typePoly === 'Circle') {
            value1 = 'Circle';
          } else if (scope.typePoly === 'Ellipse') {
            value1 = 'LineString';
            maxPoints = 2;
            geometryFunction = function(coordinates, geometry) {
              if (!geometry) {
                geometry = new ol.geom.Polygon(null);
              }
              var centerCoord = coordinates[0];
              var refCoord = coordinates[1];
              var dX = centerCoord[0] - refCoord[0];
              var dY = centerCoord[1] - refCoord[1];
              var rayon = Math.sqrt(sqr(dX) + sqr(dY));
              var ellipseCoords = scope.createEllipsePointCoords(
                centerCoord[0],
                centerCoord[1],
                rayon,
                360
              );

              geometry.setCoordinates([ellipseCoords]);

              return geometry;
            };
          } else if (scope.typePoly === 'Square') {
            value1 = 'Circle';
            geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
          } else if (scope.typePoly === 'Box') {
            value1 = 'LineString';
            maxPoints = 2;
            geometryFunction = function(coordinates, geometry) {
              if (!geometry) {
                geometry = new ol.geom.Polygon(null);
              }
              var start = coordinates[0];
              var end = coordinates[1];
              geometry.setCoordinates([
                [start, [start[0], end[1]], end, [end[0], start[1]], start],
              ]);
              return geometry;
            };
          } else value1 = 'Polygon';
          if (scope.isActive) {
            //fin def valeur
            /* var a =  gclayers.getDrawLayer();
                        scope.drawinteraction = new ol.interaction.Draw({
                            source:gclayers.getDrawLayer().getSource(),
                            type:  'Polygon'
                        });*/
            // definition de la l'interaction draw en fonction du type et de la geometry
            scope.drawinteraction = new ol.interaction.Draw({
              source: gclayers.getDrawLayer().getSource(),
              type: value1,
              geometryFunction: geometryFunction,
              maxPoints: maxPoints,
            });
            scope.drawinteraction.set('gctype', 'kis');
            scope.drawinteraction.set('interaction', 'Draw');
            scope.drawinteraction.set('widget', 'editionoutil' + Math.random());
            scope.drawinteraction.setActive(true);
            gcInteractions.setCurrentToolBar(scope.toolbarwidget);
            map.addInteraction(scope.drawinteraction);
            //on start
            scope.drawinteraction.on('drawstart', function(evt) {
              console.log('drawstart');
              scope.test = 'drawstart';
              try {
                scope.$apply(scope);
              } catch(err) {}
            });

            // on end
            scope.drawinteraction.on('drawend', function(evt) {
              // pour le cas d'un cercle => transformer la geometry en cercle pour pouvoir l'enregistrer  en format GeoJson
              if (evt.feature.getGeometry().getType() === 'Circle') {
                var geomCircle = evt.feature.getGeometry();
                var geomPoly = ol.geom.Polygon.fromCircle(geomCircle, 360, 0);
                //geometryFunction=ol.geom.Polygon.fromCircle(evt.feature.getGeometry,32,0);
                evt.feature.setGeometry(geomPoly);
                //console.log(evt.feature.getGeometry().getCoordinates());
              }
              /// pour le cas d'une ellipse => il faut avoir le premier point et le dernier égaux
              if (scope.typePoly === 'Ellipse') {
                var coords = evt.feature.getGeometry().getCoordinates();
                if (coords[0][0] !== coords[0][359]) {
                  coords[0][359] = coords[0][0];
                  evt.feature.getGeometry().setCoordinates(coords);
                }
              }
              var format = new ol.format.GeoJSON();
              var feature = format.writeFeatureObject(evt.feature);
              if (gcRestrictionProvider.hasRestrictionEdition()) {
                gcRestrictionProvider
                  .GeometryInRestriction(
                    feature.geometry,
                    map
                      .getView()
                      .getProjection()
                      .getCode()
                  )
                  .then(
                    function(res) {
                      if (JSON.parse(res.data)) {
                        scope.drawinteraction.setActive(false);
                        map.removeInteraction(scope.drawinteraction);
                        scope.isActive = false;
                        scope.onfinish();
                        $timeout(function() {
                          scope.res = feature.geometry;
                        });
                      } else {
                        gcRestrictionProvider.showErrorMessage();
                        scope.isActive = false;
                        scope.onfinish();
                      }
                    },
                    function(res) {
                      console.error(res.data);
                    }
                  );
              } else {
                scope.drawinteraction.setActive(false);
                map.removeInteraction(scope.drawinteraction);
                scope.isActive = false;
                scope.onfinish();
                $timeout(function() {
                  scope.res = feature.geometry;
                });
              }
              //recuperation des objets en intersection si ftis definis dans cfg
              if (scope.ftis.length > 0) {
                var res1 = '';
                scope.ftis.forEach(function(fType) {
                  res1 = res1 + fType.uid + ',';
                });
                // var filter = gclayers.getSelectFilterasStringuid(map);
                var geometryExtent = evt.feature.getGeometry().getExtent();
                var leftX = geometryExtent[0];
                var bottomY = geometryExtent[1];
                var rightX = geometryExtent[2];
                var topY = geometryExtent[3];
                var catchments_url =
                  '/services/' +
                  PortalsFactory.getPortalId() +
                  '/ogc/getfeat?service=WFS&version=1.0.0&request=GetFeature&typeName=' +
                  res1 +
                  '&outputformat=json&srsName=' +
                  map
                    .getView()
                    .getProjection()
                    .getCode() +
                  '&cql_filter=INTERSECTS(geom, POLYGON((' +
                  leftX +
                  ' ' +
                  bottomY +
                  ',' +
                  rightX +
                  ' ' +
                  bottomY +
                  ',' +
                  rightX +
                  ' ' +
                  topY +
                  ',' +
                  leftX +
                  ' ' +
                  topY +
                  ',' +
                  leftX +
                  ' ' +
                  bottomY +
                  ')))';
                var promise = $http.get(catchments_url);
                promise.then(function(res1) {
                  scope.resselection = res1.data;
                });
              }
            });

            try {
              if (attrs.onclick != undefined) {
                scope.onclick();
              }
            } catch (e) {
              console.error(e);
            }
          }

          /* try{
                     scope.$apply();
                     }
                     catch(e){
                     scope.onclick();
                     }
                     scope.onclick();*/
        };
      },
    };
  };

  gcelement.$inject = [
    'gclayers',
    '$timeout',
    'gcRestrictionProvider',
    'gcInteractions',
    'FeatureTypeFactory',
    '$http',
    'PortalsFactory',
  ];
  return gcelement;
});
