/*
 * jquery.ssutil.js
 * (C) 2010 SEKI, Sintaro
 *
 * Version  : 1.2
 * Author   : SEKI, Shintaro
 * Mail     : s2pch.luck@gmail.com
 * Created  : 2009-10-21
 * Modified : 2010-10-28
 * Licenced : MIT or GPLv3
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.opensource.org/licenses/gpl-3.0.html
 *
 * [変更履歴]
 * 2009-10-21 (v0.0)
 * ちくちく書き始める。
 *
 * 2010-10-14 (v1.0)
 * v1.0リリース。
 *
 * 2010-10-22 (v1.1)
 * swapBgImgのバグを修正。
 * 
 * 2010-10-28 (v1.2)
 * hoverToggleのFirefox以外で発生する不可解なバグ(*1)対処という意味を含め仕様の変更
 * (*1) Firefox以外ではロード時にマウスを高速ホバーインアウトすると、表示非表示が逆になってしまうことがある。
 */
/**
 * @name jquery.ssutil.js
 * @fileoverview 過去必要なときに作ったjQueryプラグインをまとめ、さらに機能を付け加えたものです。10行を1行にすることを目標としています。
 * @version 1.2
 * @copyright (C) 2009-2010 SEKI, Shintaro
 * @author SEKI, Shintaro <s2pch.luck@gmail.com>
 * @license MIT or GPLv3
 */
/**
 * @class
 * @name jQuery
 * @desc 詳細は<a href="http://jquery.com">jQuery</a>のウェブサイトを見てください。
 */ 
/**
 * @class
 * @name fn
 * @memberOf jQuery
 * @desc 詳細は<a href="http://jquery.com">jQuery</a>のウェブサイトを見てください。
 */
 
(function($) {

/** @exports sslib as jQuery.fn */
var sslib = $.fn;

/**
 * @inner
 * @private
 * undefined, null値以外が入っていたらtrue
 * こういうのもグローバルに公開するのもありなのだろうか
 * @since 1.1.0
 */
var isval = function(obj) {
	return (obj || (obj === false));
}

/**
 * @inner
 * @private
 * isval()の複数版。引数に値がないものがあればfalse。
 * @since 1.0
 */
var isvals = function() {
	if (arguments.length == 0) return false;
	for (var $v in arguments) {
		if (!isval($v)) return false;
	}
	return true;
}

/**
 * @inner
 * @private
 * デフォルト値に対して、オプションがあれば、デフォルト値をそれに変える
 * @since 1.0
 * @param def デフォルト値。opに従い書き換わる。
 * @param op オプション値。defに無い要素は無視される。
 */
var setOption = function (def, op) {
	if (!op) return;
	for (var i in def) {
		if (isval(op[i])) def[i] = op[i];
	}
}

/**
 * マウスホバー時にファイル名に"_o"を付けた画像と入れ替える。
 * @since 1.0
 * @example
$(document).ready(function() {
	$(".swapimg").swapImage();
	//$(".swapimg").swapImage({suffix: "_s", preload: false});
});
 * @param option オプション。指定しない場合デフォルト値が使われる。
 * @param [option.suffix="_o"] x.pngならx_o.pngと入れ替える。
 * @param [option.preload=true] 入れ替える画像をあらかじめロードしておくかどうか。
 * @param [option.swapped_file=null] 画像へのパスを指定すると、この画像と入れ替える。suffixは無視される。
 */
sslib.swapImage = function(option) {
	var op = {
		suffix: "_o",
		preload: true,
		swapped_file: null
	}
	setOption(op, option);
	this.each(function() {
		var t = this.src.match(/(.*)\.(\w+)$/);
		// get file name
		var src = op.swapped_file || t[1] + op["suffix"] + "." + t[2];
		// preload
		if (op.preload) (new Image()).src = src;
		// register event
		$(this).hover(
			function() { this.src = src; },
			function() { this.src = t[0]; }
		);
	});
}

/**
 * マウスホバー時にスタイルを入れ替える。
 * @since 1.0
 * @param style_name スタイル名
 * @param value 値
 */
sslib.swapStyle = function(style_name, value) {
	this.each(function() {
		var obj = $(this);
		var org = obj.css(style_name);
		obj.hover(
			function() { obj.css(style_name, value); },
			function() { obj.css(style_name, org); }
		);
	});
}

/**
 * swapImageの背景画像版。
 * @since 1.0
 * @param option オプション。指定しない場合デフォルト値が使われる。
 * @param [option.suffix="_o"] x.pngならx_o.pngと入れ替える。
 * @param [option.preload=true] 入れ替える画像をあらかじめロードしておくかどうか。
 * @param [option.swapped_file=null] 画像へのパスを指定すると、この画像と入れ替える。suffixは無視される。
 */
sslib.swapBgImage = function(option) {
	var op = {
		suffix: "_o",
		preload: true,
		swapped_file: null
	}
	setOption(op, option);
	this.each(function() {
		obj = $(this);
		var src, url;
		if (!isval(op.swapped_file)) {
			var t = obj.css("background-image").match(/(\w*\(\W?)(.*)\.(\w+)(\W?\))$/);
			// get file name
			src = t[2] + op["suffix"] + "." + t[3];
			url = t[1] + src + t[4];
		} else {
			src = op.swapped_file;
			url = "url(" + src + ")";
		}
		// preload
		if (op.preload) (new Image()).src = src;
		// register event
		$(this).swapStyle("background-image", url);
	});
}

/**
 * 透過によるボタンホバーアニメーションを施す。<br />
 * 一部オプションはjQueryのものと同じものなので、<a href="http://api.jquery.com/animate/">jQueryドキュメント</a>の方をみること。
 * @since 1.0
 * @param option オプション。指定しない場合デフォルト値が使われる。
 * @param [option.time=100] 指定の透過度になるまでの時間。
 * @param [option.time_back=100] 透過状態からもどるまでの時間。
 * @param [option.opacity=0.8] 透過度。範囲は[0,1]。
 * @param [option.easing="swing"] 値の変化量。詳しくは<a href="http://api.jquery.com/animate/">jQueryドキュメント</a>を参照。
 * @param [option.easing_back="swing"] easingと同じ。
 */
sslib.opacityButton = function(option) {
	var op = {
		time: 100,
		time_back: null,
		opacity: 0.8,
		easing: "swing",
		easing_back: "swing"
	}
	setOption(op, option);
	this.each(function() {
		var obj = $(this);
		obj.hover(
			function() {
				obj.animate({opacity: op.opacity}, {
					duration: op.time,
					easing: op.easing
				});
			},
			function() {
				obj.animate({opacity: 1.0}, {
					duration: op.time_back || op.time,
					easing: op.easing_back
				});
			}
		);
	});
}

/**
 * マウスホバー時に（デフォルトでは次の要素の）表示・非表示を切り替える。
 * ポップアップメニューを作るときとかに使える。
 * @since 1.0
 * @param option オプション。
 * @param [option.traversal="next"] jQueryの<a href="http://api.jquery.com/category/traversing/tree-traversal/">Tree Traversal</a>の関数名を文字列で指定。
 * @param [option.selector=""] option.traversalに与えるセレクタ。。
 * @param [option.showed=false] 初期状態で表示されているかを指定できる。指定した場合はスタイルシートよりこちらが優先される。
 * @param [option.effect="toggle"] toggle, slideToggleなどjQueryのtoggle系関数を指定。あるいは配列で[over, out]で指定(ex. ["show", "slideToggle"])。
 * @param [option.speed=0] アニメーションのスピードを指定。形式は<a href="http://api.jquery.com/toggle/">オリジナルのtoggle</a>と同じ。[over, out]で指定も可(ex. [200, 0])。
 * @param [option.easing="linear"] easing形式。[over, out]で指定も可。
 */
sslib.hoverToggle = function(option) {
	var op = {
		traversal: "next",
		selector: "",
		showed: null,
		effect: "toggle",
		speed: 0,
		easing: "linear",
		jquery_obj: null // 対象をセレクタではなくjqueryオブジェクトで指定。未実装
	}
	setOption(op, option);
	this.each(function() {
		var obj = $(this);
		var targets = eval("obj." + op.traversal + "('" + op.selector + "')");
		if (isval(op.showed)) {
			if (op.showed)
				targets.show();
			else
				targets.hide();
		}
		// 強引に配列にする
		if (typeof(op.effect) == "string")
			op.effect = [op.effect, op.effect];
		if (typeof(op.speed) == "number")
			op.speed = [op.speed, op.speed];
		if (typeof(op.easing) == "string")
			op.easing = [op.easing, op.easing];
		var f = new Array(2);
		for (var i = 0; i < 2; ++i)
			f[i] = "targets." + op.effect[i] + "(" + op.speed[i] + ", '" + op.easing[i] + "')";
		obj.hover(
			function() { eval(f[0]); },
			function() { eval(f[1]); }
		);
	});
}


})(jQuery); /* end of script */


