(function(){

//=======================================
// 設定
//=======================================

var opacity = .8, // マウスオーバー時の不透明度 0〜1
	easing = 'linear', //イージング http://semooh.jp/jquery/cont/doc/easing/
	duration = 250, // 速度 1/1000秒
	wait = 5000; // 表示時間 1/1000秒

var suffix = {
	on:'_on',
	active:'_on',
	off:'_off'
};

//=======================================

var topSliderCnt = '#topSlider',
	listContainer = '#topSliderList',
	navContainer = '#topSliderNav',
	lArrow = '#lArrow',
	rArrow = '#rArrow';

var listNum = 3,
	width = 920,
	liWidth = 766,
	centerX = width / 2,
	offsetX = (width - liWidth) / 2,
	liHarfWidth = liWidth / 2,
	timer;

// liArr以外は疑似配列 (jQueryオブジェクト
// 配列のメソッドを利用したい場合はcallかapplyで
var allLiArr,liArr = [],navArr;

// 選択中のオブジェクト
var activeLi,activeNav;

// フラグ
var liMouseoverFlg = false,
	moveFlg = false; // 移動中か否か

var que = false,
	queV,queC;

//===========================================
// 移動
//===========================================

var move = (function(){
	var i,
		c, // 連続移動回数
		v, // 移動ベクトル
		numV; // 配列追加ベクトル

	//---------------------------------------
	// callBack 移動完了後呼び出される。
	//---------------------------------------
	var callBack = (function(){
		var num;
		return function(){	
			if(numV === -1){
				num = $(liArr.pop()).data('num');
				listContainer.find('li:last-child').remove();
				$(allLiArr[num-1]).data('num',num);
			}else if(numV === 1){
				num = $(liArr.shift()).data('num');
				listContainer.find('li:first-child').remove();
				$(allLiArr[num-1]).data('num',num);
			};
			// ループするかどうかの処理
			c--;
			if(c <= 0){
				if(activeLi.attr('class') === 'ghost'){
					move(v,1);
				}else{
					moved();
				};
			}else{
				if(que){
					que = false;
					v = activeLi.data('num') - activeNav.data('num');
					c = v < 0 ? v*-1 : v ;
					v = v < 0 ? -1 : 1 ;
				}
				move(v,c);
			}
		}
	})();

	//---------------------------------------
	// setting 配列やリストの設定
	//---------------------------------------
	var setting = function(){
		var i,
			num,
			pos; // 新しく追加するリストの位置に利用
		return function(_v){
			// 配列追加ベクトル
			numV = _v * -1;
			if(numV === -1){
				// 左に追加の場合
				activeLi = $(liArr[0]);
				num = activeLi.data('num') + numV;
				if(num === 0) num = allLiArr.length;
				// 位置を設定
				pos = listContainer.find('li:first-child')[0].offsetLeft - liWidth;
				// 配列に追加
				liArr.unshift(allLiArr[num-1]);
				// コンテナに追加
				listContainer.prepend(liArr[0]);
				// スタイルとイベントの設定
				$(liArr[0])
					.css('left',pos+'px')
					.find('a').bind('mouseover',liMouseEvent).bind('mouseout',liMouseEvent);
			//---------------------------------
			}else if(numV === 1){
				// 右に追加の場合
				activeLi = $(liArr[2]);
				num = activeLi.data('num');
				if(num === allLiArr.length){
					num = 0;
				}
				// 位置を設定
				pos = listContainer.find('li:last-child')[0].offsetLeft + liWidth;
				// 配列に追加
				liArr.push(allLiArr[num]);
				// コンテナに追加
				listContainer.append(liArr[liArr.length-1]);
				$(liArr[liArr.length-1])
					.css('left',pos+'px')
					.find('a').bind('mouseover',liMouseEvent).bind('mouseout',liMouseEvent);
			}
		}
	}();

	//---------------------------------------
	// インスタンス
	//---------------------------------------
	return function(_v,_c){
		// フラグを実行中に
		moveFlg = true;
		v = _v;
		// 連続回数
		c = _c || 1;
		// 配列やリストの設定
		setting(_v);
		// リスト数callbackが呼ばれるのでカウント
		i = 0;
		// アニメーション
		$(liArr).animate({
			'left':'+='+liWidth * v
		},duration,easing,function(){
			i++;
			if(liArr.length === i) callBack();
		});
	}
})();

//===========================================
// 移動終了後
//===========================================

var moved = function(){
	moveFlg = false;
	navActivate($(navArr[activeLi.data('num')-1]));
	// タイマー再設定
	clearInterval(timer);
	timer = setInterval(interval,wait);
}

//===========================================
// 初期化
//===========================================

var init = function(){
	// リストとナビの数が一致していない場合の処理
	if($(listContainer+' li').length !== $(navContainer+' li').length){
		alert('topSlider : リストの数とナビの数が一致していません。');
		return false;
	};
	topSliderCnt = $(topSliderCnt);
	// --------------------------------------
	// リストの設定
	// --------------------------------------
	(function(){
		var i,l,val = 0;//arr = Array.prototype;
		allLiArr = $(listContainer+' li');
		// リスト数が必須数4以下だった場合の処理
		// 常に3つ表示でループさせるには最低4つ必要
		if(allLiArr.length < 4){
			l = 4 - allLiArr.length;
			for(i=0; i<l; i++){
				$(listContainer).append('<li class="ghost"></li>');
			}
			allLiArr = $(listContainer+' li');
		};
		// コンテナを空にしてからjQuery参照渡し
		$(listContainer).empty();
		listContainer = $(listContainer);
		// 番号を付加
		for(var i=0,l=allLiArr.length; i<l; i++){
			$(allLiArr[i]).data('num',i+1);
		};
		// 最初のものを中央に持ってくるため、[1][2][3]を[3][1][2]に
		//arr.unshift.call(allLiArr,arr.pop.call(allLiArr));
		// listContainerに追加
		liArr.push(allLiArr[allLiArr.length-1]);
		listContainer.append(liArr[0]);
		for(i=0;i<listNum-1;i++){
			liArr.push(allLiArr[i]);
			listContainer.append(liArr[i+1]);
		}
		// 位置の調整
		for(i=0;i<listNum;i++){
			val = (i===0) ? -1 * liWidth : (i===1) ? 0 : (i-1) * liWidth ;
			val = (val+offsetX)+'px';
			$(liArr[i]).css('left',val);
		}
		//　マウスイベント登録
		$(liArr).find('a').bind('mouseover',liMouseEvent).bind('mouseout',liMouseEvent);
		// 初期アクティブ
		activeLi = $(liArr[1]);
	})();
	// --------------------------------------
	// 矢印の設定
	// --------------------------------------
	$(lArrow)
		.bind('click',function(t){arrowMouseEvent(t,1)})
		.bind('mouseover',arrowMouseEvent).bind('mouseout',arrowMouseEvent);
	$(rArrow)
		.bind('click',function(t){arrowMouseEvent(t,-1)})
		.bind('mouseover',arrowMouseEvent).bind('mouseout',arrowMouseEvent);
	// --------------------------------------
	// ナビの設定
	// --------------------------------------
	(function(){
		var src,pre;
		navArr = $(navContainer+" li");
		navContainer = $(navContainer);
		//番号付加
		for(var i=0,l=navArr.length; i<l; i++){
			$(navArr[i]).data('num',i+1);
		};
		// 初期アクティブ化
		activeNav = $(navArr[0]);
		activeNav.addClass('active');
		// 画像のurl変更　必要があれば分離
		pre = activeNav.find('img');
		src = pre.attr('src').replace(suffix.off,suffix.active);
		pre.attr('src',src);
		pre.hover(function(e){
			src = $(this).attr('src').replace(suffix.off,suffix.on);
		pre.attr('src',src);
		},function(e){
			src = $(this).attr('src').replace(suffix.on,suffix.off);
			pre.attr('src',src);
		});
		//
		// イベント登録
		navArr.bind('click',navMouseEvent);
	})();
	// --------------------------------------
	// timerセット
	timer = setInterval(interval,wait);
}


//===========================================
// interval 定期呼び出しメソッド
//===========================================
var interval = function(){
	// マウスが乗ってない状態でかつリストが動いていない状態のとき
	if(!liMouseoverFlg && !moveFlg){
		move(-1,1);
	}
}

//===========================================
// navActivate
//===========================================

var navActivate = (function(){
	var src,pre;
	return function(t){
		pre = activeNav.find('img');
		src = pre.attr('src').replace(suffix.active,suffix.off);
		pre.attr('src',src);	
		activeNav.removeClass('active');
		activeNav = t;
		activeNav.addClass('active');
		pre = activeNav.find('img');
		src = pre.attr('src').replace(suffix.off,suffix.active);
		pre.attr('src',src);
	}
})();

//===========================================
// イベントハンドラ
//===========================================

// リストのマウスイベント処理
// liMouseoverはリストの動きを止める。
var liMouseEvent = function(t){
	if(t.type === 'mouseover'){
		$(this).css('opacity',opacity);
	}else if(t.type === 'mouseout'){
		$(this).css('opacity',1);
	}
	liMouseoverFlg = !liMouseoverFlg;
};


// ナビのマウスイベント処理
var navMouseEvent = (function(){
	var v,c;
	return function(t){
		if($(this).data('num') === activeNav.data('num')) return false;
		navActivate($(this));
		v = activeLi.data('num') - $(this).data('num');
		c = v < 0 ? v*-1 : v ;
		v = v < 0 ? -1 : 1 ;
		// 動いてなければ直ぐ実行
		if(!moveFlg) move(v,c);
		// 動いている場合の処理
		if(moveFlg) que = true;
	}
})();


// 矢印のマウスイベント処理
var arrowMouseEvent = function(t,v){
	if(t.type === 'click'){
		if(!moveFlg) move(v,1);
	}else{
		if(t.type === 'mouseover'){
			$(this).css('opacity',opacity);		
		}else if(t.type === 'mouseout'){
			$(this).css('opacity',1);
		}
		liMouseoverFlg = !liMouseoverFlg;	
	}
}

//===========================================
// ready...
//===========================================
$(init);

})();

