define([
	'lodash/lodash',
	'angular/angular',
], function(
	_,
	ang
	) {
		angular.module('utility.filters', [])
			.filter('siPrefix', ['$filter', function($filter) {
				return function(value, suffix, precision, init) {
					if(_.isUndefined(precision)) {
						precision = 2;
					}

					if(_.isUndefined(value) | _.isNaN(value)) {
						return '';
					} else {
						if(_.isUndefined(init)) {
							var count = 0;
						} else {
							var count = init;
						}

						var prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z'];

						while(value > 1E3) {
							value /= 1E3
							count++;
						}

						return $filter('number')(value, precision) + ' ' + prefixes[count] + suffix;
					}
				}
			}])

			.filter('toMs', [function() {
				return function(date) {
					var obj = new Date(date);

					return obj.getTime();
				}
			}])

			.filter('toInt', [function() {
				return function(data, base) {
					if(_.isUndefined(base)) {
						base = 10
					}

					return parseInt(data, base);
				}
			}])


			.filter('difference', ['$filter', function($filter) {
				return function(from, to, granularity, precision) {
					var modifier;
					var fromMs = from;
					var toMs = to;

					switch (granularity) {
						case 'days':
						case 'day':
							modifier = 1000 * 60 * 60 * 24;
							break;
						case 'hours':
						case 'hour':
							modifier = 1000 * 60 * 60;
							break
						case 'minutes':
						case 'minute':
							modifier = 1000 * 60;
							break
						case 'seconds':
						case 'second':
							modifier = 1000;
							break
					}

					if(_.isDate(from)) {
						fromMs = from.getTime();
					}

					if(_.isDate(to)) {
						toMs = to.getTime();
					}

					var result = (toMs - fromMs) / modifier;
					return $filter('number')(result, precision) + ' ' + $filter('pluralize')(granularity, result, precision);
				}
			}])

			.filter('pluralize', ['$filter', function($filter) {
				return function(root, count, precision) {
					if(parseInt($filter('number')(count, precision), 10) !== 1) {
						return root + 's';
					} else {
						return root;
					}
				}
			}])

			.filter('percent', ['$filter', function($filter) {
				return function(ratio, precision) {
					if(_.isUndefined(precision)) {
						precision = 2;
					}

					if(_.isUndefined(ratio) | _.isNaN(ratio)) {
						return '';
					} else {
						return $filter('number')(ratio * 100, precision) + '%';
					}
				}
			}])

			.filter('relativePercent', ['$filter', function($filter) {
				return function(ratio, precision) {
					return ([
						ratio > 0 ? '+' : '-',
						$filter('percent')(ratio, precision)
					]).join('')
				}
			}]);
})
