1var override = require('../utils/override');
2
3var INTEGER_PATTERN = /^\d+$/;
4
5var ALL_UNITS = ['*', 'all'];
6var DEFAULT_PRECISION = 'off'; // all precision changes are disabled
7var DIRECTIVES_SEPARATOR = ','; // e.g. *=5,px=3
8var DIRECTIVE_VALUE_SEPARATOR = '='; // e.g. *=5
9
10function roundingPrecisionFrom(source) {
11  return override(defaults(DEFAULT_PRECISION), buildPrecisionFrom(source));
12}
13
14function defaults(value) {
15  return {
16    'ch': value,
17    'cm': value,
18    'em': value,
19    'ex': value,
20    'in': value,
21    'mm': value,
22    'pc': value,
23    'pt': value,
24    'px': value,
25    'q': value,
26    'rem': value,
27    'vh': value,
28    'vmax': value,
29    'vmin': value,
30    'vw': value,
31    '%': value
32  };
33}
34
35function buildPrecisionFrom(source) {
36  if (source === null || source === undefined) {
37    return {};
38  }
39
40  if (typeof source == 'boolean') {
41    return {};
42  }
43
44  if (typeof source == 'number' && source == -1) {
45    return defaults(DEFAULT_PRECISION);
46  }
47
48  if (typeof source == 'number') {
49    return defaults(source);
50  }
51
52  if (typeof source == 'string' && INTEGER_PATTERN.test(source)) {
53    return defaults(parseInt(source));
54  }
55
56  if (typeof source == 'string' && source == DEFAULT_PRECISION) {
57    return defaults(DEFAULT_PRECISION);
58  }
59
60  if (typeof source == 'object') {
61    return source;
62  }
63
64  return source
65    .split(DIRECTIVES_SEPARATOR)
66    .reduce(function (accumulator, directive) {
67      var directiveParts = directive.split(DIRECTIVE_VALUE_SEPARATOR);
68      var name = directiveParts[0];
69      var value = parseInt(directiveParts[1]);
70
71      if (isNaN(value) || value == -1) {
72        value = DEFAULT_PRECISION;
73      }
74
75      if (ALL_UNITS.indexOf(name) > -1) {
76        accumulator = override(accumulator, defaults(value));
77      } else {
78        accumulator[name] = value;
79      }
80
81      return accumulator;
82    }, {});
83}
84
85module.exports = {
86  DEFAULT: DEFAULT_PRECISION,
87  roundingPrecisionFrom: roundingPrecisionFrom
88};
89