/* *****************************************************************************
 * サブメニューのポップアップを実装する
 * ************************************************************************** */

$(document).ready(function()
{
	initNavigationPopup();
});

/**
 * すべてのサブメニューの配列です.
 */
var subMenus = [];

/**
 * 表示済みサブメニューの配列です.
 */
var shownSubMenuCache = [];

/**
 * 最も高さのあるサブメニューの高さです.
 */
var maxSubMenuHeight = 0;

var MOVE_INTERVAL = 30;

var NAVI_SUBS =
[
	[
		{ src : "img/navi_01_01_o.gif", alt : "集めて楽しい！",             link : "/howto/collect/" },
		{ src : "img/navi_01_02_o.gif", alt : "バトルして楽しい！",         link : "/howto/battle/" },
		{ src : "img/navi_01_03_o.gif", alt : "バトルに強くなろう！",       link : "/howto/strong/deck/" },
		{ src : "img/navi_01_04_o.gif", alt : "どんな商品があるの？",       link : "/howto/products/recom_goods.html" },
		{ src : "img/navi_01_05_o.gif", alt : "イベントに行こう！",         link : "/howto/event/" },
		{ src : "img/navi_01_06_o.gif", alt : "webでさらに楽しもう！",      link : "/howto/web/" }
	],
	[
	 	{ src : "img/navi_02_00_o.gif", alt : "くわしくけんさく",    		link : "/card/index.php?mode=stroke" },
		{ src : "img/navi_02_01_o.gif", alt : "週間カードランキング！",     link : "/card/ranking.php" },
		{ src : "img/navi_02_02_o.gif", alt : "カードリスト",               link : "/card/list.html" }
	],
	[
		{ src : "img/navi_03_01_o.gif", alt : "シリーズしょうひん",         link : "/products/series.html" },
		{ src : "img/navi_03_02_o.gif", alt : "ていばんしょうひん",         link : "/products/regular/" },
		{ src : "img/navi_03_03_o.gif", alt : "テレビCM",                   link : "/products/cm/" }
	],
	[
		{ src : "img/navi_04_01_o.gif", alt : "イベントへ行こう！",         link : "/event/about.html" },
		{ src : "img/navi_04_02_o.gif", alt : "イベントスケジュール",       link : "/event/schedule/" },
		{ src : "img/navi_04_03_o.gif", alt : "イベントレポート",           link : "/event/report/" }
	],
	[
		{ src : "img/navi_05_01_o.gif", alt : "ミニゲーム",                 link : "/enjoy/game/" }
	]
];

/**
 * sprintf エミュレータです。フォーマットは %s のみをサポートしています.
 * @param {String} format フォーマット文字列
 * @param {Array<String>} args 置き換える文字列
 */
function sprintf_s(/* format, args */)
{
	var _format = arguments[0];
	var args = [];
	
	for (var i = 1; i < arguments.length; i++)
		args.push(arguments[i]);
	
	return _format.replace(/%s/g, function(m){ return args.length ? args.shift() : m });
}

/**
 * 表示済みのサブメニューを非表示にします.
 */
function hideShownSubMenu()
{
	var o;
	while (shownSubMenuCache.length)
	{
		o = shownSubMenuCache.shift();
		o.hide();
	}
}

/**
 * サブメニューをポップアップ表示させます.
 * @param {jQuery} subNaviObject 表示させるサブメニューオブジェクト
 */
function showSubNavi(subNaviObject)
{
	var naviButton = subNaviObject.parentNavi;
	var naviButtonPos = naviButton.offset();
	var naviButtonPosBottom = naviButtonPos.top + naviButton.outerHeight();
	var windowHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight;
	var windowScrollTop = (($.support || $.browser).safari ? document.body : document.documentElement).scrollTop;
	
	// 既にポップアップしているサブメニューを隠す
	hideShownSubMenu();
	
	// このサブメニューを表示する
	subNaviObject.show();
	
	// 上の方へポップアップする
	if (windowScrollTop + windowHeight < naviButtonPosBottom + maxSubMenuHeight)
		subNaviObject.css('top', naviButtonPos.top - subNaviObject.outerHeight() + 1 + "px");
	// 下の方へポップアップする
	else
		subNaviObject.css('top', naviButtonPosBottom - 1 + "px");
	
	// ポップアップ済みとして登録する
	shownSubMenuCache.push(subNaviObject);
}

/**
 * サブメニューのマウスオーバー ハンドラです。イベントのバブルアップのキャンセルのみを行ないます.
 */
function subnavi_mouseover()
{
	if (window.event)
		window.event.cancelBubble = true;
	else
		arguments[0].stopPropagation();
}

/**
 * メニューボタンのマウスオーバー ハンドラです。サブメニューをポップアップ表示します.
 */
function navi_button_mouseover()
{
	if (window.event)
		window.event.cancelBubble = true;
	else
		arguments[0].stopPropagation();
	
	showSubNavi(this.subMenuObject);
}

/**
 * document.body のマウスオーバー ハンドラです。サブメニューを非表示にするために使用します.
 */
function body_mouseover()
{
	hideShownSubMenu();
}

/**
 * ウィンドウのリサイズ ハンドラです。サブメニューの位置調整に使用します.
 */
function window_reize()
{
	for (var i in subMenus)
		subMenus[i].css('left', subMenus[i].parentNavi.offset().left - 1 + "px");
}

/**
 * サブメニューを作成し、ポップアップ機構を実装します.
 */
function initNavigationPopup()
{
	var imageCache = [];
	
	// サブメニュー要素を作成する
	$("#navi_primary li").each(function(i, e)
	{
		var subMenuHash = NAVI_SUBS[i];
		var htmlBuffer = '<ul>';
		
		// サブメニューの HTML を書く
		for (var j = 0, n = subMenuHash.length; j < n; j++)
		{
			htmlBuffer += sprintf_s('<li><a href="%s"><img src="%s" alt="%s" /></a></li>',
				subMenuHash[j].link, subMenuHash[j].src, subMenuHash[j].alt);
		}
		htmlBuffer += "</ul>";
		
		// jQuery で詳細なセットアップを行なう
		var subMenuObject = $(htmlBuffer);
		
		subMenuObject.css(
		{
			display : "none",
			position : "absolute",
			top : $(e).offset().top + "px",
			zIndex : 1024,
			width : "auto",
			height : "auto"
		});
		
		subMenuObject.find("li").css(
		{
			fontSize : "0",
			lineHeight : "0"
		});
		
		// サブメニュー内の画像をロールオーバーするように
		var subMenuImages = subMenuObject.find("img");
		subMenuImages.set_rollovers();
		
		// メニュー項目の画像への参照を保持する
		// 画像読み込み完了を検出するために使う
		imageCache = imageCache.concat(subMenuImages.get());
		subMenuImages.each(function()
		{
			var img = new Image;
			img.src = this.src.replace("_o.", "_h.");
			imageCache.push(img);
		});
		
		// ページにサブメニューを追加する
		$("#content").append(subMenuObject);
		
		// サブメニュー オブジェクトからナビボタンへの参照を保持する
		subMenuObject.parentNavi = $(e);
		
		// ナビボタンからサブメニュー オブジェクトへの参照を保持する
		e.subMenuObject = subMenuObject;
		
		// グローバル配列に push してオブジェクトへの参照を保持する
		subMenus.push(subMenuObject);
	});
	
	// サブメニュー内の画像の読み込みが完了するまで待機する
	window.setTimeout(function()
	{
		var completedImageCount = 0;
		
		// 読み込みが終了した画像の数を数える
		jQuery.each(imageCache, function()
		{
			if (this.complete)
				completedImageCount++;
		});
		
		// すべての画像の読み込みが終了したら
		if (completedImageCount == imageCache.length)
		{
			$("#navi_primary li").each(function(i, e)
			{
				// 一部のブラウザでは、画像が未キャッシュの状態だとメニューの高さを取得できないので
				// 画像の高さからメニューの高さを決定してしまう
				if (subMenus[i].height() == 0)
				{
					var h = 0;
					subMenus[i].find("img").each(function(){ h += this.height });
					subMenus[i].height(h);
				}
				
				// メニューの幅を画像の幅に合わせる
				subMenus[i].toggle();
				subMenus[i].find("li").each(function()
				{
					$(this).css("width", $(this).find("img").get(0).width + "px");
				});
				subMenus[i].toggle();
				
				// もっとも高いサブメニューの高さを取得する
				if (maxSubMenuHeight < subMenus[i].outerHeight())
					maxSubMenuHeight = subMenus[i].outerHeight();
				
				// ポップアップのためのイベントハンドラを割り当てる
				subMenus[i].bind("mouseover", subnavi_mouseover);
				$(e).bind("mouseover", navi_button_mouseover);
				$("body").bind("mouseover", body_mouseover);
				
				// ウィンドウリサイズ時にサブメニューの位置を調整する関数を割り当てる
				$(window).bind("resize", window_reize);
				$(window).trigger("resize");
			});
		}
		else
			window.setTimeout(arguments.callee, 100);
		
	}, 100);
}