/**
 * アイキャッチ部分のロード処理
 * @param {String} mode "top" または "shopTop"
 * @param {String} id アイキャッチをロードする部分の ID
 * @param {Object} json アイキャッチ用の JSON データ
 * @param {Number} loopTime 端に到達する秒数 (ms)
 */
function loadEyeCatch(mode, id, json, loopTime) {
	var eyecatch = new jQuery.Eyecatch(mode, id, json, loopTime);
	eyecatch.start();
}

(function ($) {
/** プリロード処理用クラス. */
$.Preloader = function () {
	/** インスタンス参照用. */
	var that = this;
	/** プリローダにセットされた全画像数. */
	this.count = 0;
	/** ロードされた画像の個数. */
	this.loaded = 0;
	
	/**
	 * コールバックメソッド.
	 * 画像のロードが終わる度に通知される.
	 * @param {Object} preloader Preloader オブジェクト.
	 * @param {Number} count プリローダにセットされた画像の数.
	 * @param {Number} loaded ロードされた画像の数.
	 */
	this.callback = function (preloader, count, loaded) {
		console.log("callback " + preloader + count + " " + loaded);
	};
	
	/**
	 * 画像のキャッシュ開始.
	 * @param {Array} images 画像 URL の配列.
	 */
	this.loadImages = function (images) {
		var count = images.length;
		//console.log("images " + count);
		for (var i = count; i--;) {
			this.loadImage(images[i]);
		}
	};
	
	/**
	 * 画像のキャッシュ開始.
	 * @param {String} url 画像 URL.
	 */
	this.loadImage = function (url) {
		this.count++;
		var img = document.createElement("img");
		$(img).attr("src", url).load(this._onImageLoaded);
		$(img).attr("src", url); // なぜか参照しないとロードされない (IE 7)
	};
	
	/**
	 * 画像のロードが完了した時に呼び出されるメソッド.
	 * @param {Object} e イベントオブジェクト.
	 */
	this._onImageLoaded = function (e) {
		that.loaded++;
		that.callback(that, that.count, that.loaded);
	};
};
})(jQuery);

(function ($) {
/** 画像リスト. JSON データから画像の URL のみを抽出する. */
$.ImageList = function () {
	/** プリロードする画像のリスト. */
	this.preloadList = [];
	/** 遅延ロードする画像のリスト. */
	this.lazyList = [];
	
	/** プリロードする画像の数. */
	this.preloadCount = 0;
	/** 画像の数. */
	this.count = 0;
	
	/**
	 * アイキャッチ用 JSON をパースする.
	 * @param {Object} json JSON オブジェクト.
	 * @param {Number} preloadCount プリロードする数.
	 */
	this.parseJson = function (json, preloadCount) {
		this.preloadCount = preloadCount;
		// ジャック画像
		var splashUrl = json.splash.url;
		if (splashUrl != "") {
			this.preloadList.push(splashUrl);
		}
		
		// レイアウト部分をパースする
		this._parseLayout(json);
	};
	
	/**
	 * レイアウト部分をパースする.
	 * @param {Object} json JSON オブジェクト.
	 */
	this._parseLayout = function (json) {
		var layouts = json.layouts;
		var length = layouts.length;
		for (var i = 0; i < length; i++) {
			this._parseImages(layouts[i].images);
		}
	};
	
	/**
	 * 画像リスト部分をパースする.
	 * @param {Object} json JSON オブジェクト.
	 */
	this._parseImages = function (images) {
		//console.log("this.count: " + this.count);
		var length = images.length;
		for (var i = 0; i < length; i++) {
			var url = images[i].img;
			if (url == "" || url == undefined) {
				continue;
			}
			this.count++;
			if (this.count > this.preloadCount) {
				this.lazyList.push(url);
				continue;
			}
			this.preloadList.push(url);
		}
	};
};
})(jQuery);

(function ($) {
/** ジャック画像. */
$.Splash = function () {
	/** インスタンス参照用. */
	var that = this;
	var SPLASH_WAIT = 4000;
	
	/** ジャック画像がクリックされたら true. */
	this.splashClicked = false;
	
	/** ジャック画像の入った img 要素への参照. */
	this.img = null;
	
	/**
	 * コールバックメソッド.
	 * ジャック画像の表示が終了した時に呼び出される.
	 */
	this.callback = function () {
		console.log("$.Splash.callback()");
	};
	
	/**
	 * ジャック画像をロードする.
	 * @param {Object} target ジャック画像をロードする div タグの jQuery オブジェクト.
	 * @param {String} url ジャック画像の URL.
	 * @param {String} link クリックした時に遷移する URL.
	 * @param {String} wt ウインドウのターゲット指定.
	 */
	this.load = function (target, url, link, wt) {
		target.append("<div class='ec_splash'><img /></div>");
		
		var img = target.children("div").children("img");
		this.img = img;
		img.hide();
		//img.css("opacity", 0);
		img.attr("src", url).load(this._onImageLoaded);
		img.attr("src", url); // なぜか参照しないとロードされない (IE 7)
		
		if (link != null && link != "") {
			// カーソルを指アイコンにする
			img.css("cursor", "pointer");
			
			// マウスクリック時のイベントを付ける
			img.click(function () {
				//console.log("wt; " + wt);
				if (wt == null || wt == "") {
					that.splashClicked = true;
					location.href = link;
				} else {
					window.open(link, wt);
				}
			});
		}
	};
	
	/**
	 * 画像のロードが完了した時.
	 * @param {Object} e イベントオブジェクト.
	 */
	this._onImageLoaded = function (e) {
		that.img.fadeIn("slow", that._onFadeInComplete);
		//console.log("loaded: " +  ", " + img);
	};
	
	/**
	 * 画像のフェードインが完了した時.
	 * @param {Object} e イベントオブジェクト.
	 */
	this._onFadeInComplete = function (e) {
		// 3 秒待ってからフェードアウト
		setTimeout(function () {
			if (that.splashClicked == true) {
				return;
			}
			that.img.fadeOut("slow", that.callback);
		}, SPLASH_WAIT);
	};
};
})(jQuery);

(function ($) {
/**
 * アイテム用のイベントハンドラ.
 */
$.ItemEventHandler = function () {};

/** アイテム上でロールオーバーした時. */
$.ItemEventHandler.onRollOver = function () {
	var overFlag = "overflag";
	var img = $.data(this, "img");
	var desc = $.data(this, "desc");
	
	if (img == null) {
		img = $("img", this);
		$.data(this, "img", img);
	}
	
	if (desc == null) {
		desc = $(".desc", this);
		$.data(this, "desc", desc);
	}
	
	if (/*img.attr("src") == undefined ||*/ desc.html() == "") {
		return;
	}
	
	// マウスオーバーした回数だけ出てきてしまう問題の解消用
	if ($.data(this, overFlag) == null) {
		$.data(this, overFlag, false);
	}
	
	if ($.data(this, overFlag) == true) {
		return;
	}
	$.data(this, overFlag, true);
	
	var desctext = desc.children(".desctext");
	
	// 説明テキストを表示する
	//desc.slideDown("fast");
	desctext.hide();
	desc.fadeIn("fast", function () {
		//console.log("desc: " + desctext);
		desc.css("filter", "alpha(opacity=60)");
		desctext.fadeIn("fast");
	});
	//$(".fg1,.fg2,.fg3", this).fixPng().animate({opacity:0}, "fast");
};

/** アイテム上からロールアウトした時. */
$.ItemEventHandler.onRollOut = function () {
	var overFlag = "overflag";
	var img = $.data(this, "img");
	var desc = $.data(this, "desc");
	
	if (desc == null) {
		return;
	}
	
	// マウスオーバーした回数だけ出てきてしまう問題の解消用
	if ($.data(this, overFlag) == false) {
		return;
	}
	
	// 説明テキストを隠す
	var that = this;
	//desc.slideUp("fast", function () {
	//	$.data(that, overFlag, false);
	//});
	desc.fadeOut(50, function () {
		$.data(that, overFlag, false);
	});
	//$(".fg1,.fg2,.fg3", this).fixPng().animate({opacity:1}, "fast");
};

/** アイテムがクリックされた時. */
$.ItemEventHandler.onClick = function () {
	// console.log("test test ");
	var url = $.data(this, "url");
	if (url != undefined && url != "") {
		$(".desc", this).hide();
		location.href = url;
	}
};
})(jQuery);

(function ($) {
/**
 * アイキャッチ.
 * @param {String} mode "top" または "shopTop"
 * @param {String} id アイキャッチをロードする div タグの ID.
 * @param {Object} json JSON オブジェクト.
 * @param {Number} loopTime 端に到達するまでの時間 (ミリ秒).
 */
$.Eyecatch = function (mode, id, json, loopTime) {
	var that = this;
	this.target = $("#" + id);
	
	// ジャック画像がクリックされたら true.
	this.splashClicked = false;
	
	// 遅延読み込み用
	this.lazyLoadPosition = 0;
	this.imageList = new $.ImageList;
	
	// アニメーション停止フラグ
	this.stopFlag = false;
	
	// DOM 上のレイアウトの位置を保存しておく配列
	this.layoutList = [];
	
	/** アイキャッチの読み込みを開始する. */
	this.start = function () {
		var preloadCount = 14;
		if (mode == "shopTop") {
			preloadCount = 12;
		}
		this._preloadImages(preloadCount);
	};
	
	/** 画像のプリロード処理. */
	this._preloadImages = function (preload_count) {
		this.imageList.parseJson(json, preload_count);
		//console.log("imageList.preloadList: " + this.imageList.lazyList);
		
		var preloader = new $.Preloader;
		preloader.handled = false;
		preloader.callback = this._onPreloadComplete;
		preloader.loadImages(this.imageList.preloadList);
	};
	
	/** 画像のプリロードが完了した時. */
	this._onPreloadComplete = function (preloader, count, loaded) {
		//console.log("################################################");
		// 8 割ほど読み終わったら完了とする
		if (loaded >= count * 0.8 && preloader.handled == false) {
			preloader.handled = true;
			
			// ジャック画像がある場合
			if (json.splash.img != "") {
				that._loadSplash();
				return;
			}
			
			// ジャック画像がない場合
			that._loadLayout();
		}
	};
	
	/**
	 * ジャック画像の読み込み.
	 */
	this._loadSplash = function () {
		// アイキャッチ全体を空にする
		this.target.empty();
		
		// ジャック画像読み込み処理
		var splash = new $.Splash;
		splash.callback = function () {
			that._loadLayout();
		};
		splash.load(
			this.target,
			json.splash.img,
			json.splash.url,
			json.splash.target
		);
	};
	
	/**
	 * レイアウトをロードして画面を構築する.
	 */
	this._loadLayout = function () {
		// アイキャッチ部分のデータのロード
		var childCount = this._parseJson();
		if (childCount > 2) {
			childCount -= 2;
		}
		
		// アイテム用のイベントをセットする
		this._setItemEvents();
		
		// スクロール位置をチェック
		var w = $(window);
		w.scroll(this._onScrollWindow);
		this._onScrollWindow();
		
		// ループ処理を開始する
		this._loopStart(childCount);
	};
	
	/**
	 * 画面がスクロールされた時.
	 */
	this._onScrollWindow = function () {
		var w = $(window);
		var top = that.target.offset().top;
		var height = that.target.height();
		//console.log("target.y " + top + ", " + height);
		var scrollY = w.scrollTop();
		if (scrollY > top + height) {
			that.stopFlag = true;
		} else {
			that.stopFlag = false;
		}
	};
	
	/**
	 * アイテム用のイベントをセットする.
	 */
	this._setItemEvents = function () {
		// アイテムにマウスオーバーした時, カーソルを指アイコンにする
		$(".eyecatch .i1, .eyecatch .i2, .eyecatch .i3").css(
			"cursor", "pointer"
		);
		
		// マウスオーバー時のイベントを付ける
		$(".eyecatch .i1, .eyecatch .i2, .eyecatch .i3").hover(
			$.ItemEventHandler.onRollOver,
			$.ItemEventHandler.onRollOut
		);
		// マウスクリック時のイベントを付ける
		$(".eyecatch .i1, .eyecatch .i2, .eyecatch .i3").click(
			$.ItemEventHandler.onClick
		);
		// 説明テキストを非表示にする
		$(".eyecatch .desc").hide();
	};
	
	/**
	 * JSON の中の, レイアウト部分をパースする.
	 * JSON データの内容から,
	 *  - レイアウト
	 *  - 画像
	 *  - リンク先
	 *  - 説明テキスト
	 * をロードする.
	 * @return 子要素の数.
	 */
	this._parseJson = function () {
		//console.log("parseJson");
		var target = this.target;
		target.empty(); // アイキャッチ全体を空にする
		target.hide();
		
		var layouts = json.layouts;
		var length = json.layouts.length;
		
		// 左の 2 個分の要素を, 右端にコピーする
		// 一番右までスクロールした時に, 空白が見えないようにするため
		if (length > 1) {
			layouts[length] = layouts[0];
			length++;
			layouts[length] = layouts[1];
			length++;
		}
		
		//console.log("length: " + length);
		
		// li タグ 1 つ分の要素をロードする
		for (var i = 0; i < length; i++) {
			//console.log("json.layouts[i]: " + json.layouts[i]);
			this._parseLayout(layouts[i]);
			//console.log("layouts[i].layout: " + layouts[i].layout);
		}
		target.wrapInner("<ul class='bg1'></ul>");
		//console.log(target);
		
		//var fg = $("#eyecatch ul").clone(true);
		//fg.removeClass("bg1");
		//fg.addClass("fg1");
		
		//target.append("<div class='foreground'></div>");
		//target.append("<div class='leftline'></div>");
		//target.append("<div class='rightline'></div>");
		
		//target.append(fg);
		//target.remove(bg);
		
		// ラッパーオブジェクトの名前
		var wrapper_id = "__wrap_" + id;
		
		// 要素をラッパーオブジェクトで囲む
		target.children("ul.bg1").wrapAll("<div id='" + wrapper_id + "'></div>");
		//target.children("ul.fg1").wrapAll("<div id='" + wrapper_id + "_fg'></div>");
		//$("#" + wrapper_id + " .desc").remove();
		//$("#" + wrapper_id + "_fg img").remove();
		
		//var w2 = $(".fg .eyecatch");
		//w2.css("border: 1px solid red");
		
		return length;
	};
	
	/**
	 * アイキャッチ部分のレイアウトを設定する
	 * @param {Object} layouts
	 */
	this._parseLayout = function (layouts) {
		var target = this.target;
		var layoutNum = layouts.layout;
		
		// div 要素をコピーして, アイキャッチの中に配置する
		var layout = $(".ec_layout" + layoutNum).clone().removeClass("ec_layout" + layoutNum);
		//console.log("layoutNum: " + layoutNum);
		if (layoutNum == 0 || layoutNum == 1 || layoutNum == 2) {
			target.append(layout.wrap('<li class="w2"></li>').parent());
		} else {
			target.append(layout.wrap('<li class="w1"></li>').parent());
		}
		//target.append(layout);
		
		// レイアウトに合わせて, 画像と説明テキストをロードする
		var items = [];
		var length = layouts.images.length;
		for (var i = 0; i < length; i++) {
			var image = layouts.images[i];
			var itemClass = "." + $.Eyecatch.itemClasses[layoutNum][i];
			
			// 存在しない場所の場合, 画像をロードしない
			if (itemClass == null || itemClass == ".") {
				continue;
			}
			
			// 画像と説明テキストを設定する
			var item = layout.children(itemClass);
			var img = item.children("img");
			items.push({"img": img, "src": image.img});
			//item.children("img").attr("src", image.img).load();
			item.children(".desc").children(".desctext").html(image.desc);
			
			// UI 要素自体に, クリック時の遷移先 URL を保存しておく
			$.data(item.get(0), "url", image.url);
		}
		this.layoutList.push({
			"layoutNum": layoutNum,
			"layout": layout,
			"items": items
		});
		
		// ec_layout クラスを取り外す
		//target
		//	.children(".eyecatch")
		//	.removeClass("ec_layout" + layoutNum);
	};
	
	/**
	 * ループを開始する.
	 */
	this._loopStart = function () {
		var target = this.target;
		
		// ラッパーオブジェクトの名前
		var wrapper_id = "__wrap_" + id;
		
		// 要素をラッパーオブジェクトで囲む
		//target.children("ul.bg").wrapAll("<div id='" + wrapper_id + "'></div>");
		var wrapper = $("#" + wrapper_id);
		
		// 左右のライン
		//var target = this.target;
		
		/*target.append(
			"<div id='__fg'><ul><li>" +
			"<div class='eyecatch'>" +
			"<div class='i1 p00 border1'>" +
				"<img class='img1' src=''>" +
				"<div class='fg1' style='opacity: 0;'></div>" +
				"<div class='desc d1' style=''>L.D.S.<br>ショルダーバッグ<br>￥6,900</div></div>" +
			"<div class='i1 p01 border1'></div>" +
			"<div class='i1 p02 border1'></div>" +
			"<div class='i1 p03 border1'></div>" +
			"<div class='i1 p10 border1'></div>" +
			"<div class='i2 p11 border1'></div>" +
			"<div class='i1 p13 border1'></div>" +
			"</div>" +
			"</li></ul></div>"
		);*/
		//this._setItemEvents();
		
		// 前景
		//$(".fg1,.fg2,.fg3").fixPng().css({opacity:0});
		
		// 
		/*$(".foreground").hover(
			function (e) {
				console.log("foreground mouseover: " + e);
				console.log(e);
			}, function (e) {
				console.log("foreground mouseout: " + e);
			}
		);*/

		// li タグ全てを合わせた幅を取得
		var containerWidth = wrapper.children("ul").children("li").width();
		var layoutCount = wrapper.children("ul").children("li").length;

		var wrapperWidth = containerWidth * layoutCount;

		wrapper.css({
			top: "0",
			left: "0",
			width: wrapperWidth,
			height: target.height(),
			overflow: "hidden",
			position: "absolute"
		});
		
		/*var wrapper2 = $("#" + wrapper_id + "_fg");
		wrapper2.css({
			top: "0",
			left: "0",
			width: wrapperWidth,
			height: target.height(),
			overflow: "hidden",
			position: "absolute"
		});*/

		// ラッパー要素の幅を li タグ全てを合わせた幅にする
		$("#" + wrapper_id + " ul").css("width", wrapperWidth);
		
		// 最初に見えている範囲の画像をロード
		var columnCount = 7;
		if (mode == "shopTop") {
			columnCount = 6;
		}
		for (var i = 0; i < columnCount; i++) {
			var layoutIndex = (i / 4) | 0;
			var columnIndex = i - layoutIndex * 4;
			that._loadImage(layoutIndex, columnIndex);
		}
		
		// フェードインしてアニメーション開始
		target.fadeIn(
			"slow",
			function () {
				that._startAnimation(wrapper, containerWidth);
			}
		);
		
		// 遅延ロード
		/*
		var lazyLoadTimerId = setInterval(function () {
			var img = document.createElement("img");
			//console.log($(img));
			var lazyList = that.imageList.lazyList;
			
			console.log("lazyList.length: " + lazyList.length);
			$(img).attr("src", lazyList[that.lazyLoadPosition]).load(function () {
				//console.log("preload: " + _lazyLoadPosition);
			});
			// なぜか参照しないとロードされない (IE 7)
			$(img).attr("src", lazyList[that.lazyLoadPosition]);
			that.lazyLoadPosition++;
			
			if (lazyList.length <= that.lazyLoadPosition) {
				clearInterval(lazyLoadTimerId);
			}
		}, 500);
		*/
	};
	
	/**
	 * アイテムごとの画像をロード.
	 * @param {Number} layoutIndex レイアウト番号 (0-5)
	 * @param {Number} columnIndex 列番号 (0-3)
	 */
	this._loadImage = function (layoutIndex, columnIndex) {
		//console.log("_loadImage: ");
		//console.log("layoutIndex: " + layoutIndex);
		//console.log("columnIndex: " + columnIndex);
		var layout = that.layoutList[layoutIndex];
		if (layout == null) {
			return;
		}
		if (columnIndex > 3) {
			return;
		}
		
		var layoutNum = layout.layoutNum;
		var position = $.Eyecatch.imagePosition[layoutNum];
		var column = position[columnIndex];
		
		// 1 列分ロード
		for (var i = 0; i < 2; i++) {
			if (column[i] < 0) {
				continue;
			}
			var itemRef = layout.items[column[i]];
			var img = itemRef.img;
			var src = itemRef.src;
			if (img.attr("src") != "" && img.attr("src") != null) {
				continue;
			}
			img.attr("src", src).load();
		}
		
		// 右端の分をロード
		//console.log("mode: " + mode);
		if (mode == "top") {
			if (layoutIndex <= 1) {
				this._loadImage(layoutIndex + 4, columnIndex);
			}
		} else if (mode == "shopTop") {
			if (layoutIndex <= 1) {
				this._loadImage(layoutIndex + 2, columnIndex);
			}
		}
		
		//console.log("this.layoutList: " + that.layoutList);
	};
	
	/**
	 * アニメーションを開始する.
	 * @param {Object} wrapper 画像リストのコンテナ
	 * @param {Number} containerWidth コンテナの横幅
	 */
	this._startAnimation = function (wrapper, containerWidth) {
		var target = this.target;
		
		var maxCount = 16;
		var loadStartCount = 7;
		
		//console.log("mode " + mode);
		if (mode == "shopTop") {
			maxCount = 8;
			loadStartCount = 6;
		}
		
		var count = 0;
		var distance = containerWidth / 4;
		var looped = false;
		var itemMoveTime = loopTime / maxCount;
		
		// 初期位置
		wrapper.css("left", 0);
		//wrapper2.css("left", 0);
		var leftPosition = 0;
		
		// アニメーション開始
		function moveItem() {
			//console.log("count " + count);
			// 画像のロード (画面に出てくる前にロードする)
			if (looped == false) {
				var i = count + loadStartCount;
				var layoutIndex = (i / 4) | 0;
				var columnIndex = i - layoutIndex * 4;
				that._loadImage(layoutIndex, columnIndex);
			}
			
			// 停止フラグが立っていたら, アニメーションを停止する
			if (that.stopFlag == true) {
				// 500 ミリ秒ごとに停止フラグをチェックする
				var timerId = setInterval(function () {
					//console.log("stop");
					if (that.stopFlag == false) {
						clearInterval(timerId);
						moveItem();
					}
				}, 500);
				return;
			}
			
			count++;
			
			// 画面を 1 周した時
			if (count > maxCount) {
				count = 1;
				looped = true;
				wrapper.css("left", 0);
				//wrapper2.stop().css("left", 0);
				leftPosition = 0;
				//console.log("wrapper2: " + wrapper2.css("left"));
			}
			
			var index = Math.floor((count - 1) / 4);
			var li = $("ul li", wrapper);
			//console.log("index: ", index);
			//console.dir($(li[index]).width());
			
			// アイテム 1 つ分移動させる
			// 移動が完了したら moveItem() を再度呼び出す
			leftPosition -= $(li[index]).width() / 4;
			wrapper.animate(
				{left: leftPosition + "px"},
				itemMoveTime,
				"linear",
				moveItem
			);
			//wrapper2.animate(
			//	{left: leftPosition + "px"},
			//	itemMoveTime,
			//	"linear"
			//);
		}
		moveItem();
	};
};

// レイアウトごとの要素の位置を取得するための配列
$.Eyecatch.itemClasses = [
	[ "p00", "p01", "p02", "p03", "p10", "p11",    "",    "" ], // layout0
	[ "p00", "p01", "p03", "p10", "p11", "p12",    "",    "" ], // layout1
	[ "p00", "p01", "p02", "p03", "p10", "p11", "p12",    "" ], // layout2
	[ "p00", "p01", "p02", "p03", "p10", "p11", "p13",    "" ], // layout3
	[ "p00", "p01", "p03", "p10", "p11", "p12", "p13",    "" ], // layout4
	[ "p00", "p01", "p02", "p03", "p10", "p11", "p12", "p13" ]  // layout5
];

// 画像ロード時の, 1 列分を表すデータ
$.Eyecatch.imagePosition = [
	[[0, 4], [1, 5], [2, -1], [3, -1]], // layout0
	[[0, 3], [1, 4], [-1, 5], [2, -1]], // layout1
	[[0, 4], [1, 5],  [2, 6], [3, -1]], // layout2
	[[0, 4], [1, 5], [2, -1],  [3, 6]], // layout3
	[[0, 3], [1, 4], [-1, 5],  [2, 6]], // layout4
	[[0, 4], [1, 5],  [2, 6],  [3, 7]]  // layout5
];

})(jQuery);

