/*
 * $.ui.transitionChainable
 *
 * version 0.1.2 (2010/07/08)
 * Copyright (c) 2010 Takeshi Takatsudo (takazudo[at]gmail.com)
 * MIT license
 *
=============================================================================
 depends on
-----------------------------------------------------------------------------
 * jQuery 1.4.2
 * jQuery UI 1.8.2
 * jQuery UI Widget 1.8.2
 *
 */
(function($){ // start $=jQuery encapsulation

(document.getElementsByTagName('html')[0].style.webkitTransition !== undefined) ? $.support.webkitTransition = true : $.support.webkitTransition = false;
(document.getElementsByTagName('html')[0].style.webkitTransform !== undefined) ? $.support.webkitTransform = true : $.support.webkitTransform = false;

	$.widget('ui.transitionChainable',{
		options: {
			property: '-webkit-transform',
			initVal: null
		},
		_translateX: null,
		_translateY: null,
		_finalVal: null,
		_reservedFn: null,
		_create: function(){
			this._disableTransition();
			this._detectCssTransitionsSupport(); //追加
			var val = this.options.initVal;
			val && this.changeVal(val);
		},
		_enableTransition: function(duration, easing){
			var val = this.options.property;
			val = duration ? val + ' ' + this._millisecondsToSeconds(duration) : val;
			val = easing ? val + ' ' + easing : val;
			this.element.css('-webkit-transition', val);
			return this;
		},
		_disableTransition: function(){
			this.element.css('-webkit-transition','none');
			return this;
		},
		// 追加
		_detectCssTransitionsSupport: function(){
			this._cssTransitionsSupported = $.support.webkitTransform;
			return this;
		},
		_millisecondsToSeconds: function(milliseconds){
			return [milliseconds/1000, 's'].join('');
		},
		_cancelAll: function(){
			this.element.clearQueue();
			var fn = this._reservedFn;
			fn && this.element.get(0).removeEventListener('webkitTransitionEnd', fn, false);
		},
		_stop_transform: function(){
			this._cancelAll();
			var val = this._getComputedTranslate3dVal()
			this._disableTransition();
			this.element.css( this.options.property, val );
			return this;
		},
		_stop_otherProps: function(){
			this._cancelAll();
			this._disableTransition();
		},
		_getComputedTransformVal: function(){
			var element = this.element.get(0); // <div class="positioner">
			var matrix = '';
			if(this._cssTransitionsSupported){
				matrix = document.defaultView.getComputedStyle(element).webkitTransform; //Fx でエラー
			} else{
				var x=0, y=0;
				x = $(this.element).css('left').replace(/px/g,'');
				y = $(this.element).css('top').replace(/px/g,'');
				matrix = 'matrix(1, 0, 0, 1, '+ x +', '+ y +')';
				//console.log(matrix);
			}
			return matrix;
		},
		_getComputedTranslate3dXY: function(){
			var matrix = this._getComputedTransformVal();
			if(matrix==='none'){
				return { x: 0, y: 0 };
			}
			matrix = matrix.replace(/ /g,''); // trim whitespaces
			var res =  matrix.match(/^matrix\([0-9\-\.]+ *, *[0-9\-\.]+ *, *[0-9\-\.]+ *, *[0-9\-\.]+ *, *([0-9\-\.]+) *, *([0-9\-\.]+)\)$/);
				/*
					matrix(1,0,0,1,191,200)
					               ^^^ ^^^
					                x   y
				*/
			return {
				x: Number(res[1]),
				y: Number(res[2])
			};
		},
		_getComputedTranslate3dVal: function(){
			var xy = this._getComputedTranslate3dXY();
			this._translateX = xy.x;
			this._translateY = xy.y;
			return [ 'translate3d(', xy.x, 'px,', xy.y, 'px,0)' ].join('');
		},
		/*
			o is like this
			{
				val: value of css property,
				easing: transition easing type,
				duration: transition duration,
				before: callback before transition,
				after: callback after transition
			}
		*/

		// アニメーションコア 関数
		animate: function(o){
			var self = this;
			var e = self.element;
			self._finalVal = o.val;
			e.queue(function(){
				self._enableTransition(o.duration, o.easing);
				var node = self.element.get(0);
				var fn = self._reservedFn = function(){
					o.after && o.after();
					self._disableTransition();
					node.removeEventListener('webkitTransitionEnd', fn, false);
					self._reservedFn = null;
					setTimeout(function(){ // need zero delay to avoid ignoring animation
						e.dequeue();
					},0);
				};
				o.before && o.before();
				node.addEventListener('webkitTransitionEnd', fn, false);
				self.changeVal(o.val);
			});
			return self;
		},
		changeVal: function(val){
			this.element.css(this.options.property, val);
			this._finalVal = val;
			return this;
		},
		finish: function(){
			this.element.clearQueue();
			this._disableTransition();
			this.changeVal(this._finalVal);
			return this;
		},
		stop: function(){
			if(this.options.property==='-webkit-transform'){
				this._stop_transform();
			}else{
				this._stop_otherProps();
			}
			return this;
		},
		getXY: function(){
			(this._translateX === null) && this._getComputedTranslate3dVal();
			return {
				x: this._translateX,
				y: this._translateY
			}
		},
		getComputedXY: function(){
			var xy = this._getComputedTranslate3dXY();
			return xy;
		}
	});
	
})(jQuery); // end $=jQuery encapsulation

