text: "use strict";
  
  (function ($) {
  
      $.fn.circliful = function (options, callback) {
  
          var settings = $.extend({
              // These are the defaults.
              startdegree: 0,
              fgcolor: "#556b2f",
              bgcolor: "#eee",
              fill: false,
              width: 15,
              dimension: 200,
              fontsize: 15,
              percent: 50,
              animationstep: 1.0,
              iconsize: '20px',
              iconcolor: '#999',
              border: 'default',
              complete: null,
              bordersize: 10,
              delay: 0
          }, options);
  
          return this.each(function () {
  
              var customSettings = ["fgcolor", "bgcolor", "fill", "width", "dimension", "fontsize", "animationstep", "endPercent", "icon", "iconcolor", "iconsize", "border", "startdegree", "bordersize", "delay"];
  
              var customSettingsObj = {};
              var icon = '';
              var percent;
              var obj = $(this);
              var fill = false;
              var text, info;
  
              obj.addClass('circliful');
  
              checkDataAttributes(obj);
  
              var endPercent = customSettingsObj.endPercent || 0.0;
  
              if (obj.data('text') != undefined) {
                  text = obj.data('text');
  
                  if (obj.data('icon') != undefined) {
                      icon = $('<i></i>')
                          .addClass('fa ' + $(this).data('icon'))
                          .css({
                              'color': customSettingsObj.iconcolor,
                              'font-size': customSettingsObj.iconsize
                          });
                  }
  
                  if (obj.data('type') != undefined) {
                      type = $(this).data('type');
  
                      if (type == 'half') {
                          addCircleText(obj, 'circle-text-half', (customSettingsObj.dimension / 1.45));
                      } else {
                          addCircleText(obj, 'circle-text', customSettingsObj.dimension);
                      }
                  } else {
                      addCircleText(obj, 'circle-text', customSettingsObj.dimension);
                  }
              }
  
              if ($(this).data("total") != undefined && $(this).data("part") != undefined) {
                  var total = $(this).data("total") / 100;
  
                  percent = (($(this).data("part") / total) / 100).toFixed(3);
                  endPercent = ($(this).data("part") / total).toFixed(3);
              } else {
                  if ($(this).data("percent") != undefined) {
                      percent = $(this).data("percent") / 100;
                      endPercent = $(this).data("percent");
                  } else {
                      percent = settings.percent / 100;
                  }
              }
  
              if ($(this).data('info') != undefined) {
                  info = $(this).data('info');
  
                  if ($(this).data('type') != undefined) {
                      type = $(this).data('type');
  
                      if (type == 'half') {
                          addInfoText(obj, 0.9);
                      } else {
                          addInfoText(obj, 1.25);
                      }
                  } else {
                      addInfoText(obj, 1.25);
                  }
              }
  
              $(this).width(customSettingsObj.dimension + 'px');
  
              var size = customSettingsObj.dimension,
                  canvas = $('<canvas></canvas>').attr({
                      width: size,
                      height: size
                  }).appendTo($(this)).get(0);
  
              var context = canvas.getContext('2d');
  
              var dpr = window.devicePixelRatio;
              if ( dpr ) {
                  var $canvas = $(canvas);
                  $canvas.css('width', size);
                  $canvas.css('height', size);
                  $canvas.attr('width', size * dpr);
                  $canvas.attr('height', size * dpr);
  
                  context.scale(dpr, dpr);
              }
  
              var container = $(canvas).parent();
              var x = size / 2;
              var y = size / 2;
              var degrees = customSettingsObj.percent * 360.0;
              var radians = degrees * (Math.PI / 180);
              var radius = size / 2.5;
              var startAngle = 2.3 * Math.PI;
              var endAngle = 0;
              var counterClockwise = false;
              var curPerc = customSettingsObj.animationstep === 0.0 ? endPercent : 0.0;
              var curStep = Math.max(customSettingsObj.animationstep, 0.0);
              var circ = Math.PI * 2;
              var quart = Math.PI / 2;
              var type = '';
              var fireCallback = true;
              var additionalAngelPI = (customSettingsObj.startdegree / 180) * Math.PI;
              var animationDelay = customSettingsObj.delay;
  
              if ($(this).data('type') != undefined) {
                  type = $(this).data('type');
  
                  if (type == 'half') {
                      startAngle = 2.0 * Math.PI;
                      endAngle = 3.13;
                      circ = Math.PI;
                      quart = Math.PI / 0.996;
                  }
              }
  
              if ($(this).data('type') != undefined) {
                  type = $(this).data('type');
  
                  if (type == 'angle') {
                      startAngle = 2.25 * Math.PI;
                      endAngle = 2.4;
                      circ = 1.53 + Math.PI;
                      quart = 0.73 + Math.PI / 0.996;
                  }
              }
  
              /**
               * adds text to circle
               *
               * @param obj
               * @param cssClass
               * @param lineHeight
               */
              function addCircleText(obj, cssClass, lineHeight) {
                  $("<span></span>")
                      .appendTo(obj)
                      .addClass(cssClass)
                      .html(text)
                      .prepend(icon)
                      .css({
                          'line-height': lineHeight + 'px',
                          'font-size': customSettingsObj.fontsize + 'px'
                      });
              }
  
              /**
               * adds info text to circle
               *
               * @param obj
               * @param factor
               */
              function addInfoText(obj, factor) {
                  $('<span></span>')
                      .appendTo(obj)
                      .addClass('circle-info-half')
                      .css(
                      'line-height', (customSettingsObj.dimension * factor) + 'px'
                  )
                      .text(info);
              }
  
              /**
               * checks which data attributes are defined
               * @param obj
               */
              function checkDataAttributes(obj) {
                  $.each(customSettings, function (index, attribute) {
                      if (obj.data(attribute) != undefined) {
                          customSettingsObj[attribute] = obj.data(attribute);
                      } else {
                          customSettingsObj[attribute] = $(settings).attr(attribute);
                      }
  
                      if (attribute == 'fill' && obj.data('fill') != undefined) {
                          fill = true;
                      }
                  });
              }
  
              /**
               * draw background circle
               */
              function bgrCircle () {
                  context.clearRect(0, 0, canvas.width, canvas.height);
  
                  context.beginPath();
                  context.arc(x, y, radius, endAngle, startAngle, false);
  
                  context.lineWidth = customSettingsObj.bordersize + 1;
  
                  context.strokeStyle = customSettingsObj.bgcolor;
                  context.stroke();
  
                  if (customSettingsObj.fill) {
                      context.fillStyle = customSettingsObj.fill;
                      context.fill();
                  }
  
              }
  
              /**
               * animate foreground circle
               * @param current
               */
              function animate(current) {
  
                  bgrCircle ();
                  context.beginPath();
                  context.arc(x, y, radius, -(quart) + additionalAngelPI, ((circ) * current) - quart + additionalAngelPI, false);
  
                  if (customSettingsObj.border == 'outline') {
                      context.lineWidth = customSettingsObj.width + customSettingsObj.bordersize;
                  } else if (customSettingsObj.border == 'inline') {
                      context.lineWidth = customSettingsObj.width - customSettingsObj.bordersize;
                  }
  
                  context.strokeStyle = customSettingsObj.fgcolor;
                  context.stroke();
  
                  if (curPerc < endPercent) {
                      curPerc += curStep;
                      requestAnimationFrame(function () {
                          animate(Math.min(curPerc, endPercent) / 100);
                      }, obj);
                  }
  
                  if (curPerc == endPercent && fireCallback && typeof(options) != "undefined") {
                      if ($.isFunction(options.complete)) {
                          options.complete();
  
                          fireCallback = false;
                      }
                  }
              }
  
              setTimeout(function () {
                  animate(curPerc / 100);
              }, animationDelay);
          });
      };
  }(jQuery));