/*
---

name: CSSAnimation

license: MIT-style license.

author: Ryan Florence <http://ryanflorence.com>

provides: [CSSAnimation]

...
*/

;(function(global){

var getSupportedStyle = function(element, supported){
	for (var i = supported.length - 1; i >= 0; i--){
		if (element.style[supported[i]] !== undefined){
			return supported[i];
		}
	};
};

var Transform = global.Transform = function(element, supported){
	this.element = element;
	this.style = getSupportedStyle(element, supported || [ 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
}; global.Transform.prototype = {

	translate: function(axis, value){
		return this.setter(axis, value, 'translate');
	},

	rotate: function(axis, value){
		if (typeof axis === 'number') return this.add('rotate', axis);
		return this.setter(axis, value, 'rotate');
	},
	
	skew: function(axis, value){
		return this.setter(axis, value, 'skew');
	},

	scale: function(axis, value){
		if (typeof axis === 'number') return this.add('scale', axis);
		this.setter(axis, value, 'scale');
		return this;
	},

	matrix: function(){
		var transform = this.element.style[this.style],
			match = new RegExp(this.rules.matrix.regex).test(transform),
			shared = 'matrix(' + Array.prototype.slice.call(arguments, 0).join(',') + ')';
		if (transform === 'none') transform = '';
		return match
			? this.set(transform.replace(this.rules[rule].regex, shared))
			: this.set(transform + ' ' + shared);
	},

	clear: function(){
		return this.set('');
	},

	set: function(def){
		this.element.style[this.style] = def;
		return this;
	},

	// not "public", feel free to use, but the rest of these methods
	// are not guaranteed to have backward compatibility in future releases

	setter: function(a, b, method){
		if (typeof a === 'string') return this.add(method + a.toUpperCase(), b);
		for (i in a) if (a.hasOwnProperty(i)) this[method](i, a[i])
		return this;
	},

	add: function(rule, value){
		var transform = this.element.style[this.style],
			rule = rule === 'rotateZ' ? 'rotate' : rule,
			match = new RegExp(this.rules[rule].regex).test(transform),
			unit = this.rules[rule].unit,
			shared = rule + '(' + value + unit + ')';
		if (transform === 'none') transform = '';
		return match
			? this.set(transform.replace(this.rules[rule].regex, shared))
			: this.set(transform + ' ' + shared);
	},

	remove: function(rule){
		return this.set(this.element.style[this.style].replace(this.rules[rule].regex, ''));
	},

	// this is admittadly verbose, but if an API changes,
	// this is easy to override and (sortof) future-proof the script
	// I'm still not sold it's the right way :\ ... but I'm more interested in
	// creating something useful first, then clean it up :D
	rules: {
		'rotateX':{
			regex: /rotateX\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'rotateY': {
			regex: /rotateY\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'rotateZ': {
			regex:  /rotateZ\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'rotate': {
			regex: /rotate\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'translateX': {
			regex:  /translateX\((-?[0-9]+%)\)/,
			unit: '%'
		},
		'translateY': {
			regex: /translateY\((-?[0-9]+%)\)/,
			unit: '%'
		},
		'translateZ': {
			regex: /translateZ\((-?[0-9]+px)\)/,
			unit: 'px'
		},
		'scale': {
			regex: /scale\((-?[0-9]+)\)/,
			unit: ''
		},
		'scaleX': {
			regex: /scaleX\((-?[0-9]+)\)/,
			unit: ''
		},
		'scaleY': {
			regex: /scaleY\((-?[0-9]+)\)/,
			unit: ''
		},
		'skewX': {
			regex:  /skewX\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'skewY': {
			regex:  /skewY\((-?[0-9]+deg)\)/,
			unit: 'deg'
		},
		'scale': {
			regex: /scale\((-?[0-9]+\.?[0-9]+?)\)/,
			unit: ''
		},
		'scaleX': {
			regex: /scaleX\((-?[0-9]+\.?[0-9]+?)\)/,
			unit: ''
		},
		'scaleY': {
			regex: /scaleY\((-?[0-9]+\.?[0-9]+?)\)/,
			unit: ''
		},
		'matrix': {
			regex: /matrix(.+)/,
			unit: ''
		}
	}
};

var Transition = global.Transition = function(element, supported){
	this.element = element;
	this.supported = supported || {
		prefixes:          ['WebkitTransition', 'MozTransition', 'OTransition', 'msTransition' ],
		transformPrefixes: ['-webkit-'        , '-moz-'        , '-o-'        , '-ms-']
	};
	this.style = getSupportedStyle(element, this.supported.prefixes);
	this.supported.index = this.supported.prefixes.indexOf(this.style);
}; global.Transition.prototype = {

	map: {
		'duration': 'Duration',
		'property': 'Property',
		'timing-function': 'TimingFunction'
	},

	set: function(property, value){
		if (typeof property === 'string') {
			if (value === 'transform') value = this.supported.transformPrefixes[this.supported.index] + 'transform';
			this.element.style[this.style + this.map[property]] = value;
			return this;
		}
		for (i in property) if (property.hasOwnProperty(i)) this.set(i, property[i]);
		return this;
	},

	clear: function(rule){
		if (!rule) {
			return this.set({
				duration: '',
				property: '',
				'timing-function': ''
			});
		}
		return this.set(rule, '');
	}

}

})(window); // change window to whatever global object you want to hand these constructors from

