/*!
 * jQuery Transit - CSS3 transitions and transformations
 * (c) 2011-2012 Rico Sta. Cruz <rico@ricostacruz.com>
 * MIT Licensed.
 *
 * http://ricostacruz.com/jquery.transit
 * http://github.com/rstacruz/jquery.transit
 */
(function($) {
    $.transit = {
        version: "0.9.9",
        propertyMap: {
            marginLeft: 'margin',
            marginRight: 'margin',
            marginBottom: 'margin',
            marginTop: 'margin',
            paddingLeft: 'padding',
            paddingRight: 'padding',
            paddingBottom: 'padding',
            paddingTop: 'padding'
        },
        enabled: true,
        useTransitionEnd: false
    };
    var u = document.createElement('div');
    var w = {};

    function getVendorPropertyName(a) {
        if (a in u.style) return a;
        var b = ['Moz', 'Webkit', 'O', 'ms'];
        var c = a.charAt(0).toUpperCase() + a.substr(1);
        if (a in u.style) {
            return a
        }
        for (var i = 0; i < b.length; ++i) {
            var d = b[i] + c;
            if (d in u.style) {
                return d
            }
        }
    }

    function checkTransform3dSupport() {
        u.style[w.transform] = '';
        u.style[w.transform] = 'rotateY(90deg)';
        return u.style[w.transform] !== ''
    }
    var z = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
    w.transition = getVendorPropertyName('transition');
    w.transitionDelay = getVendorPropertyName('transitionDelay');
    w.transform = getVendorPropertyName('transform');
    w.transformOrigin = getVendorPropertyName('transformOrigin');
    w.transform3d = checkTransform3dSupport();
    var A = {
        'transition': 'transitionEnd',
        'MozTransition': 'transitionend',
        'OTransition': 'oTransitionEnd',
        'WebkitTransition': 'webkitTransitionEnd',
        'msTransition': 'MSTransitionEnd'
    };
    var B = w.transitionEnd = A[w.transition] || null;
    for (var C in w) {
        if (w.hasOwnProperty(C) && typeof $.support[C] === 'undefined') {
            $.support[C] = w[C]
        }
    }
    u = null;
    $.cssEase = {
        '_default': 'ease',
        'in': 'ease-in',
        'out': 'ease-out',
        'in-out': 'ease-in-out',
        'snap': 'cubic-bezier(0,1,.5,1)',
        'easeOutCubic': 'cubic-bezier(.215,.61,.355,1)',
        'easeInOutCubic': 'cubic-bezier(.645,.045,.355,1)',
        'easeInCirc': 'cubic-bezier(.6,.04,.98,.335)',
        'easeOutCirc': 'cubic-bezier(.075,.82,.165,1)',
        'easeInOutCirc': 'cubic-bezier(.785,.135,.15,.86)',
        'easeInExpo': 'cubic-bezier(.95,.05,.795,.035)',
        'easeOutExpo': 'cubic-bezier(.19,1,.22,1)',
        'easeInOutExpo': 'cubic-bezier(1,0,0,1)',
        'easeInQuad': 'cubic-bezier(.55,.085,.68,.53)',
        'easeOutQuad': 'cubic-bezier(.25,.46,.45,.94)',
        'easeInOutQuad': 'cubic-bezier(.455,.03,.515,.955)',
        'easeInQuart': 'cubic-bezier(.895,.03,.685,.22)',
        'easeOutQuart': 'cubic-bezier(.165,.84,.44,1)',
        'easeInOutQuart': 'cubic-bezier(.77,0,.175,1)',
        'easeInQuint': 'cubic-bezier(.755,.05,.855,.06)',
        'easeOutQuint': 'cubic-bezier(.23,1,.32,1)',
        'easeInOutQuint': 'cubic-bezier(.86,0,.07,1)',
        'easeInSine': 'cubic-bezier(.47,0,.745,.715)',
        'easeOutSine': 'cubic-bezier(.39,.575,.565,1)',
        'easeInOutSine': 'cubic-bezier(.445,.05,.55,.95)',
        'easeInBack': 'cubic-bezier(.6,-.28,.735,.045)',
        'easeOutBack': 'cubic-bezier(.175, .885,.32,1.275)',
        'easeInOutBack': 'cubic-bezier(.68,-.55,.265,1.55)'
    };
    $.cssHooks['transit:transform'] = {
        get: function(a) {
            return $(a).data('transform') || new Transform()
        },
        set: function(a, v) {
            var b = v;
            if (!(b instanceof Transform)) {
                b = new Transform(b)
            }
            if (w.transform === 'WebkitTransform' && !z) {
                a.style[w.transform] = b.toString(true)
            } else {
                a.style[w.transform] = b.toString()
            }
            $(a).data('transform', b)
        }
    };
    $.cssHooks.transform = {
        set: $.cssHooks['transit:transform'].set
    };
    if ($.fn.jquery < "1.8") {
        $.cssHooks.transformOrigin = {
            get: function(a) {
                return a.style[w.transformOrigin]
            },
            set: function(a, b) {
                a.style[w.transformOrigin] = b
            }
        };
        $.cssHooks.transition = {
            get: function(a) {
                return a.style[w.transition]
            },
            set: function(a, b) {
                a.style[w.transition] = b
            }
        }
    }
    registerCssHook('scale');
    registerCssHook('translate');
    registerCssHook('rotate');
    registerCssHook('rotateX');
    registerCssHook('rotateY');
    registerCssHook('rotate3d');
    registerCssHook('perspective');
    registerCssHook('skewX');
    registerCssHook('skewY');
    registerCssHook('x', true);
    registerCssHook('y', true);

    function Transform(a) {
        if (typeof a === 'string') {
            this.parse(a)
        }
        return this
    }
    Transform.prototype = {
        setFromString: function(a, b) {
            var c = (typeof b === 'string') ? b.split(',') : (b.constructor === Array) ? b : [b];
            c.unshift(a);
            Transform.prototype.set.apply(this, c)
        },
        set: function(a) {
            var b = Array.prototype.slice.apply(arguments, [1]);
            if (this.setter[a]) {
                this.setter[a].apply(this, b)
            } else {
                this[a] = b.join(',')
            }
        },
        get: function(a) {
            if (this.getter[a]) {
                return this.getter[a].apply(this)
            } else {
                return this[a] || 0
            }
        },
        setter: {
            rotate: function(a) {
                this.rotate = unit(a, 'deg')
            },
            rotateX: function(a) {
                this.rotateX = unit(a, 'deg')
            },
            rotateY: function(a) {
                this.rotateY = unit(a, 'deg')
            },
            scale: function(x, y) {
                if (y === undefined) {
                    y = x
                }
                this.scale = x + "," + y
            },
            skewX: function(x) {
                this.skewX = unit(x, 'deg')
            },
            skewY: function(y) {
                this.skewY = unit(y, 'deg')
            },
            perspective: function(a) {
                this.perspective = unit(a, 'px')
            },
            x: function(x) {
                this.set('translate', x, null)
            },
            y: function(y) {
                this.set('translate', null, y)
            },
            translate: function(x, y) {
                if (this._translateX === undefined) {
                    this._translateX = 0
                }
                if (this._translateY === undefined) {
                    this._translateY = 0
                }
                if (x !== null && x !== undefined) {
                    this._translateX = unit(x, 'px')
                }
                if (y !== null && y !== undefined) {
                    this._translateY = unit(y, 'px')
                }
                this.translate = this._translateX + "," + this._translateY
            }
        },
        getter: {
            x: function() {
                return this._translateX || 0
            },
            y: function() {
                return this._translateY || 0
            },
            scale: function() {
                var s = (this.scale || "1,1").split(',');
                if (s[0]) {
                    s[0] = parseFloat(s[0])
                }
                if (s[1]) {
                    s[1] = parseFloat(s[1])
                }
                return (s[0] === s[1]) ? s[0] : s
            },
            rotate3d: function() {
                var s = (this.rotate3d || "0,0,0,0deg").split(',');
                for (var i = 0; i <= 3; ++i) {
                    if (s[i]) {
                        s[i] = parseFloat(s[i])
                    }
                }
                if (s[3]) {
                    s[3] = unit(s[3], 'deg')
                }
                return s
            }
        },
        parse: function(c) {
            var d = this;
            c.replace(/([a-zA-Z0-9]+)\((.*?)\)/g, function(x, a, b) {
                d.setFromString(a, b)
            })
        },
        toString: function(a) {
            var b = [];
            for (var i in this) {
                if (this.hasOwnProperty(i)) {
                    if ((!w.transform3d) && ((i === 'rotateX') || (i === 'rotateY') || (i === 'perspective') || (i === 'transformOrigin'))) {
                        continue
                    }
                    if (i[0] !== '_') {
                        if (a && (i === 'scale')) {
                            b.push(i + "3d(" + this[i] + ",1)")
                        } else if (a && (i === 'translate')) {
                            b.push(i + "3d(" + this[i] + ",0)")
                        } else {
                            b.push(i + "(" + this[i] + ")")
                        }
                    }
                }
            }
            return b.join(" ")
        }
    };

    function callOrQueue(a, b, c) {
        if (b === true) {
            a.queue(c)
        } else if (b) {
            a.queue(b, c)
        } else {
            c()
        }
    }

    function getProperties(b) {
        var c = [];
        $.each(b, function(a) {
            a = $.camelCase(a);
            a = $.transit.propertyMap[a] || $.cssProps[a] || a;
            a = uncamel(a);
            if ($.inArray(a, c) === -1) {
                c.push(a)
            }
        });
        return c
    }

    function getTransition(b, c, d, e) {
        var f = getProperties(b);
        if ($.cssEase[d]) {
            d = $.cssEase[d]
        }
        var g = '' + toMS(c) + ' ' + d;
        if (parseInt(e, 10) > 0) {
            g += ' ' + toMS(e)
        }
        var h = [];
        $.each(f, function(i, a) {
            h.push(a + ' ' + g)
        });
        return h.join(', ')
    }
    $.fn.transition = $.fn.transit = function(d, e, f, g) {
        var h = this;
        var j = 0;
        var k = true;
        var l = jQuery.extend(true, {}, d);
        if (typeof e === 'function') {
            g = e;
            e = undefined
        }
        if (typeof e === 'object') {
            f = e.easing;
            j = e.delay || 0;
            k = e.queue || true;
            g = e.complete;
            e = e.duration
        }
        if (typeof f === 'function') {
            g = f;
            f = undefined
        }
        if (typeof l.easing !== 'undefined') {
            f = l.easing;
            delete l.easing
        }
        if (typeof l.duration !== 'undefined') {
            e = l.duration;
            delete l.duration
        }
        if (typeof l.complete !== 'undefined') {
            g = l.complete;
            delete l.complete
        }
        if (typeof l.queue !== 'undefined') {
            k = l.queue;
            delete l.queue
        }
        if (typeof l.delay !== 'undefined') {
            j = l.delay;
            delete l.delay
        }
        if (typeof e === 'undefined') {
            e = $.fx.speeds._default
        }
        if (typeof f === 'undefined') {
            f = $.cssEase._default
        }
        e = toMS(e);
        var m = getTransition(l, e, f, j);
        var n = $.transit.enabled && w.transition;
        var i = n ? (parseInt(e, 10) + parseInt(j, 10)) : 0;
        if (i === 0) {
            var o = function(a) {
                h.css(l);
                if (g) {
                    g.apply(h)
                }
                if (a) {
                    a()
                }
            };
            callOrQueue(h, k, o);
            return h
        }
        var p = {};
        var q = function(a) {
            var b = false;
            var c = function() {
                if (b) {
                    h.unbind(B, c)
                }
                if (i > 0) {
                    h.each(function() {
                        this.style[w.transition] = (p[this] || null)
                    })
                }
                if (typeof g === 'function') {
                    g.apply(h)
                }
                if (typeof a === 'function') {
                    a()
                }
            };
            if ((i > 0) && (B) && ($.transit.useTransitionEnd)) {
                b = true;
                h.bind(B, c)
            } else {
                window.setTimeout(c, i)
            }
            h.each(function() {
                if (i > 0) {
                    this.style[w.transition] = m
                }
                $(this).css(d)
            })
        };
        var r = function(a) {
            this.offsetWidth;
            q(a)
        };
        callOrQueue(h, k, r);
        return this
    };

    function registerCssHook(c, d) {
        if (!d) {
            $.cssNumber[c] = true
        }
        $.transit.propertyMap[c] = w.transform;
        $.cssHooks[c] = {
            get: function(a) {
                var t = $(a).css('transit:transform');
                return t.get(c)
            },
            set: function(a, b) {
                var t = $(a).css('transit:transform');
                t.setFromString(c, b);
                $(a).css({
                    'transit:transform': t
                })
            }
        }
    }

    function uncamel(b) {
        return b.replace(/([A-Z])/g, function(a) {
            return '-' + a.toLowerCase()
        })
    }

    function unit(i, a) {
        if ((typeof i === "string") && (!i.match(/^[\-0-9\.]+$/))) {
            return i
        } else {
            return "" + i + a
        }
    }

    function toMS(a) {
        var i = a;
        if (typeof i === 'string' && (!i.match(/^[\-0-9\.]+/))) {
            i = $.fx.speeds[i] || $.fx.speeds._default
        }
        return unit(i, 'ms')
    }
    $.transit.getTransitionValue = getTransition
})(jQuery);
