/**
 * jQuery.flickSimple v1.1
 *
 * Copyright (c) 2011 Makog. http://d.hatena.ne.jp/makog/
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
(function($){

	$.flickSimple = function( obj, param ) {
		this.setup( $(obj), param );
	};
	
	$.extend( $.flickSimple.prototype, {
		elm: null,
		target: null,
		snap: 'element',
		ratio: 5,
		duration: 600,
		lock: false,
		onChange: null,
		onResize: null,
		onAnimationEnd: null,
		onClick: null,
	
		elmWidth: 0,
		page: 1,
		pageWidth: 0,
		pageLength: 0,
		android: false,
		webkit: true,
		touchable: true,
		anc: null,
		
		startX: null,
		preX: 0,
		currentX: 0,
		flickX: 0,
		nextX: 0,
		// debug: null,

		setup: function( obj, param ) {
			var o = this;
		//	o.debug = $('#debug');
			o.elm = obj;
			o.elm.css( { overflow: 'hidden' } );
			o.target = param.target || o.elm.find('ul');
			
			o.android = param.android === void 0
				? navigator.userAgent.indexOf('Android') != -1
				: param.android;
			o.webkit = typeof( WebKitTransitionEvent ) !== "undefined";
			o.touchable = typeof( ontouchstart ) !== "undefined";

			if ( param.snap  !== void 0 )    o.snap = param.snap;
			if ( param.ratio !== void 0 )    o.ratio = param.ratio;
			if ( param.duration !== void 0 ) o.duration = param.duration;
			if ( param.lock !== void 0 )     o.lock = param.lock;

			o.onChange       = param.onChange;
			o.onResize       = param.onResize;
			o.onAnimationEnd = param.onAnimationEnd;
			o.onClick        = param.onClick;

			o.init();

			if ( o.android || ! o.webkit ) {
				o.target.css({ position:'relative' });
			} else {
				o.target.css({
					position:'relative',
					webkitTransition:'none',
					webkitTransform:'translate3d(0,0,0)'
				});
			}

			if ( typeof window.onorientationchange !== 'undefined' ) {
				$(window).bind( 'orientationchange', function(){ o.updateSize(); } );
			} else {
				$(window).bind( 'resize', function(){ o.updateSize(); } );
			}
			o.updateSize();
			
			if ( o.touchable ) {
				o.elm.bind( 'touchstart', function(e){ o.touchstart(e) } )
					.bind( 'touchmove', function(e){ o.touchmove(e) } )
					.bind( 'touchend', function(e){ o.touchend(e) } );
			} else {
				o.elm.bind( 'mousedown', function(e){ o.touchstart(e) } );
				$('body').bind( 'mouseup', function(e){ o.touchend(e) } )
					.bind( 'mousemove', function(e){ o.touchmove(e) } );
			}

			o.target.bind( 'webkitTransitionEnd', function(e) {
				if ( $.isFunction( o.onAnimationEnd ) ) {
					o.onAnimationEnd(e);
				}
			} );
			return o;
		},
		
		// 次のページへ移動
		nextPage: function( num ) {
			return this.goTo( this.page + (num || 1) );
		},
		
		// 前のページへ移動
		prevPage: function( num ) {
			return this.goTo( this.page - (num || 1) );
		},
		
		// 指定されたページへ移動
		goTo: function( pagenum ) {
			var pos = (pagenum -1) * this.pageWidth;
			return this.move( -pos );
		},
		
		// 指定されたX座標に移動
		move: function( pos ) {
			if ( pos > 0 ) {
				pos = 0;
			} else if ( pos < -this.elmWidth ) {
				pos = -this.elmWidth;
			}
			if ( this.android || ! this.webkit ) {
				this.target.animate( { left: pos + 'px' } );
			} else {
				this.target.css( {
					webkitTransition:"-webkit-transform 0.3s ease-in",
					webkitTransform:"translate3d("+pos+"px,0,0)"
				} );
			}
			return this.update( pos );
		},
		
		// 表示が変更されたら、各エレメントの大きさを計算し直す
		updateSize: function() {
			var o = this;
			var ori = typeof( window.orientation ) !== 'undefined'
				? ( window.orientation == 0 ? 'portrait' : 'landscape' )
				: ( window.innerWidth < window.innerHeight ? 'portrait' : 'landscape' );
			var lis = o.target.find('li');
	
			o.elm.removeClass('landscape portrait').addClass( ori );
			// うまく反映されない場合があるので、エレメント自体にclassを振る
			o.target.removeClass('landscape portrait').addClass( ori );
			lis.removeClass('landscape portrait').addClass( ori );
	
			var targw = o.target.width();
			var elmw = o.elm.width();
			o.elmWidth = targw - elmw;
	
			if ( o.snap == 'element' ) {
				o.pageWidth = elmw;
			} else if ( o.snap == 'first' ) {
				o.pageWidth = $(lis.get(0)).width();
			} else if ( o.snap == 'smallest' ) {
				var smaller = 0;
				lis.each( function() {
					var w = $(this).width();
					if ( smaller > w || smaller == 0 ) {
						smaller = w;
					}
				} );
				o.pageWidth = smaller;
			} else if ( ! isNaN(o.snap) ) {
				o.pageWidth = o.snap;
			} else {
				o.pageWidth = 0;
			}
			o.pageLength = Math.ceil( targw / o.pageWidth );
	
			if ( $.isFunction(o.onResize) ) {
				o.onResize();
			}
	
			o.goTo( o.page );
			return o;
		},

		touchstart: function(e) {
		},
		
		touchmove: function(e) {
		},
	
		touchend: function(e) {
		},
		
		update: function( pos ) {
			var o = this;
			if ( o.pageWidth ) {
				o.page = Math.ceil( (pos * -1) / o.pageWidth ) +1;
			}
			if ( o.currentX !== pos ) {
				o.currentX = pos;
				if ( $.isFunction( o.onChange ) ) {
					o.onChange();
				}
			}
			return o;
		},
		
		no_mousedown: function(e) {
			e.preventDefault();
		},
		
		// 初期化（内容に変更があった場合には、呼び出すこと）
		init: function() {
		}
	} );

	$.fn.flickSimple = function( param ) {
		var res = this;
		if ( typeof param === "string" ) { // 引数が文字列の場合
			var args = Array.prototype.slice.call(arguments, 1);
			this.each( function() {
				var instance = $.data(this, 'flickSimple');
				var val;
				if ( instance ) {
					if ( $.isFunction(instance[param]) ) {
						val = instance[param].apply(instance, args);
					} else {
						if ( args.length > 0 ) {
							instance[param] = args[1];
						}
						val = instance[param];
					}
				}
				if ( val !== instance ) {
					res = val
				}
			});
		} else {
			this.each( function() {
				var instance = $.data(this, 'flickSimple');
				if (! instance) {
					$.data(this, 'flickSimple', new $.flickSimple( this, param || {} ) );
				} else {
					res = instance;
				}
			} );
		}
		return res;
	};

})(jQuery);

