'use strict';
define(function() {
  var radiuspicker = function($timeout) {
    return {
      templateUrl: 'js/XG/widgets/mapapp/style/views/radiuspicker.html',
      restrict: 'EA',
      scope: {
        degree: '=degree',
      },
      link: function(scope) {
        scope.uniqid = 'radiuspicker_' + Date.now();

        function getDegreePickerContainer() {
          return {
            el: null,
            x: null,
            y: null,
            radius: null,
            center: {
              x: null,
              y: null,
            },
          };
        }

        function getDegreePickerHandle(_) {
          return {
            el: null,
            x: null,
            y: null,
            size: 0,
            position: function(of) {
              return Math.round(
                _.container.radius *
                  Math[of === 'x' ? 'cos' : 'sin'](
                    Math.atan2(_.handle.y, _.handle.x)
                  )
              );
            },
          };
        }

        function getDegreePickerMoveFunction(_) {
          return function() {
            _.handle.el.style['-webkit-transform'] =
              'translate(' +
              _.handle.position('x') +
              'px, ' +
              _.handle.position('y') +
              'px)';
            _.handle.el.style['-moz-transform'] =
              'translate(' +
              _.handle.position('x') +
              'px, ' +
              _.handle.position('y') +
              'px)';
            _.handle.el.style['-o-transform'] =
              'translate(' +
              _.handle.position('x') +
              'px, ' +
              _.handle.position('y') +
              'px)';
            _.handle.el.style.transform =
              'translate(' +
              _.handle.position('x') +
              'px, ' +
              _.handle.position('y') +
              'px)';
          };
        }

        function getDegreePickerInitFunction(_) {
          return function() {
            _.container.el = document.querySelector(el);
            _.container.x = _.container.el.offsetLeft;
            _.container.y = _.container.el.offsetTop;
            _.container.radius = _.container.el.offsetWidth / 2;
            _.updateElementCenter();

            _.handle.el = _.container.el.children[0];
            _.handle.size = _.handle.el.offsetWidth;

            _.degree.el = _.container.el.children[1];
            _.degree.set(_.container.el.getAttribute('data-degree') || 0);

            // Bind events
            _.handle.el.addEventListener('mousedown', _.onMouseDown);
            window.addEventListener('mouseup', _.onMouseUp);
            window.addEventListener('mousemove', _.onMouseMove);
            window.addEventListener('mousedown', _.updateElementCenter);
            window.addEventListener('resize', _.updateElementCenter);
          };
        }

        // from : http://codepen.io/Idered/pen/bCJAz
        // fixed @RB for fixed/absolute containers
        var DegreePicker = function(el, opts) {
          var defaults = {
            step: 1,
            callback: function(self, degree) {
              $timeout(function() {
                scope.degree = degree;
              });
            },
          };

          opts = opts || {};

          for (var property in defaults)
            if (!opts[property]) opts[property] = defaults[property];

          var _ = {
            container: getDegreePickerContainer(),
            handle: getDegreePickerHandle(_),
            degree: {
              el: null,
              value: null,

              get: function() {
                return Math.round(this.value);
              },

              update: function() {
                this.value =
                  (Math.atan2(_.handle.y * -1, _.handle.x) * 180) / Math.PI;
                //this.value = 90-this.value;
                this.value += this.value < 0 ? 360 : 0;

                _.degree.el.value = _.degree.get();
                _.container.el.setAttribute('data-degree', _.degree.get());
              },

              set: function(value) {
                if (typeof value == 'string') value = parseInt(value, 10);
                if (!angular.isNumber(value) || isNaN(value)) return;

                _.degree.value = value;

                //value = 90- value;
                value = value > 180 ? value - 360 : value;
                value = (value * Math.PI) / 180;

                _.handle.x = Math.cos(value);
                _.handle.y = -Math.sin(value);

                _.move();
              },
            },

            isDragging: false,

            init: getDegreePickerInitFunction(_),

            /* Events
             *************************************/
            onMouseDown: function(event) {
              _.isDragging = true;
              _.updateCoords(event);
              _.degree.update();
              _.move();
            },

            onMouseUp: function() {
              opts.callback(_.container.el, _.degree.get());
              _.isDragging = false;
            },

            onMouseMove: function(event) {
              if (_.isDragging) {
                _.updateCoords(event);
                _.degree.update();
                _.move();
              }
            },

            /* Methods
             *************************************/
            updateElementCenter: function() {
              // RB : using viewportOffset instead of container.el.offset
              // if not, it wont work on fixed/absolute containers

              var viewportOffset = _.container.el.getBoundingClientRect();
              _.container.center.x = viewportOffset.left + _.container.radius;
              _.container.center.y = viewportOffset.top + _.container.radius;

              /*_.container.center.x = _.container.el.offsetLeft + _.container.radius;
                             _.container.center.y = _.container.el.offsetTop + _.container.radius;*/
            },

            updateCoords: function(e) {
              _.handle.x = e.clientX - _.container.center.x;
              _.handle.y = e.clientY - _.container.center.y;
            },

            move: getDegreePickerMoveFunction(_),
          };

          _.init();

          return {
            getValue: _.degree.get,
            setValue: _.degree.set,
          };
        };

        scope.updateDegree = function() {
          scope.picker.setValue(scope.degree);
        };

        $timeout(function() {
          scope.picker = new DegreePicker('#' + scope.uniqid);
        });
      },
    };
  };

  radiuspicker.$inject = ['$timeout'];
  return radiuspicker;
});
