(function(Konva) {
  'use strict';
  /**
   * Arc constructor
   * @constructor
   * @augments Konva.Shape
   * @param {Object} config
   * @param {Number} config.angle in degrees
   * @param {Number} config.innerRadius
   * @param {Number} config.outerRadius
   * @param {Boolean} [config.clockwise]
   * @@shapeParams
   * @@nodeParams
   * @example
   * // draw a Arc that's pointing downwards
   * var arc = new Konva.Arc({
   *   innerRadius: 40,
   *   outerRadius: 80,
   *   fill: 'red',
   *   stroke: 'black'
   *   strokeWidth: 5,
   *   angle: 60,
   *   rotationDeg: -120
   * });
   */
  Konva.Arc = function(config) {
    this.___init(config);
  };

  Konva.Arc.prototype = {
    _centroid: true,
    ___init: function(config) {
      // call super constructor
      Konva.Shape.call(this, config);
      this.className = 'Arc';
      this.sceneFunc(this._sceneFunc);
    },
    _sceneFunc: function(context) {
      var angle = Konva.getAngle(this.angle()),
        clockwise = this.clockwise();

      context.beginPath();
      context.arc(0, 0, this.getOuterRadius(), 0, angle, clockwise);
      context.arc(0, 0, this.getInnerRadius(), angle, 0, !clockwise);
      context.closePath();
      context.fillStrokeShape(this);
    },
    // implements Shape.prototype.getWidth()
    getWidth: function() {
      return this.getOuterRadius() * 2;
    },
    // implements Shape.prototype.getHeight()
    getHeight: function() {
      return this.getOuterRadius() * 2;
    },
    // implements Shape.prototype.setWidth()
    setWidth: function(width) {
      Konva.Node.prototype.setWidth.call(this, width);
      if (this.getOuterRadius() !== width / 2) {
        this.setOuterRadius(width / 2);
      }
    },
    // implements Shape.prototype.setHeight()
    setHeight: function(height) {
      Konva.Node.prototype.setHeight.call(this, height);
      if (this.getOuterRadius() !== height / 2) {
        this.setOuterRadius(height / 2);
      }
    }
  };
  Konva.Util.extend(Konva.Arc, Konva.Shape);

  // add getters setters
  Konva.Factory.addGetterSetter(
    Konva.Arc,
    'innerRadius',
    0,
    Konva.Validators.getNumberValidator()
  );

  /**
   * get/set innerRadius
   * @name innerRadius
   * @method
   * @memberof Konva.Arc.prototype
   * @param {Number} innerRadius
   * @returns {Number}
   * @example
   * // get inner radius
   * var innerRadius = arc.innerRadius();
   *
   * // set inner radius
   * arc.innerRadius(20);
   */

  Konva.Factory.addGetterSetter(
    Konva.Arc,
    'outerRadius',
    0,
    Konva.Validators.getNumberValidator()
  );

  /**
   * get/set outerRadius
   * @name outerRadius
   * @method
   * @memberof Konva.Arc.prototype
   * @param {Number} outerRadius
   * @returns {Number}
   * @example
   * // get outer radius
   * var outerRadius = arc.outerRadius();
   *
   * // set outer radius
   * arc.outerRadius(20);
   */

  Konva.Factory.addGetterSetter(
    Konva.Arc,
    'angle',
    0,
    Konva.Validators.getNumberValidator()
  );

  /**
   * get/set angle in degrees
   * @name angle
   * @method
   * @memberof Konva.Arc.prototype
   * @param {Number} angle
   * @returns {Number}
   * @example
   * // get angle
   * var angle = arc.angle();
   *
   * // set angle
   * arc.angle(20);
   */

  Konva.Factory.addGetterSetter(Konva.Arc, 'clockwise', false);

  /**
   * get/set clockwise flag
   * @name clockwise
   * @method
   * @memberof Konva.Arc.prototype
   * @param {Boolean} clockwise
   * @returns {Boolean}
   * @example
   * // get clockwise flag
   * var clockwise = arc.clockwise();
   *
   * // draw arc counter-clockwise
   * arc.clockwise(false);
   *
   * // draw arc clockwise
   * arc.clockwise(true);
   */

  Konva.Collection.mapMethods(Konva.Arc);
})(Konva);
