/**
 * omkslider
 *
 * @version      1.0
 * @author       ajike
 * @copyright    ajike.co.jp
 * @license      The MIT License
 *
 *　■呼び出し方法
 *　$('#omkslider-content').omkslider();
 *  
 *  ■css (omkslider.css)
 *  #omkslider-content
 *  .omkslider-box
 *  .omkslider-boxinner
 *  .omkslider-large
 *  .omkslider-small
 *  .omkslider-btn
 *
 */

(function($) {
	
	// ***********************************************
	//
	// omkslider Plugin
	// 
	// ***********************************************
	$.fn.omkslider = function(options) {
		var config = $.extend({
			intervalWidth : 620, //画像の配置間隔（小さい画像を基点）
			offsetX:470, //中心点Xを指すoffset
			offsetY:170, //中心点Yを指すoffset
			smallWidth:565, //縮小時の横幅
			smallHeight:262, //縮小時の縦幅
			largeWidth:707, //拡大時の横幅
			largeHeight:328, //拡大時の縦幅
			idx:0, //初期index ※現在0のみ。他の値は未実装
			duration:500, //moveにかかる時間
			timerDelay:2900 //自動で動く時間間隔
		}, options);
		
		var $content = this;
		var $contentInner = $(".omkslider-contentinner",$content);
		var $btnLeft = $(".omkslider-btnleft",$content);
		var $btnRight = $(".omkslider-btnright",$content);
		var factory = new OmkBoxFactory();
		var _boxs = [];
		var _deleteBoxs = [];
		var _idx = config.idx;
		var _oldidx = config.idx; //同じidx値の移動を無視するためにold値を持っておく
		var _timerId;  //setIntervalのID
		var beforeclickTime = 0;
		
		
		//指定通りに呼び出されていなければエラー
		if($content.length == 0){
			throw new Error(" $('#omkslider-content').omkslider(); と呼び出してください。 ");
		}
		
		//$contentが id でなく classで指定されていればエラー
		if($content.attr("id") == null || $content.attr("id") == ""){
			throw new Error(" classでなくidで指定してください。 ");
		}
		
		function _init(){
			//それぞれのboxをセット
			$(".omkslider-box",$content).each(function(i){
				factory.add($(this));
			})
			
			for (var i = -1; i <= 1; i++){
				var boxClass = factory.create(_idx + i);
				boxClass.position(i);
				$contentInner.append(boxClass.$box);
				_boxs.push(boxClass);
			};
			
			addHoverTimerStop($btnLeft);
			addHoverTimerStop($btnRight);
			_addTimer();  //タイマースタート
		}
		_init();
		
		
		// ***********************************************
		//
		// Event Handler
		// 
		// ***********************************************
		$btnLeft.click(function(){
			var time = _getTimer();
			if((time - this.beforeclickTime) < config.duration-100){
				return;
			}
			this.beforeclickTime = time;
			
			_idx = --_idx;
			removeBoxRight();
			addBoxLeft();
			_move();
		});
		
		$btnRight.click(function(){
			var time = _getTimer();
			if((time - this.beforeclickTime) < config.duration-100){
				return;
			}
			this.beforeclickTime = time;
			
			_idx = ++_idx;
			removeBoxLeft();
			addBoxRight();
			_move();
		});
		
		function _timerHandler(){
			var time = _getTimer();
			if((time - this.beforeclickTime) < config.duration-100){
				return;
			}
			this.beforeclickTime = time;
			
			_idx = ++_idx;
			removeBoxLeft();
			addBoxRight();
			_move();
		}
		
		// ***********************************************
		//
		// private function
		// 
		// ***********************************************
		function _move(){
			if(_oldidx == _idx) return; //同じ位置での処理を回避
			
			for (var i = 0; i < _boxs.length; i++){
				var box = _boxs[i];
				var toIdx = box.idx - _idx;
				box.anime(toIdx);
			};
			
			_oldidx = _idx;
		}
		
		/*
		 *  タイマー処理追加
		 */
		function _addTimer(){
			//タイマー処理
			_timerId = setInterval(_timerHandler,config.timerDelay);
		}
		
		/*
		 *  タイマー処理削除
		 */
		function _removeTimer(){
			//タイマー処理
			clearInterval(_timerId);
		}
		
		/*
		 *  マウスオーバー中はタイマーを削除
		 */
		function addHoverTimerStop($obj){
			$obj.hover(
				function(){_removeTimer();}
				,function(){_addTimer();}
			);
		}
		
		/*
		 *  左端にboxを追加（移動時に呼ばれる）
		 */
		function addBoxLeft(){
			var boxClass = factory.create(_idx-1);
			boxClass.position(-2);
			$contentInner.append(boxClass.$box);
			_boxs.unshift(boxClass);
		}
		
		/*
		 *  右端にboxを追加（移動時に呼ばれる）
		 */
		function addBoxRight(){
			var boxClass = factory.create(_idx+1);
			boxClass.position(+2);
			$contentInner.append(boxClass.$box);
			_boxs.push(boxClass);
		}
		
		/*
		 *  左端のboxを削除（移動時に呼ばれる）
		 */
		function removeBoxLeft(){
			var box = _boxs[_deleteBoxs.length];
			box.removeflg = true;
			box.removeTarget = "left";
			_deleteBoxs.push(box);
		}
		
		/*
		 *  右端のboxを削除（移動時に呼ばれる）
		 */
		function removeBoxRight(){
			var box = _boxs[_boxs.length-1 -_deleteBoxs.length];
			box.removeflg = true;
			box.removeTarget = "right";
			_deleteBoxs.push(box);
		}
		
		function _getTimer(){
			var now = new Date();
			return now.getTime();
		}
		
		// ***********************************************
		//
		// Class (newして使われる)
		// 
		// ***********************************************
		/*
		 *  new OmkBoxFactory()
		 *  new OmkBoxを生成するクラス
		 */
		function OmkBoxFactory(){
			this.node = {};
			this.count = 0;
			this.add = function($box){
				this.node[this.count] = $box;
				this.count++;
				$box.remove(); 
			}
			this.create = function(idx){
				//-2や-1,2,3,5に対応
				var boxNum = this.getTargetBoxNum(idx);
				return new OmkBox(idx ,boxNum , this.node[boxNum].clone() );
			}
			this.getTargetBoxNum = function(idx){
				return (this.count + (idx % this.count))%this.count;
			}
		}
		
		/*
		 *  new OmkBox()
		 *  .omkslider-boxに対応するクラス
		 */
		function OmkBox(idx,boxNum,$box){
			this.idx = idx;
			this.boxNum = boxNum;
			this.$box = $box;
			this.$img = new OmkImg( $(".omkslider-img",$box) );
			this.$btn = new OmkBtn( $(".omkslider-btn",$box) );
			this.removeflg = false;
			this.removeTarget;
			 
			this.anime = function(toIdx){
				var removeflg = this.removeflg;
				var disposeFunc = this.dispose;
				var scope=this;
				var zindex;
				if(this.idx == _idx){
					//拡大
					this.$img.animeLarge();
					this.$btn.animeShow();
					zindex = 100;
				} else {
					//縮小
					this.$img.animeSmall();
					this.$btn.animeHide();
					zindex = 1;
				}
				//boxを移動
				this.$box.animate(
					{
						"left":toIdx * config.intervalWidth + config.offsetX - this.$img.smallW/2
						,"top":config.offsetY - this.$img.smallH/2
					}
					,config.duration
					,"easeOutCirc"
					,function(){
						if(_deleteBoxs.length > 0) disposeFunc.apply(scope);
					}
					);
				//深度を変更
				this.$box.css({
					"z-index": zindex
				});
			}
			
			this.dispose = function(){
				var n = _deleteBoxs.length;
				for(i = 0 ; i < n ; i++){
					var box = _deleteBoxs.shift();
					if(box.removeTarget == "left"){
						_boxs.shift();
					} else {
						_boxs.pop();
					}
					box.$box.remove();
				}
			}
			
			this.position = function(positionIdx){
				this.$box.css({
					"left":config.offsetX - this.$img.smallW/2 + config.intervalWidth*positionIdx +"px"
					,"top":config.offsetY - this.$img.smallH/2 +"px"
				});
			}
			
			//init
			this._init = function(){
				if(this.idx == config.idx){
					this.$img.animeLarge(true);
					this.$btn.animeShow(true);
					this.$box.css({"z-index": 100});
				} else {
					this.$img.animeSmall(true);
					this.$btn.animeHide(true);
					this.$box.css({"z-index": 1});
				}
				
				addHoverTimerStop(this.$box);
				//this.$box.remove() //init時は削除
				//console.log(this.$box);
			}
			this._init();
		}
		
		/*
		 *  new OmkImg()
		 *  .omkslider-imgに対応するクラス
		 */
		function OmkImg($img){
			this.$img = $img;
			this.smallW = config.smallWidth;
			this.smallH = config.smallHeight;
			this.largeW = config.largeWidth;
			this.largeH = config.largeHeight;
			
			this.animeLarge = function(initBool){
				
				
				//IEの場合、PNGにopacityを欠けると汚くなるため無視
				var ua = $.browser;
				if(!ua.msie){
					this.$img.animate({
						"width":this.largeW
						,"height":this.largeH
						,"left":-(this.largeW - this.smallW)/2
						,"top":-(this.largeH - this.smallH)/2
						,"opacity":1
					}
					,initBool ? 0 :config.duration,"easeInQuad" );
				} else {
					this.$img.animate({
						"width":this.largeW
						,"height":this.largeH
						,"left":-(this.largeW - this.smallW)/2
						,"top":-(this.largeH - this.smallH)/2
					}
					,initBool ? 0 :config.duration,"easeInQuad" );
				}
			}
			this.animeSmall = function(initBool){
				
				
				//IEの場合、PNGにopacityを欠けると汚くなるため無視
				var ua = $.browser;
				if(!ua.msie){
					this.$img.animate({
						"width":this.smallW
						,"height":this.smallH
						,"left":0
						,"top":0
						,"opacity":0.4
						}
					,initBool ? 0 :config.duration,"easeOutQuad");
				} else {
					this.$img.animate({
						"width":this.smallW
						,"height":this.smallH
						,"left":0
						,"top":0
						}
					,initBool ? 0 :config.duration,"easeOutQuad");
				}
			}
			
			this._init = function(){
				this.$img.css({"width":this.smallW});
				this.$img.css({"height":this.smallH});
			}
			
			this._init();
		}
		
		/*
		 *  new OmkBtn()
		 *  .omkslider-btnに対応するクラス
		 */
		function OmkBtn($btn){
			this.$btn = $btn;
			
			this.animeShow = function(initBool){
				//IEの場合、PNGにopacityを欠けると汚くなるため無視
				var ua = $.browser;
				if(!ua.msie){
					this.$btn.animate({
						"opacity":1
						}
					,initBool ? 0 :config.duration,"easeInExpo" );
				} else {
					this.$btn.show();
				}
				
							}
			this.animeHide = function(initBool){
				//IEの場合、PNGにopacityを欠けると汚くなるため無視
				var ua = $.browser;
				if(!ua.msie){
					this.$btn.animate({
						"opacity":0
						}
					,initBool ? 0 :config.duration,"easeOutExpo" );
				} else {
					this.$btn.hide();
				}
			}
			
			
			this._init = function(){
				$("a",this.$btn).simpleRollOver();
				var w = $btn.width() !== 0 ? $btn.width() : $("img",$btn).attr("width") !== 0 ? $("img",$btn).attr("width") : 230;
				var h = $btn.height() !== 0 ? $btn.height() : $("img",$btn).attr("height") !== 0 ? $("img",$btn).attr("height") : 40;
				this.$btn.animate({
					"left":config.largeWidth - w -102
					,"top":config.largeHeight - h -55
				},0);
				
			}
			this._init();
		}
		
		return this;		
	}

})(jQuery);



$(document).ready(function(){
	//omkslider-contentを指定
	$('#omkslider-content').omkslider();
});
	
	
// JavaScript Document
