/*
 * Copyright (C) 2008 Daichi Tachihata
 *
 * MIT License
 * http://www.opensource.org/licenses/mit-license.php
 */

//グローバル変数定義
var isMSIE = /*@cc_on!@*/false; 
var myFunc = {};


//ここからjQueryが$で使えるよ。
(function($){

/*--------------------------------------*/
/*# Function拡張 #                      */
/*--------------------------------------*/

//ベンチマーク
//func.bench(st)(args);
Function.prototype.bench = function(st){
	var self = this; // 実行時間を計りたい関数
	st = st || "実行時間は";
	return function(){
		var start = new Date().getTime();
		var res = self.apply(this,arguments);
		var end = new Date().getTime();
		//window.status = st+":"+(end-start); // 結果をステータスバーに表示
		alert(st+":"+(end-start)); // 結果をアラート
		return res;
	}
}

//非同期化
//func.asynchronize()(function(result){/*...*/})
Function.prototype.asynchronize = function() {
	var f = this;
	return function() {
		var resultcb = function() {};
		var failcb = function(e) { throw e };
		if (typeof arguments[arguments.length - 1] == 'function') {
			resultcb = Array.prototype.pop.apply(arguments);
			if (typeof arguments[arguments.length - 1] == 'function') {
				failcb = Array.prototype.pop.apply(arguments);
			}
		}
		try {
			var result = f.apply(this, arguments);
			setTimeout(function() { resultcb(result) }, 0);
		}
		catch (e) {
			setTimeout(function() { failcb(e) }, 0);
		}
	};
};




/*--------------------------------------*/
/*# いろいろ関数とか #                  */
/*--------------------------------------*/

//改行付き出力
/*
function print(arg){
	document.writeln(arg + "\n");
}
*/

myFunc = $.extend(myFunc,{
	
	//クラス関係
	Class: {
		
		//クラス定義
		define : function(data){
		/*
		var newclass = ns.define({
			name: クラス名,
			extend: 親クラス,
			construct: function(arg){
				this.p = arg;
			},
			methods: {
				m1 : function(){},
				m2 : function(){}
			},
			statics: {
				s1 : function(){},
				s2 : function(){}
			},
			borrows: メソッドを借用したいクラスかクラスの配列,
			provides: 同じメソッドがあるか検証したいクラスかクラスの配列
		});
		*/
			var classname = data.name;
			var superclass = data.extend || Object;
			var constructor = data.construct || function(){};
			var methods = data.methods || {};
			var statics = data.statics || {};
			var borrows = !data.borrows ?
			              	[] :
			              	data.borrows instanceof Array ?
			              		data.borrows :
			              		[data.borrows];
			var provides = !data.provides ?
			              	[] :
			              	data.provides instanceof Array ?
			              		data.provides :
			              		[data.provides];
			
			
			var _TYPE_FUNCTION = "function",
			    _P_NAME_CONSTRUCTOR = "constructor",
			    _P_NAME_SUPERCLASS = "superclass";
			
			var proto = new superclass();
			
			for(var p in proto){
				if(proto.hasOwnProperty(p)) delete proto[p];
			}
			
			for(var i = 0, l = borrows.length; i < l; i++){
				var c = borrows[i];
				for(var p in c.prototype){
					if(typeof c.prototype[p] != _TYPE_FUNCTION) continue;
					proto[p] = c.prototype[p];
				}
			}
			
			for(var p in methods) proto[p] = methods[p];
			
			proto.constructor = constructor;
			proto.superclass = superclass;
			if(classname) proto.classname = classname;
			
			for(var i = 0, l = provides.length; i < l; i++){
				var c = provides[i];
				for(var p in c.prototype){
					if(typeof c.prototype[p] != _TYPE_FUNCTION) continue;
					if(p == _P_NAME_CONSTRUCTOR || p == _P_NAME_CONSTRUCTOR) continue;
					if(p in proto &&
					   typeof proto[p] == _TYPE_FUNCTION &&
					   proto[p].length == c.prototype[p].length) continue;
					
					throw new Error("Class"+ classname +"does not provide method "+ c.classname +"."+ p);
				}
			}
			
			constructor.prototype = proto;
			
			for(var p in statics) constructor[p] = statics[p];
			
			return constructor;
		}
	}
	
});

myFunc = $.extend(myFunc,{
	
	//URI関連
	URI : myFunc.Class.define({
		name: "myFunc.URI",
		construct: function(url){
			this.originalPath = url;
			this.absolutePath = this.getAbsolutePath(url);
		},
		methods: {
			//絶対パスを取得
			getAbsolutePath : function(path){
				var img = new Image();
				img.src = path;
				path = img.src;
				img.src = '#';
				return path;
			},
			
			//同じ文書にリンクしているかどうか
			isSelfLink : (this.absolutePath == location.href)
		}
	}),
	
	
	//PreLoad
	PreLoad : {
		preLoadImg: [],
		load: function(path){
			var pImg = this.preLoadImg;
			var l = pImg.length;
			pImg[l] = new Image;
			pImg[l].src = path;
		}
	},
	
	
	//日付関連
	Date : myFunc.Class.define({
		name: "myFunc.Date",
		extend: Date,
		construct: function(d){
			var d = d ? new Date(d) : new Date();
			
			var yy = d.getFullYear() || d.getYear();
			var mm = d.getMonth() + 1;
			var dd = d.getDate();
			this.yy = yy > 1900 ? yy : yy + 1900;
			this.mm = mm < 10 ? mm = "0" + mm : mm;
			this.dd = dd <10 ? dd = "0" + dd : dd;
			
			var h = d.getHours();
			var m = d.getMinutes();
			var s = d.getSeconds();
			this.h = h < 10 ? h = "0" + h : h;
			this.m = m <10 ? m = "0" + m : m;
			this.s = s < 10 ? s = "0" + s : s;
		},
		methods: {
			date : function(sep){
				sep = sep || "";
				return this.yy + sep + this.mm + sep + this.dd;
			},
			
			time : function(sep){
				sep = sep || "";
				return this.h + sep + this.m + sep + this.s;
			},
			
			now : function(sep){
				sep = sep || "";
				return this.date(sep) + sep + this.time(sep);
			}
		}
	}),
	
	
	//cookie関連
	Cookie : {
		set: function(name, val, options){
			/*
				options = {
					limit: 期限,
					path: 有効なパス
				}
			*/
			if(!options) options= {};
			var limit = options.limit;
			var path = options.path;
			
			var ckStr = encodeURIComponent(name) + "=" + encodeURIComponent(val);
			
			if (typeof limit != 'undefined'){
				var limit_d = new Date;
				limit_d.setTime(limit_d.getTime() + 1000*60*60*24 * (limit_d - 0));
				ckStr += '; expires=' + limit_d.toGMTString();
			}
			
			if (typeof path == 'undefined') path = "/";
			ckStr += '; path=' + path + ';';
			
			document.cookie = ckStr;
			return [name, val];
		},
		
		get: function(name){
			var match = ('; ' + document.cookie + ';').match('; ' + name + '=(.*?);');
			return match ? decodeURIComponent(match[1]) : '';
		}
	},
	
	
	//ポップアップ
	popup : function(file, name, options, optionStr){
		defaultOptions = {
			location : "no",
			menubar : "no",
			status : "no",
			toolbar : "no"
		};
		options = $.extend(defaultOptions, options);
		
		var optStr = "", _EQ = "=", _COMMA = ",", _SCROLLBARS = "scrollbars", _YES = "yes";
		if("scrollbars" in options && 
		   (options["scrollbars"] == "yes" ||
		    options["scrollbars"] == "1")){
			if("width" in options){
				var width = options["width"] - 0;
				options["width"] = width + 15;
			}
			if("height" in options){
				var height = options["height"] - 0;
				options["width"] = height + 20;
			}
		}
		for(var i in options){
			optStr += i + _EQ + options[i] + _COMMA;
		}
		optStr = optStr.substring(0, optStr.length - 1);
		
		window.open(file, name, optStr);
		return void 0;
	}
	
	
});


// jqueryオブジェクトの中身をダンプする関数
function jquery_dump($obj) {
	var dumphtml = [];
	if(jQuery.browser.msie) {
		for(var i = 0, l = $obj.length; i < l; i++) {
			dumphtml.push('[' + i + '] ');
			dumphtml.push($obj[i].outerHTML.replace(/^[\r\n\t]+/, ''));
			dumphtml.push("\n");
		}
	} else {
		for(var i = 0, l = $obj.length; i < l; i++) {
			dumphtml.push('[' + i + '] '
				+ '<' + $obj[i].nodeName.toLowerCase());
			for(var j = 0, l2 = $obj[i].attributes.length; j < l2; j++) {
				dumphtml.push(' ' + $obj[i].attributes[j].nodeName + '="' 
					+ $obj[i].attributes[j].nodeValue + '"');
			}
			dumphtml.push('>' + $obj[i].innerHTML);
			dumphtml.push('<\/' + $obj[i].nodeName.toLowerCase() + '>');
			dumphtml.push("\n");
		}
	}
	alert(dumphtml.join(''));
}
var jQuery_dump = jquery_dump;





/*--------------------------------------*/
/*# jQueryプラグイン #                  */
/*--------------------------------------*/

/*** imgover ***
■解説
[対象Object]内にあるリンク画像(<a>タグに囲まれている<img>)の
マウスオーバー時に画像が「画像名_[引数:postfix].拡張子」に切り替わる。（foo.gif→foo_o.gif）
もちろんマウスアウトで元の画像に戻る。
リンクでは無い画像や、class="[引数:exclude]"を付与された画像ではマウスオーバー時の切替しない。

[引数:isSelf]をtrueにしたら、現在ページとリンク先が同じ場合に、
・画像を「画像名_[引数:aPostfix].拡張子」にする。
・classに[引数:exclude]を付与。（[引数:isSelfOver]がfalseの場合のみ）

■例
<div class="imgover">
	<a><img src="foo.gif"></a>　←反応する
	<a><img src="bar.gif"></a>　←反応する
	<a><img src="foobar.gif" class="imgactive"></a>　←反応しない
	<img src="foo2.gif">　←反応しない
</div>

■引数
.imgover({
	exclude: "imgactive",
	postfix: "o",
	aPostfix: "", //指定なしならpostfixと同じ
	isSelf: false,
	isSelfOver: false
});
*/
	$.fn.imgover = function(config){
		
		config = $.extend({
			exclude: "imgactive",
			postfix: "o",
			aPostfix: "",
			isSelf: false,
			isSelfOver: false,
			dynamic: false
		},config);
		
		var tObj = this;
		tObj.find("a").each(function(){
			
			var aPostfix = config.aPostfix ? config.aPostfix : config.postfix;
			var dynamic = config.dynamic;
			
			$(this).find("img").each(function(){
				var src = $(this).attr("src");
				var ftype = src.substring(src.lastIndexOf('.'), src.length);
				src =  dynamic ? src.replace(new RegExp("_"+ aPostfix + ftype), ftype) : src;
				
				//自身のページかチェック
				if(config.isSelf && new myFunc.URI($(this).attr("href")).isSelfLink){
					
					var asrc = src.replace(ftype, "_"+ aPostfix + ftype);
					$(this).attr("src", asrc);
					src = $(this).attr("src");
					
					//自身の場合のマウスオーバー可否
					if(!config.isSelfOver){
						$(this).addClass(config.exclude);
					}
				}
				
				var hsrc = src.replace(ftype, "_"+config.postfix + ftype);
				
				myFunc.PreLoad.load(hsrc);
				
				$(this).filter("img" + (dynamic ? "" :":not(."+ config.exclude +")"))
					.hover(function(){
						if(!(dynamic && $(this).is("."+ config.exclude)))
							$(this).attr("src", hsrc);
					},function(){
						if(!(dynamic && $(this).is("."+ config.exclude)))
							$(this).attr("src", src.replace("_"+config.postfix + ftype, ftype));
					});
			});
		});
		return tObj;
	};


/*** 画像切替 ***
■解説
[対象Object]のリンクにマウスオーバーで[引数:targetAttr]=""に指定したIDの画像が
[引数:targetAttr]=""が指定されてなかったら自分自身の画像が
「画像名_[引数:postfix].拡張子」に切り替わる。（foo.gif→foo_o.gif）
もちろんマウスアウトで元の画像に戻るよ。

■例
ターゲットが別オブジェクトの場合
<a class="chimg" chimg="hogehoge">text</a>
<img src="foo.gif" id="hogehoge">

ターゲットがオブジェクト自身の場合
<img src="hogehoge.gif" class="chimg" />
<input type="image" src="hogehoge.gif" class="chimg" />

<a href="" chimg="hogehoge"><img src="hogehoge.gif" id="hogehoge" /></a>

■引数
.chimg({
	postfix: "o",
	targetAttr: "chimg"
});
*/
	$.fn.chimg = function(config){
		
		config = $.extend({
			postfix: "o",
			targetAttr: "chimg"
		},config);
		
		var tObj = this;
		tObj.each(function(){
			var chimg = $(this).attr(config.targetAttr);
			var target = (chimg == undefined) ? $(this) : $("#"+chimg) ;
			
			//postfix属性があれば
			var postfix = $(this).attr("postfix");
			var postfix = (postfix == undefined) ? config.postfix : postfix ;
			
			var src = target.attr("src");
			var ftype = src.substring(src.lastIndexOf('.'), src.length);
			var hsrc = src.replace(ftype, "_"+postfix+ftype);
			
			myFunc.PreLoad.load(hsrc);
			
			$(this).hover(function(){
				target.attr("src", hsrc);
			},function(){
				target.attr("src", src.replace("_"+postfix+ftype, ftype));
			});
		});
		return tObj;
	};


/*** tableColor ***
■解説
[対象Object]内のtrかliタグに交互に
class="[引数:oddClass]"とclass="[引数:evenClass]"を付与する。
cssで色をつければ交互色に。

■例
<table class="coloredRow">
	<tr class="odd">
		<th></th><td></td>
	</tr>
	<tr class="even">
		<th></th><td></td>
	</tr>
	<tr class="odd">
		<th></th><td></td>
	</tr>
</table>

■TODO
ul,ol,dlあたりでもできるように。
	→liできたよー。

■引数
.alternate({
	evenClass: "even",
	oddClass: "odd",
	onlyTbody: true,
});
*/
	$.fn.alternate = function(config){
		
		config = $.extend({
			evenClass: "even",
			oddClass: "odd",
			onlyTbody: true
		},config);
		
		var tObj = this;
		
		if(tObj.is("table")){
			var tObj = config.onlyTbody ? tObj.find("tbody") : tObj ;
			tObj.find("> tr:odd").addClass(config.oddClass);
			tObj.find("> tr:even").addClass(config.evenClass);
		}else if(tObj.is("ul,ol")){
			tObj.find("> li:odd").addClass(config.oddClass);
			tObj.find("> li:even").addClass(config.evenClass);
		}
		
		return tObj;
	};


})(jQuery);
