/**
* jquery-jcflick.js
* マルチデバイス対応(メディアクエリー対応)
* PC, iOS, Android
* 
* @version 0.0.5
* @Author: hiroki ooiwa;
* @Url:    http://hiropo.co.uk
* @Date    2010/10/22
* @Update  2011/09/30
*/

(function(jQuery){
/**============================================================
* global
*/
jQuery.fn.jcflick = function(config)
{
	//引数の初期値を設定（カンマ区切り）
	var defaults = {
		flickContainer: 'flickContainer',
		flickWrapper: 'flickWrapper',
		flickCol: 'flickCol',
		
		autoTimer: 5000
	}
	var options = $.extend( defaults, config );
	
	//一致した要素上で繰り返す
	return this.each(function(i){
		var self = $(this);
		//init
		init( options, self );
	});
}

var init = function( args, self ){
	
	/**------------------------------------------------------------
	* プロパティ
	*/
	var f = (typeof(f) == 'undefined' || !f)? {}: undefined;
	f.p = {
		//フリックするコンテンツの現在のページ値
		//0～
		nowPage: 0,
		
		//フリックエリアトータル横幅
		wrapperWidth: 0,
		
		//フリックする1つあたりのコンテンツ横幅
		colWidth: 0,
		
		//フリックするコンテンツ最大数
		totalLength: 0,
		
		//タッチした瞬間のX座標
		touchPositionX: 0,
		
		//タッチした瞬間のY座標
		touchPositionY: 0,
		
		//実際に移動する距離
		movePosition: 0,
		
		//現在地
		nowPosition: 0,
		
		//進むか戻るかの判定(X軸)
		positionIntX: 0,
		
		//進むか戻るかの判定(Y軸)
		positionIntY: 0,
		
		//フリックイベント判定
		flag: false,
		
		//自動で切り替わるフラグ
		autoChangeFlag: true,
		
		//Timer変数
		Timer: '',
		
		//Android用フリック調整Timer変数
		AndroidTimer: ''
	}
	
	/**------------------------------------------------------------
	* 汎用関数
	*/
	f.singleCol = function(className, self){
		var elm = $('.'+ className, self);
		return elm;
	}
	
	//ua
	f.ua = {
		Android: navigator.userAgent.indexOf('Linux; U; Android ')!=-1,
		Honeycomb: navigator.userAgent.indexOf('HONEYCOMB')!=-1,
		GalaxyTab: navigator.userAgent.indexOf('SC-01C')!=-1,
		iPod: navigator.userAgent.indexOf('iPod')!=-1,
		iPhone: navigator.userAgent.indexOf('iPhone')!=-1,
		iPad: navigator.userAgent.indexOf('iPad')!=-1
	}
	
	/**------------------------------------------------------------
	* args
	*/
	var flickContainer = f.singleCol(args.flickContainer, self);
	var flickWrapper = f.singleCol(args.flickWrapper, self);
	var flickCol = f.singleCol(args.flickCol, self);
	
	flickWrapper.css({ width: flickContainer.width() + 'px' });
	flickCol.css({ width: flickContainer.width() + 'px' });
	
	f.p.nowPage = (typeof(args.flickCur) != 'undefined')? args.flickCur: 0;
	
	/*------------------------------------------------------------
	* Module
	*/
	//iOS
	var flickWrapperCssTranslate3d = function(pos){
		flickWrapper.css({
			webkitTransition: 'all 0.6s',
			webkitTransform: 'translate3d('+ pos +'px, 0, 0)'
		});
	}
	//Android
	var flickWrapperCssTranslate = function(pos){
		flickWrapper.css({
			webkitTransition: 'all 0.6s',
			webkitTransform: 'translate('+ pos +'px, 0)'
		});
	}
	//PC
	var flickWrapperCssPostion = function(pos){
		flickWrapper.stop().animate({
			left: f.p.nowPosition +'px'
		}, 500);
	}
	
	//All
	var flickWrapperMoveAll = function(pos){
		//iPhone, iPad, iPod
		if( f.ua.iPhone || f.ua.iPad || f.ua.iPod ){
			flickWrapperCssTranslate3d(pos);
		}
		//Android
		else if( f.ua.Android ){
			flickWrapperCssTranslate(pos);
		}
		//PC
		else{
			flickWrapperCssPostion(pos);
		}
	}
	
	/**------------------------------------------------------------
	* 初期化
	*/
	f.p.wrapperWidth = (f.p.totalLength = flickCol.length)*(f.p.colWidth = flickCol.width());
	f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
	
	flickWrapperMoveAll(f.p.nowPosition);
	
	//lamp
	f.flickLamp = function(count){
		var span = $('<span>');
		span.addClass('lamp_def lamp_'+ count);
		span.html('');
		return span
	}
	f.flickLampCol = [];
	if( typeof(args.flickLamp) != 'undefined' ){
		
		//lamp position center
		if( f.ua.iPad ){
			var flickLamp = f.singleCol(args.flickLamp, self).html('').css({
				textAlign: 'center',
				width: flickContainer.width() + 'px'
			});
		}
		else{
			var flickLamp = f.singleCol(args.flickLamp, self).html('').css({
				textAlign: 'center'
			});
		}
		
		//lamp append
		for( var i = 0; i < f.p.totalLength; i++ ){
			f.flickLampCol[i] = new f.flickLamp(i);
			if( i === f.p.nowPage ){
				f.flickLampCol[i].addClass('lamp_cur');
			}
			flickLamp.append( f.flickLampCol[i] );
		}
	}
	
	//option
	var autoChange = false;
	autoChange = (args.autoChange)? args.autoChange: false;
	
	//Timer
	var mintime = args.autoTimer;
	var autoChangeFunc = function(){
		if( f.p.autoChangeFlag ){
			f.p.nowPosition = f.p.movePosition;
			
			if( typeof(args.flickBtn) != 'undefined' ){
				f.flickBtnNext.removeClass('btnFalse').addClass('pointer');
				f.flickBtnBack.removeClass('btnFalse').addClass('pointer');
			}
			
			//進む
			if( f.p.nowPage < f.p.totalLength ){
				if( f.p.nowPage < (f.p.totalLength - 1) ){
					f.p.nowPage++;
					f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
					
					flickWrapperMoveAll(f.p.nowPosition);
					
					if( typeof(args.flickBtn) != 'undefined' && f.p.nowPage == (f.p.totalLength - 1) ){
						f.flickBtnNext.removeClass('pointer').addClass('btnFalse');
					}
				}
				else if( f.p.nowPage === (f.p.totalLength - 1) ){
					//最小値までフリックした場合、0地点に戻す
					f.p.nowPage = 0;
					f.p.nowPosition = 0;
					
					flickWrapperMoveAll(f.p.nowPosition);
					
					if( typeof(args.flickBtn) != 'undefined' ){
						f.flickBtnBack.removeClass('pointer').addClass('btnFalse');
					}
				}
			}
			if( typeof(args.flickLamp) != 'undefined' && typeof(f.flickLampCol[f.p.nowPage]) != 'undefined' ){
				//lamp削除
				for( var i = 0; i < f.p.totalLength; i++ ){
					f.flickLampCol[i].removeClass('lamp_cur');
				}
				//カレント追加
				f.flickLampCol[f.p.nowPage].addClass('lamp_cur');
			}
		}
	}
	
	var autoWidthChange = function(){
		if( f.p.autoChangeFlag ){
			flickWrapper.css({ width: flickContainer.width() + 'px' });
			flickCol.css({ width: flickContainer.width() + 'px' });
			if( typeof(args.flickBtn) != 'undefined' ){
				flickBtn.css({ width: flickContainer.width() + 'px' });
			}
			f.p.wrapperWidth = (f.p.totalLength = flickCol.length)*(f.p.colWidth = flickCol.width());
			flickWrapper.css({
				width: f.p.wrapperWidth
			});
			f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
			flickWrapperMoveAll(f.p.nowPosition);
		}
	}
	
	//flickBtn
	f.flickBtn = function(className, value){
		var span = $('<span>');
		span.addClass( 'flick_btn_' + className );
		span.html(value);
		return span;
	}
	//event 進む
	var autoChangeFlagTrue = function(){ f.p.autoChangeFlag = true; }
	
	if( typeof(args.flickBtn) != 'undefined' ){
		//new btn
		var flickBtn = f.singleCol(args.flickBtn, self).html('').css({ width: flickContainer.width() + 'px' });
		var flag = true;
		
		var fbn = (typeof(args.flickBtnNextName) != 'undefined')? args.flickBtnNextName: 'next';
		var fbb = (typeof(args.flickBtnBackName) != 'undefined')? args.flickBtnBackName: 'back';
		
		//append
		f.flickBtnNext = new f.flickBtn('next', fbn);
		f.flickBtnBack = new f.flickBtn('back', fbb);
		if( f.p.nowPage === 0 ){
			f.flickBtnNext.addClass('pointer');
			f.flickBtnBack.addClass('btnFalse');
		}
		else if( f.p.nowPage === (f.p.totalLength - 1) ){
			f.flickBtnNext.addClass('btnFalse');
			f.flickBtnBack.addClass('pointer');
		}
		else{
			f.flickBtnNext.addClass('pointer');
			f.flickBtnBack.addClass('pointer');
		}
		flickBtn.append( f.flickBtnNext );
		flickBtn.append( f.flickBtnBack );
		
		f.flickBtnNext.bind('click', function(){
			f.p.autoChangeFlag = false;
			clearInterval(f.p.Timer);
			clearInterval(f.p.AndroidTimer);
			
			flag = false;
			if( f.p.nowPage < (f.p.totalLength - 1) ){
				f.p.nowPage++;
				f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
				
				flickWrapperMoveAll(f.p.nowPosition);
				
				f.flickBtnBack.removeClass('btnFalse').addClass('pointer');
				if( f.p.nowPage == (f.p.totalLength - 1) ){
					f.flickBtnNext.removeClass('pointer').addClass('btnFalse');
				}
				if( typeof(args.flickLamp) != 'undefined' && typeof(f.flickLampCol[f.p.nowPage]) != 'undefined' ){
					//lamp削除
					for( var i = 0; i < f.p.totalLength; i++ ){
						f.flickLampCol[i].removeClass('lamp_cur');
					}
					//カレント追加
					f.flickLampCol[f.p.nowPage].addClass('lamp_cur');
				}
			}
			flag = true;
			autoChangeFlagTrue();
			if( autoChange ){
				f.p.Timer = setInterval(autoChangeFunc, mintime);
			}
			f.p.AndroidTimer = setInterval(autoWidthChange, 1000);
		});
		
		//event 戻る
		f.flickBtnBack.bind('click', function(){
			f.p.autoChangeFlag = false;
			clearInterval(f.p.Timer);
			clearInterval(f.p.AndroidTimer);
			
			flag = false;
			if( f.p.nowPage > 0 ){
				f.p.nowPage--;
				f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
				
				flickWrapperMoveAll(f.p.nowPosition);
				
				f.flickBtnNext.removeClass('btnFalse').addClass('pointer');
				if( f.p.nowPage === 0 ){
					f.flickBtnBack.removeClass('pointer').addClass('btnFalse');
				}
				if( typeof(args.flickLamp) != 'undefined' && typeof(f.flickLampCol[f.p.nowPage]) != 'undefined' ){
					//lamp削除
					for( var i = 0; i < f.p.totalLength; i++ ){
						f.flickLampCol[i].removeClass('lamp_cur');
					}
					//カレント追加
					f.flickLampCol[f.p.nowPage].addClass('lamp_cur');
				}
			}
			flag = true;
			autoChangeFlagTrue();
			if( autoChange ){
				f.p.Timer = setInterval(autoChangeFunc, mintime);
			}
			f.p.AndroidTimer = setInterval(autoWidthChange, 1000);
		});
	}
	var androidua = navigator.userAgent;
	function touchHandler(event){
		if( event.type === 'touchstart' ){
			f.p.autoChangeFlag = false;
			f.p.touchPositionX = event.originalEvent.touches[0].clientX;
			f.p.touchPositionY = event.originalEvent.touches[0].clientY;
			clearInterval(f.p.Timer);
			clearInterval(f.p.AndroidTimer);
		}
		if( event.type === 'touchmove' ){
			f.p.positionIntX = f.p.touchPositionX - event.originalEvent.touches[0].clientX;
			f.p.positionIntY = f.p.touchPositionY - event.originalEvent.touches[0].clientY;
			$('#a').html(f.p.positionIntX);
			if( Math.abs(f.p.positionIntX) > 5 ){
				event.preventDefault();
				f.p.flag = true;
				f.p.movePosition = f.p.nowPosition - f.p.positionIntX;
				
				flickWrapper.css({
					webkitTransition: 'none',
					webkitTransform: 'translate3d('+ f.p.movePosition +'px, 0, 0)'
				});
			}
		}
		if( event.type === 'touchend' ){
			if( f.p.flag ){
				f.p.nowPosition = f.p.movePosition;
				
				if( typeof(args.flickBtn) != 'undefined' ){
					f.flickBtnNext.removeClass('btnFalse').addClass('pointer');
					f.flickBtnBack.removeClass('btnFalse').addClass('pointer');
				}
				
				//進む
				if( f.p.positionIntX > 50 ){
					if( f.p.nowPage < (f.p.totalLength - 1) ){
						f.p.nowPage++;
						f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
						flickWrapperMoveAll(f.p.nowPosition);
						if( typeof(args.flickBtn) != 'undefined' && f.p.nowPage == (f.p.totalLength - 1) ){
							f.flickBtnNext.removeClass('pointer').addClass('btnFalse');
						}
					}
					else{
						//最大値までフリックした場合、最大値で止まる
						f.p.nowPosition = -(f.p.colWidth * (f.p.totalLength - 1));
						flickWrapperMoveAll(f.p.nowPosition);
						if( typeof(args.flickBtn) != 'undefined' && f.p.nowPage == (f.p.totalLength - 1) ){
							f.flickBtnNext.removeClass('pointer').addClass('btnFalse');
						}
					}
				}
				//戻る
				else if( f.p.positionIntX < -50 ){
					if( f.p.nowPage <= 0 ){
						//最小値までフリックした場合、0地点に戻す
						f.p.nowPage = 0;
						f.p.nowPosition = 0;
						flickWrapperMoveAll(f.p.nowPosition);
						if( typeof(args.flickBtn) != 'undefined' ){
							f.flickBtnBack.removeClass('pointer').addClass('btnFalse');
						}
					}
					else{
						f.p.nowPage--;
						f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
						flickWrapperMoveAll(f.p.nowPosition);
						if( typeof(args.flickBtn) != 'undefined' && f.p.nowPage === 0 ){
							f.flickBtnBack.removeClass('pointer').addClass('btnFalse');
						}
					}
				}
				else {
					f.p.nowPosition = -(f.p.colWidth * f.p.nowPage);
					flickWrapperMoveAll(f.p.nowPosition);
				}
				if( typeof(args.flickLamp) != 'undefined' && typeof(f.flickLampCol[f.p.nowPage]) != 'undefined' ){
					//lamp削除
					for( var i = 0; i < f.p.totalLength; i++ ){
						f.flickLampCol[i].removeClass('lamp_cur');
					}
					//カレント追加
					f.flickLampCol[f.p.nowPage].addClass('lamp_cur');
				}
				autoChangeFlagTrue();
				if( autoChange ){
					f.p.Timer = setInterval(autoChangeFunc, mintime);
				}
				f.p.AndroidTimer = setInterval(autoWidthChange, 1000);
			}
			f.p.flag = false;
		}
		if( event.type === 'touchcancel' ){
			autoChangeFlagTrue();
			if( autoChange ){
				f.p.Timer = setInterval(autoChangeFunc, mintime);
			}
			f.p.AndroidTimer = setInterval(autoWidthChange, 1000);
		}
	}
	if( !androidua.match(/Android 1\.5/) || !androidua.match(/Android 1\.6/) ){
		flickWrapper.bind('touchstart touchmove touchend touchcancel', touchHandler);
	}
	if( autoChange ){
		f.p.Timer = setInterval(autoChangeFunc, mintime);
	}
	//------------------------------------------------------------
	// どの横幅からでも1秒間1回横幅を取得して再計算させる。
	// これによりどの端末からでもリキッド状態のカルーセルフリックが可能となる。
	//
	f.p.AndroidTimer = setInterval(autoWidthChange, 1000);
}


//============================================================
})(jQuery);
