1var understandable = require('./properties/understandable');
2
3function animationIterationCount(validator, value1, value2) {
4  if (!understandable(validator, value1, value2, 0, true) && !(validator.isAnimationIterationCountKeyword(value2) || validator.isPositiveNumber(value2))) {
5    return false;
6  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
7    return true;
8  }
9
10  return validator.isAnimationIterationCountKeyword(value2) || validator.isPositiveNumber(value2);
11}
12
13function animationName(validator, value1, value2) {
14  if (!understandable(validator, value1, value2, 0, true) && !(validator.isAnimationNameKeyword(value2) || validator.isIdentifier(value2))) {
15    return false;
16  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
17    return true;
18  }
19
20  return validator.isAnimationNameKeyword(value2) || validator.isIdentifier(value2);
21}
22
23function areSameFunction(validator, value1, value2) {
24  if (!validator.isFunction(value1) || !validator.isFunction(value2)) {
25    return false;
26  }
27
28  var function1Name = value1.substring(0, value1.indexOf('('));
29  var function2Name = value2.substring(0, value2.indexOf('('));
30
31  return function1Name === function2Name;
32}
33
34function backgroundPosition(validator, value1, value2) {
35  if (!understandable(validator, value1, value2, 0, true) && !(validator.isBackgroundPositionKeyword(value2) || validator.isGlobal(value2))) {
36    return false;
37  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
38    return true;
39  } else if (validator.isBackgroundPositionKeyword(value2) || validator.isGlobal(value2)) {
40    return true;
41  }
42
43  return unit(validator, value1, value2);
44}
45
46function backgroundSize(validator, value1, value2) {
47  if (!understandable(validator, value1, value2, 0, true) && !(validator.isBackgroundSizeKeyword(value2) || validator.isGlobal(value2))) {
48    return false;
49  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
50    return true;
51  } else if (validator.isBackgroundSizeKeyword(value2) || validator.isGlobal(value2)) {
52    return true;
53  }
54
55  return unit(validator, value1, value2);
56}
57
58function color(validator, value1, value2) {
59  if (!understandable(validator, value1, value2, 0, true) && !validator.isColor(value2)) {
60    return false;
61  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
62    return true;
63  } else if (!validator.colorOpacity && (validator.isRgbColor(value1) || validator.isHslColor(value1))) {
64    return false;
65  } else if (!validator.colorOpacity && (validator.isRgbColor(value2) || validator.isHslColor(value2))) {
66    return false;
67  } else if (validator.isColor(value1) && validator.isColor(value2)) {
68    return true;
69  }
70
71  return sameFunctionOrValue(validator, value1, value2);
72}
73
74function components(overrideCheckers) {
75  return function (validator, value1, value2, position) {
76    return overrideCheckers[position](validator, value1, value2);
77  };
78}
79
80function fontFamily(validator, value1, value2) {
81  return understandable(validator, value1, value2, 0, true);
82}
83
84function image(validator, value1, value2) {
85  if (!understandable(validator, value1, value2, 0, true) && !validator.isImage(value2)) {
86    return false;
87  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
88    return true;
89  } else if (validator.isImage(value2)) {
90    return true;
91  } else if (validator.isImage(value1)) {
92    return false;
93  }
94
95  return sameFunctionOrValue(validator, value1, value2);
96}
97
98function keyword(propertyName) {
99  return function(validator, value1, value2) {
100    if (!understandable(validator, value1, value2, 0, true) && !validator.isKeyword(propertyName)(value2)) {
101      return false;
102    } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
103      return true;
104    }
105
106    return validator.isKeyword(propertyName)(value2);
107  };
108}
109
110function keywordWithGlobal(propertyName) {
111  return function(validator, value1, value2) {
112    if (!understandable(validator, value1, value2, 0, true) && !(validator.isKeyword(propertyName)(value2) || validator.isGlobal(value2))) {
113      return false;
114    } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
115      return true;
116    }
117
118    return validator.isKeyword(propertyName)(value2) || validator.isGlobal(value2);
119  };
120}
121
122function propertyName(validator, value1, value2) {
123  if (!understandable(validator, value1, value2, 0, true) && !validator.isIdentifier(value2)) {
124    return false;
125  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
126    return true;
127  }
128
129  return validator.isIdentifier(value2);
130}
131
132function sameFunctionOrValue(validator, value1, value2) {
133  return areSameFunction(validator, value1, value2) ?
134    true :
135    value1 === value2;
136}
137
138function textShadow(validator, value1, value2) {
139  if (!understandable(validator, value1, value2, 0, true) && !(validator.isUnit(value2) || validator.isColor(value2) || validator.isGlobal(value2))) {
140    return false;
141  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
142    return true;
143  }
144
145  return validator.isUnit(value2) || validator.isColor(value2) || validator.isGlobal(value2);
146}
147
148function time(validator, value1, value2) {
149  if (!understandable(validator, value1, value2, 0, true) && !validator.isTime(value2)) {
150    return false;
151  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
152    return true;
153  } else if (validator.isTime(value1) && !validator.isTime(value2)) {
154    return false;
155  } else if (validator.isTime(value2)) {
156    return true;
157  } else if (validator.isTime(value1)) {
158    return false;
159  } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(value2)) {
160    return true;
161  }
162
163  return sameFunctionOrValue(validator, value1, value2);
164}
165
166function timingFunction(validator, value1, value2) {
167  if (!understandable(validator, value1, value2, 0, true) && !(validator.isTimingFunction(value2) || validator.isGlobal(value2))) {
168    return false;
169  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
170    return true;
171  }
172
173  return validator.isTimingFunction(value2) || validator.isGlobal(value2);
174}
175
176function unit(validator, value1, value2) {
177  if (!understandable(validator, value1, value2, 0, true) && !validator.isUnit(value2)) {
178    return false;
179  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
180    return true;
181  } else if (validator.isUnit(value1) && !validator.isUnit(value2)) {
182    return false;
183  } else if (validator.isUnit(value2)) {
184    return true;
185  } else if (validator.isUnit(value1)) {
186    return false;
187  } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(value2)) {
188    return true;
189  }
190
191  return sameFunctionOrValue(validator, value1, value2);
192}
193
194function unitOrKeywordWithGlobal(propertyName) {
195  var byKeyword = keywordWithGlobal(propertyName);
196
197  return function(validator, value1, value2) {
198    return unit(validator, value1, value2) || byKeyword(validator, value1, value2);
199  };
200}
201
202function unitOrNumber(validator, value1, value2) {
203  if (!understandable(validator, value1, value2, 0, true) && !(validator.isUnit(value2) || validator.isNumber(value2))) {
204    return false;
205  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
206    return true;
207  } else if ((validator.isUnit(value1) || validator.isNumber(value1)) && !(validator.isUnit(value2) || validator.isNumber(value2))) {
208    return false;
209  } else if (validator.isUnit(value2) || validator.isNumber(value2)) {
210    return true;
211  } else if (validator.isUnit(value1) || validator.isNumber(value1)) {
212    return false;
213  } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(value2)) {
214    return true;
215  }
216
217  return sameFunctionOrValue(validator, value1, value2);
218}
219
220function zIndex(validator, value1, value2) {
221  if (!understandable(validator, value1, value2, 0, true) && !validator.isZIndex(value2)) {
222    return false;
223  } else if (validator.isVariable(value1) && validator.isVariable(value2)) {
224    return true;
225  }
226
227  return validator.isZIndex(value2);
228}
229
230module.exports = {
231  generic: {
232    color: color,
233    components: components,
234    image: image,
235    propertyName: propertyName,
236    time: time,
237    timingFunction: timingFunction,
238    unit: unit,
239    unitOrNumber: unitOrNumber
240  },
241  property: {
242    animationDirection: keywordWithGlobal('animation-direction'),
243    animationFillMode: keyword('animation-fill-mode'),
244    animationIterationCount: animationIterationCount,
245    animationName: animationName,
246    animationPlayState: keywordWithGlobal('animation-play-state'),
247    backgroundAttachment: keyword('background-attachment'),
248    backgroundClip: keywordWithGlobal('background-clip'),
249    backgroundOrigin: keyword('background-origin'),
250    backgroundPosition: backgroundPosition,
251    backgroundRepeat: keyword('background-repeat'),
252    backgroundSize: backgroundSize,
253    bottom: unitOrKeywordWithGlobal('bottom'),
254    borderCollapse: keyword('border-collapse'),
255    borderStyle: keywordWithGlobal('*-style'),
256    clear: keywordWithGlobal('clear'),
257    cursor: keywordWithGlobal('cursor'),
258    display: keywordWithGlobal('display'),
259    float: keywordWithGlobal('float'),
260    left: unitOrKeywordWithGlobal('left'),
261    fontFamily: fontFamily,
262    fontStretch: keywordWithGlobal('font-stretch'),
263    fontStyle: keywordWithGlobal('font-style'),
264    fontVariant: keywordWithGlobal('font-variant'),
265    fontWeight: keywordWithGlobal('font-weight'),
266    listStyleType: keywordWithGlobal('list-style-type'),
267    listStylePosition: keywordWithGlobal('list-style-position'),
268    outlineStyle: keywordWithGlobal('*-style'),
269    overflow: keywordWithGlobal('overflow'),
270    position: keywordWithGlobal('position'),
271    right: unitOrKeywordWithGlobal('right'),
272    textAlign: keywordWithGlobal('text-align'),
273    textDecoration: keywordWithGlobal('text-decoration'),
274    textOverflow: keywordWithGlobal('text-overflow'),
275    textShadow: textShadow,
276    top: unitOrKeywordWithGlobal('top'),
277    transform: sameFunctionOrValue,
278    verticalAlign: unitOrKeywordWithGlobal('vertical-align'),
279    visibility: keywordWithGlobal('visibility'),
280    whiteSpace: keywordWithGlobal('white-space'),
281    zIndex: zIndex
282  }
283};
284