# graphics/arc.js

    'use strict';

    /**
     * @namespace Arc
     */

    var Thing = require('./thing.js');

    /* The angles are always stored in radians.
     * Based on the unit (by default, degrees), the angles might be converted
     * when calling getters or setters on the start/end angles.
     */

    /**
     * @class Arc
     * @augments Thing
     * @param {number} radius - Desired radius of the arc.
     * @param {number} startAngle - Start angle of the arc.
     * @param {number} endAngle - End angle of the arc.
     * @param {number} angleUnit - Integer representing unit.
     * Degrees ===0, Radians ===1
     */
    function Arc(radius, startAngle, endAngle, angleUnit) {
      if (typeof radius != 'number') {
        throw new TypeError('You must pass four numbers to new' +
                      'Arc(radius, startAngle, endAngle, angleUnit)');
      }
      var ArcThing = new Thing();
      ArcThing.call(this);

      this.radius = radius;
      this.angleUnit = angleUnit || Arc.DEGREES;
      this.counterclockwise = Arc.COUNTER_CLOCKWISE;
      this.type = 'Arc';

      if (this.angleUnit == Arc.DEGREES) {
        startAngle = degreesToRadians(startAngle);
        endAngle = degreesToRadians(endAngle);
      }

      this.startAngle = startAngle;
      this.endAngle = endAngle;
    }

    Arc.prototype = new Thing();
    Arc.prototype.constructor = Arc;

    // Constants for Arcs.
    Arc.COUNTER_CLOCKWISE = true;
    Arc.CLOCKWISE = false;
    Arc.DEGREES = 0;
    Arc.RADIANS = 1;

    /**
     * Draws the arc in the canvas.
     * @param {CodeHSGraphics} __graphics__ - Instance of the __graphics__ module.
     */
    Arc.prototype.draw = function(__graphics__) {
      var context = __graphics__.getContext();
      context.beginPath();
      context.arc(this.x, this.y, this.radius, prepareAngle(this.startAngle), prepareAngle(this.endAngle), this.counterclockwise);
      context.lineTo(this.x, this.y);

      if(this.hasBorder) {
        context.lineWidth = this.lineWidth;
        context.strokeStyle = this.stroke.toString();
        context.stroke();
      }

      context.fillStyle = this.color.toString();
      context.fill();
    };

    /* Sets the starting angle of the arc.
     * Note: All angles are stored in radians, so we must first convert
     * to radians (if the unit is degrees) before storing the new angle.
     * @param {number} angle - The desired start angle of the arc.
     */
    Arc.prototype.setStartAngle = function(angle) {
      if (this.angleUnit == Arc.DEGREES) {
        angle = degreesToRadians(angle);
      }
      this.startAngle = angle;
    };

    /* Sets the ending angle of the arc.
     * Note: All angles are stored in radians, so we must first convert
     * to radians (if the unit is degrees) before storing the new angle.
     * @param {number} angle - The desired end angle of the arc.
     */
    Arc.prototype.setEndAngle = function(angle) {
      if (this.angleUnit == Arc.DEGREES) {
        angle = degreesToRadians(angle);
      }
      this.endAngle = angle;
    };

    /* Gets the starting angle of the arc.
     * @returns {number} The start angle of the arc.
     */
    Arc.prototype.getStartAngle = function() {
      var angle = this.startAngle;
      if (this.angleUnit == Arc.DEGREES) {
        angle = radiansToDegrees(this.startAngle);
      }

      return Math.round(angle);
    };

    /* Gets the starting angle of the arc.
     * @returns {number} The start angle of the arc.
     */
    Arc.prototype.getEndAngle = function() {
      var angle = this.endAngle;
      if (this.angleUnit == Arc.DEGREES) {
        angle = radiansToDegrees(this.endAngle);
      }
      return Math.round(angle);
    };

    /* Gets the direction of the arc (CW or CCW).
     * @param {boolean} val - Boolean representing CW or CCW.
     * `True` sets counterclockwise to true.
     */
    Arc.prototype.setDirection = function(val) {
      this.counterclockwise = val;
    };

    /**
     * Prepares an angle to be drawn.
     * @memberof Arc
     * @param {number} angle - The angle to be prepared.
     * @returns {number} The prepared angle.
     */
    var prepareAngle = function(angle) {
      // First, convert to degrees (may lose some accuracy)
      angle = radiansToDegrees(angle);
      angle = Math.round(angle);

      // The canvas arc angles go clockwise, but we want them
      // to go counterclockwise (like the unit circle). Here,
      // we adjust the angle for that.
      angle = (360 - angle) % 360;
      angle = degreesToRadians(angle);

      return angle;
    };

    /**
     * Helper to convert degrees to radians.
     * @memberof Arc
     * @param {number} angleInDegrees - The angle represented as degrees.
     * @returns {number} The angle represented as radians.
     */
    var degreesToRadians = function(angleInDegrees) {
      return angleInDegrees / 180 * Math.PI;
    };

    /**
     * Helper to convert radians to degrees.
     * @memberof Arc
     * @param {number} angleInDegrees - The angle represented as radians.
     * @returns {number} The angle represented as degrees.
     */
    var radiansToDegrees = function(angleInRadians) {
      return angleInRadians / Math.PI * 180;
    };

    module.exports = Arc;