
angular.module('KPIAppFilters',[])
.filter('toNumber', function() {
  return function(n) {
    return new Number(n);
  };
})
.filter('percentage', function() {
  return function(n,d) {
    if(n === null) {
      return "";
    }
    n = new Number(n) * 100;
    if(d){
      var p = Math.pow(10, d);
      n = Math.round(n * p) / p;
    }
    if(isNaN(n)) {
      return "";
    }
    return n+"%";
  };
})
.filter('roundCompareIcon', function () {
   return function(input, round, trueValue, falseValue) {
     input = round2(input,round);
     if(input > 0) return trueValue;
     else if(input < 0) return falseValue;
     else return "";
   };
})
.filter('interpolateFilter', function($interpolate ) {
  return function(item,name){
     var result = $interpolate('{{value | ' + arguments[1] + '}}');
     return result({value:arguments[0]});
  };
})
.directive("dpercent", function($filter){
  var p = function(viewValue){
    return parseFloat(viewValue)/100;
  };

  var f = function(modelValue){
    return parseFloat((parseFloat(modelValue)*100).toFixed(1));
  };
  
  return {
    require: 'ngModel',
    link: function(scope, ele, attr, ctrl){
      ctrl.$parsers.unshift(p);
      ctrl.$formatters.unshift(f);
    }
  };
})
.directive("dnumber", function($filter){
  var p = function(viewValue){
    return parseFloat(viewValue);
  };

  var f = function(modelValue){
    return parseFloat(modelValue);
  };
  
  return {
    require: 'ngModel',
    link: function(scope, ele, attr, ctrl){
      ctrl.$parsers.unshift(p);
      ctrl.$formatters.unshift(f);
    }
  };
})
.directive("dnumber2", function($filter){
  var p = function(viewValue){
    return parseFloat(viewValue);
  };

  var f = function(modelValue){
    return round2(parseFloat(modelValue));
  };
  
  return {
    require: 'ngModel',
    link: function(scope, ele, attr, ctrl){
      ctrl.$parsers.unshift(p);
      ctrl.$formatters.unshift(f);
    }
  };
})
.directive('convertToNumber', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(val) {
        return parseInt(val, 10);
      });
      ngModel.$formatters.push(function(val) {
        return '' + val;
      });
    }
  };
})
;



function AngularScopeCompile(root)
{
  var injector = angular.element($('[ng-app]')[0]).injector();
  var $compile = injector.get('$compile');
  var $scope = angular.element(root).scope();
  var result = $compile(root)($scope);
  $scope.$digest();
  return result;
}

function AngularCompile(root)
{
  var injector = angular.element($('[ng-app]')[0]).injector();
  var $compile = injector.get('$compile');
  var $rootScope = injector.get('$rootScope');
  var result = $compile(root)($rootScope);
  $rootScope.$digest();
  return result;
}



// Closure
(function() {
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */
  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

function round2(n,d) {
  n = new Number(n);
  if(typeof d !== 'number'){
    d = 2;
  }
  var p = Math.pow(10, d);
  n = Math.round(n * p) / p;
  return n;
};















/*
 .directive('xlPercentage', function($filter) {
    // A directive for both formatting and properly validating a percentage value. 
    // Assumes that our internal model is expressed as floats -1 to +1: .099 is 9.9%
    // Formats display into percents 1-100, and parses user inputs down to the model. 
    // Parses user input as floats between 0 and 100 into floats less than 1. 
    // Validates user input to be within the range -100 to +100. 
    // Sets Angular $valid property accordingly on the ngModelController.
    // If a `pct-max` or `pct-min` attribute is specified on the <input>, will use those bounds instead.
    // If a `pct-decimals` attr present, will truncate inputs accordingly. 

    function outputFormatter(modelValue, decimals) {
      var length = decimals || 2;
      if (modelValue != null) {
        return $filter('number')(parseFloat(modelValue) * 100, length);
      } else {
        return undefined;
      }
    };

    function inputParser(viewValue, decimals) {
      var length = decimals || 4;
      if (viewValue != null) {
        return $filter('number')(parseFloat(viewValue) / 100, length);
      } else {
        return undefined;
      }

    }

    function isWithinBounds(value, upper, lower) {
      if (value >= lower && value <= upper) {
        return true;
      } else {
        return false;
      }
    }

    return {
      restrict: 'A',
      require: 'ngModel',
      link: function postLink(scope, element, attrs, ctrl) {
        ctrl.$parsers.unshift(function(viewValue) {
          // confirm the input from the view contains numbers, before parsing
          var numericStatus = viewValue.match(/(\d+)/),
            min = parseFloat(attrs.pctMin) || -100,
            max = parseFloat(attrs.pctMax) || 100,
            decimals = parseFloat(attrs.pctDecimals) || 4,
            bounded = isWithinBounds(viewValue, max, min);
          if (numericStatus !== null && bounded) {
            ctrl.$setValidity('percentage', true);
            // round to max four digits after decimal
            return inputParser(viewValue, decimals);
          } else {
            ctrl.$setValidity('percentage', false);
            return undefined;
          }
        });

        ctrl.$formatters.unshift(outputFormatter);
        // we have to watch for changes, and run the formatter again afterwards
        element.on('change', function(e) {
          var element = e.target;
          element.value = outputFormatter(ctrl.$modelValue, 2);
        });
      }
    };
  })
 * */