(function ($) {
  $.fn.graph = function (options) {
    var _id = this.attr('id');
    if (_id == null) return this;
    var _el = document.getElementById(_id);
    if (_el == null) return this;
    var _swf = options['swf'];

    //if (_swf != null && _swf != '' && $.hasFlashPlayer)
    if (!!document.createElement('canvas').getContext) {
      drawToElement(_el, options);
    }
    else {
      this.flash({
        swf: _swf,
        width: parseInt(_el.style.width),
        height: parseInt(_el.style.height),
        wmode: 'transparent',
        params: { wmode: 'transparent' },
        flashvars: options
      });
    }
    return this;
  };

  function _drawCircle(_ctx, _x, _y, _radius) {
    //ctx.arc(x, y, radius, (0/180)*Math.PI, (360/180)*Math.PI, false);
    _drawArc(_ctx, _x, _y, _radius, 0, 360);
  }

  function _drawArc(_ctx, _x, _y, _radius, _startAngle, _arc) {
    var segAngle, theta, angle, angleMid, segs, ax, ay, bx, by, cx, cy;
    _ctx.moveTo(_x, _y);
    segs = Math.ceil(Math.abs(_arc) / 45);
    segAngle = _arc / segs;
    theta = -(segAngle / 180) * Math.PI;
    angle = -(_startAngle / 180) * Math.PI;
    if (segs > 0) {
      ax = Math.cos(_startAngle / 180 * Math.PI) * _radius;
      ay = Math.sin(-_startAngle / 180 * Math.PI) * _radius;
      _ctx.lineTo(ax + _x, ay + _y);
      // Loop for drawing curve segments
      for (var i = 0; i < segs; i++) {
        angle += theta;
        angleMid = angle - (theta / 2);
        bx = Math.cos(angle) * _radius;
        by = Math.sin(angle) * _radius;
        cx = Math.cos(angleMid) * (_radius / Math.cos(theta / 2));
        cy = Math.sin(angleMid) * (_radius / Math.cos(theta / 2));
        _ctx.quadraticCurveTo(cx + _x, cy + _y, bx + _x, by + _y);
      }
    }
    _ctx.lineTo(_x, _y);
  }

  function _gradFilter(_ctx, _x, _y, _radius) {
    var gradsize = 10;
    var radgrad1 = _ctx.createRadialGradient(_x + gradsize, _y + gradsize, _radius - gradsize, _x + gradsize / 3, _y + gradsize / 3, _radius);
    radgrad1.addColorStop(0, 'rgba(128, 128, 128, 0)');
    radgrad1.addColorStop(1, 'rgba(255, 255, 255, 0.4)');
    _ctx.fillStyle = radgrad1;
    _ctx.beginPath();
    _drawCircle(_ctx, _x, _y, _radius);
    _ctx.fill();
    _ctx.closePath();
    var radgrad2 = _ctx.createRadialGradient(_x - gradsize, _y - gradsize, _radius - gradsize, _x - gradsize / 3, _y - gradsize / 3, _radius);
    radgrad2.addColorStop(0, 'rgba(128, 128, 128, 0)');
    radgrad2.addColorStop(1, 'rgba(0, 0, 0, 0.4)');
    _ctx.fillStyle = radgrad2;
    _ctx.beginPath();
    _drawCircle(_ctx, _x, _y, _radius);
    _ctx.fill();
    _ctx.closePath();
  }

  function _drawArcLine(_ctx, _x, _y, _radius, _angle) {
    _ctx.strokeStyle = "#a0a0a0";
    _ctx.lineWidth = 1;
    _ctx.beginPath();
    var xx = Math.floor(_x + (Math.cos(_angle / 180 * Math.PI) * _radius));
    var yy = Math.floor(_y + (Math.sin(_angle / 180 * Math.PI) * _radius));
    _ctx.moveTo(Math.floor(_x), Math.floor(_y) + 0.5);
    _ctx.lineTo(Math.floor(xx), Math.floor(yy) + 0.5);
    _ctx.closePath();
    _ctx.stroke();
  }

  function drawToElement(graph, options) {
    // create the canvas elements
    var size = parseInt(graph.style.width);
    var canvas = document.createElement("canvas");
    canvas.width = size;
    canvas.height = size;
    graph.appendChild(canvas);
    var ctx = canvas.getContext("2d");

    var graphType = options['graphType'];

    // Scoring
    var eagles = parseFloat(options['eagles']);
    var birdies = parseFloat(options['birdies']);
    var pars = parseFloat(options['pars']);
    var bogies = parseFloat(options['bogies']);
    var doubleBogies = parseFloat(options['doubleBogies']);

    // GIR
    var gir = parseFloat(options['gir']);

    // Recovery
    var scramble = parseFloat(options['scramble']);
    var sandSaves = parseFloat(options['sandSaves']);

    // FairwaysHit
    var fairwaysHit = parseFloat(options['fairwaysHit']);
    var missedLeft = parseFloat(options['missedLeft']);
    var missedRight = parseFloat(options['missedRight']);


    if (graphType == "Recovery") {
      // background
      ctx.fillStyle = "#652f90"; //0x652f90
      ctx.beginPath();
      _drawCircle(ctx, size / 2, size / 2, size / 2);
      ctx.fill();
      ctx.closePath();

      // draw wedge
      var scrambleWedgeArc = 360 - 360 * scramble;
      var scrambleWedgeAngle = 270 - (scrambleWedgeArc / 2);
      ctx.fillStyle = "#e0e0e0"; //0x
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, scrambleWedgeAngle, scrambleWedgeArc);
      ctx.fill();
      ctx.closePath();

      // sand saves drop shadow
      var gradsize = 10;
      var radgrad1 = ctx.createRadialGradient(size / 2, size / 2, size / 3.33 + 2, size / 2, size / 2, size / 3.33 + 15);
      radgrad1.addColorStop(0, 'rgba(0, 0, 0, 0.3)');
      radgrad1.addColorStop(1, 'rgba(0, 0, 0, 0)');
      ctx.fillStyle = radgrad1;
      ctx.beginPath();
      _drawCircle(ctx, size / 2, size / 2, size / 2 + 10);
      ctx.fill();
      ctx.closePath();

      // sand saves
      ctx.fillStyle = "#dfd93f";
      ctx.beginPath();
      _drawCircle(ctx, size / 2, size / 2, size / 3.33);
      ctx.fill();
      ctx.closePath();
      var sandSaveWedgeArc = 360 - 360 * sandSaves;
      var sandSaveWedgeAngle = 270 - (sandSaveWedgeArc / 2);
      ctx.fillStyle = "#e0e0e0"; //0x
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 3.33, sandSaveWedgeAngle, sandSaveWedgeArc);
      ctx.fill();
      ctx.closePath();
      if (sandSaves > 0.0 && sandSaves < 1.0) {
        _drawArcLine(ctx, size / 2, size / 2, size / 3.33, 0 + 90 - 90 - sandSaveWedgeAngle);
        _drawArcLine(ctx, size / 2, size / 2, size / 3.33, 0 + sandSaveWedgeAngle - 180);
      }

      // gradient
      _gradFilter(ctx, size / 2, size / 2, size / 3.31);
    }
    else if (graphType == "Scoring") {

      // double bogies draw wedge
      var doubleBogiesWedgeArc = 360 * doubleBogies;
      var doubleBogiesWedgeAngle = -90;
      ctx.fillStyle = "#252525";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, doubleBogiesWedgeAngle, doubleBogiesWedgeArc);
      ctx.fill();
      ctx.closePath();

      // bogies draw wedge
      var bogiesWedgeArc = 360 * bogies;
      var bogiesWedgeAngle = doubleBogiesWedgeAngle + doubleBogiesWedgeArc;
      ctx.fillStyle = "#3f9745";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, bogiesWedgeAngle, bogiesWedgeArc);
      ctx.fill();
      ctx.closePath();

      // par draw wedge
      var parsWedgeArc = 360 * pars;
      var parsWedgeAngle = bogiesWedgeAngle + bogiesWedgeArc;
      ctx.fillStyle = "#1474a0";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, parsWedgeAngle, parsWedgeArc);
      ctx.fill();
      ctx.closePath();

      // birdies draw wedge
      var birdiesWedgeArc = 360 * birdies;
      var birdiesWedgeAngle = parsWedgeAngle + parsWedgeArc;
      ctx.fillStyle = "#b43826";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, birdiesWedgeAngle, birdiesWedgeArc);
      ctx.fill();
      ctx.closePath();

      // eagles draw wedge
      var eaglesWedgeArc = 360 * eagles;
      var eaglesWedgeAngle = birdiesWedgeAngle + birdiesWedgeArc;
      ctx.fillStyle = "#fbaf41";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, eaglesWedgeAngle, eaglesWedgeArc);
      ctx.fill();
      ctx.closePath();
    }
    else if (graphType == "GIR") {
      // background
      ctx.fillStyle = "#3f9745";
      ctx.beginPath();
      _drawCircle(ctx, size / 2, size / 2, size / 2);
      ctx.fill();
      ctx.closePath();

      // draw wedge
      var girWedgeArc = 360 - 360 * gir;
      var girWedgeAngle = 270 - (girWedgeArc / 2);
      ctx.fillStyle = "#e0e0e0";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, girWedgeAngle, girWedgeArc);
      ctx.fill();
      ctx.closePath();

    }
    else if (graphType == "FairwaysHit") {
      // background
      ctx.fillStyle = "#c94d28";
      ctx.beginPath();
      _drawCircle(ctx, size / 2, size / 2, size / 2);
      ctx.fill();
      ctx.closePath();

    }

    if (graphType == "FairwaysHit" || graphType == "GIR") {
      ctx.strokeStyle = "rgba(0,0,0,0.12)";
      ctx.lineWidth = 13;
      ctx.beginPath();
      ctx.arc(size / 2, size / 2, 55 - 6.5, (0 / 180) * Math.PI, (360 / 180) * Math.PI, false);
      ctx.closePath();
      ctx.stroke();

      ctx.strokeStyle = "rgba(255,255,255,0.12)";
      ctx.lineWidth = 13.5;
      ctx.beginPath();
      ctx.arc(size / 2, size / 2, 41 - 6.5, (0 / 180) * Math.PI, (360 / 180) * Math.PI, false);
      ctx.closePath();
      ctx.stroke();

      ctx.strokeStyle = "rgba(0,0,0,0.12)";
      ctx.lineWidth = 13.5;
      ctx.beginPath();
      ctx.arc(size / 2, size / 2, 27 - 6.5, (0 / 180) * Math.PI, (360 / 180) * Math.PI, false);
      ctx.closePath();
      ctx.stroke();

      ctx.strokeStyle = "rgba(255,255,255,0.12)";
      ctx.lineWidth = 13.5;
      ctx.beginPath();
      ctx.arc(size / 2, size / 2, 13 - 6.5, (0 / 180) * Math.PI, (360 / 180) * Math.PI, false);
      ctx.closePath();
      ctx.stroke();

    }

    if (graphType == "FairwaysHit") {
      // draw wedge
      var wedgeArc = 360 - 360 * fairwaysHit;
      var wedgeAngle = 270 - (wedgeArc / 2);
      ctx.fillStyle = "#e0e0e0";
      ctx.beginPath();
      _drawArc(ctx, size / 2, size / 2, size / 2, wedgeAngle, wedgeArc);
      ctx.fill();
      ctx.closePath();

      if (fairwaysHit >= 0.0 && fairwaysHit < 1.0) {
        var lineRotation = (180 + wedgeArc / 2) - (360 * missedLeft);
        _drawArcLine(ctx, size / 2, size / 2, size / 2, lineRotation - 90);

        var lineRotation2 = (180 + wedgeArc / 2);
        _drawArcLine(ctx, size / 2, size / 2, size / 2, lineRotation2 - 90);

        if (missedLeft >= 0.08) {
          var arrowAngle = lineRotation - 90 + ((360 * missedLeft) / 2);
          var xx1 = Math.floor(size / 2 + (Math.cos(arrowAngle / 180 * Math.PI) * size / 3));
          var yy1 = Math.floor(size / 2 + (Math.sin(arrowAngle / 180 * Math.PI) * size / 3));
          var leftArrow = new Image();
          leftArrow.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAWCAYAAADeiIy1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArVJREFUeNqslW1IU1EYx//nztx6wxCXWkRlX4qIskBkGWbQFLFJoGGBSmD0Qpj0JYgioi8VhIVlFEHo/KRfovqgRDMtzCWGlkEobJpTSbDNl73eu3s6Z8XadPPekX947i73Off8znOec/8jlFIo6Uv3W+pz2OAeGcLcoBWSZx7JaRlILz+LnNITBCqUFC8xaGmncwMf4RkdhnfcBnHeBSrL4fz0mB3aKQfUKgrU/7KV+iZG4errgs9hRzAoAjEKdkMDfXkNjOcuk4RAPY/vUCeb3MsgVJKw3HYGWSq1sBym2iuqIVwCv8z0WuAeHYEsilDqmcCm35AsYKDjFU0ERPjE1jYzHTM/ABZmVb7FgMk6rM3aiZTsgzDU1BFVIK4P5qf0R/N9CJKIhMQQ63bsQqapCgeOlRFFEFdn41068aIJJOBHohK0WmQWV+DwpetEEcTV9byR2prqoaFywjBe3cZDRSi69YjEPAyRyj99gegLTAjIFNKi8LMjN6fRhX6lGHmJPZ/s7kBPWzNVBHGV3LhH9EdKGQwQ6b/wBmVctHwjW6vr4BNWReXCwcZ8b34IVSCu0pv1JGW/ga1UDq84+DdnPFNLdp+/CklIilmZd2YanS3PqCoQ18mGFrJ+Tw5EDmM9kyMsKL+immQdrww9XxoUjvcdUA3iqnrSSlKyDawvMgKsB9bON+GVbsotACsg5BaLw2kbRl/EWKLGvUPfWftr6nY5UVhRGXWiGo7upf5Z55LxfNbtplMou3abLOvei5VXVBLz+1iTvhle16+Y7/wc+qz8N6FWutQ0xNuThXG7+h4p2r9WF9/p/V5YLX/69N+gkB3EkYYQTH7tX5mKguLyvuienloZUNq+XCBzG/zMKbhzcHvyszPvYffupNXQZWxJ7Hir1afudzTg8yDPWBy1p78FGACh5n8rAEpGiQAAAABJRU5ErkJggg==";
          leftArrow.onload = function() {
            ctx.drawImage(leftArrow, xx1 - 13, yy1 - 11);
          };
        }

        // right arrow
        if (missedRight >= 0.08) {
          var arrowAngle = lineRotation - 90 - ((360 * missedRight) / 2);
          var xx2 = Math.floor(size / 2 + (Math.cos(arrowAngle / 180 * Math.PI) * size / 3));
          var yy2 = Math.floor(size / 2 + (Math.sin(arrowAngle / 180 * Math.PI) * size / 3));
          var rightArrow = new Image();
          rightArrow.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAWCAYAAADeiIy1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAq5JREFUeNqslV1IFFEUx/93dme/TN0VLcksE/JJWkFKjUXTinxYtB4MhbalF8HsoYcgCCQiiHroW6hACMRIsodUEFdJI1PSsIKKpMgKQ3NJTHBbZ9ed250RpnRmv1oP3Ie599z7u+fc/zlDKKWIxcY6H9LZjrsI/PwBvSUZKfYiJO3Ih2lLLnaW7iPR9pNYQX13rtKp+81I5nV/N3Mc+GQrzNm5sOTkIaWgBPaKSpIQSLKum5fp3ON7SEJI4yRAp+NZhNth3VUGU1YOCquOkP8CSdZ5qYn+9rRDFyFZhBAQvR5mBrMx6J6GM4SLB/LG002tBg5clBeRLi8Gg/B9/YS5FwPynD4WwEjLdbrwehi+yQmIgSWQWG+2IRUbnUejg8a7H9GZrlYsfv7ArhlXhiHqeWytqUdRjYtEBD29cYHO9LRDFATEa9RgRNYhNxyueiV4TVBvUyP1DvXGHYVkIfbsuXWNKDt+YlWGVaCRjlY6/czDYtemhNi0YDDDGPCrlCeykbm/SgWRTKW6idZmBEMiguzAtWOJ47HNfQonB94T/xqfAKNkVFTDee6KplZWRTTY1kL9c96V6lN58shvOIuyWre8KJXsshI1RVqhA9Xnr4UV5CrQ9yEPluUCVqct77BLgchpEkUss4KS3NNY36u71RZR9Qro5WA/nZ/8KL+BRnfB5uJy5XuU+QaYY4hRMlgkx24/iFpaCujb8BMIC/OaxWhMtcFe4lCWisoPkF+nL9Ikqw2OSmdM9auAZt+9kluHltYsm7JUcwdrXSQe2SugxakvYZ1MaelI1GR5jw7005DgD38bo2l9QNNvx1nxRcoEWR+QzzsTua0EhYRB8huZMrPh05tBBN9KZFRqJxQcb4SRCSG9oDhhkOoP+7yvhxpMFuwu3Zt4vv6xPwIMAOd6+WgJryjwAAAAAElFTkSuQmCC";
          rightArrow.onload = function() {
            ctx.drawImage(rightArrow, xx2 - 13, yy2 - 11);
          };
        }
      }
    }

    _gradFilter(ctx, size / 2, size / 2, size / 2);
  }

})(jQuery);
