/**
 * prototype-helper.js
 * 
 * prototype.jsのヘルパライブラリ
 * 
 * $Id: $
 */
/**
 * 指定された要素内のチェックボックスをすべてOn/Offする
 * 
 * @param	string	parent_id	チェックボックス入っている親要素
 * @param	bool	value		true=すべてOn,false=すべてOff
 * @param	string	tag_type	検索するタグ,デフォルトは'input'
 */

/*************************
 * JavaScript Base Libraly
 * 
 * JavaScriptのベースライブラリ
 * 
 *************************/
function is_array( a ){ return ((typeof a == "object") && (a.constructor == Array)) };
function is_object( a ){ return ((typeof a == "object") && (a.constructor == Object)) };

function mod(a,b){
	return Math.floor(a/b);
}
function modU(a,b){
	return Math.ceil(a/b);
}
/**
 * consoleオブジェクトのダミー定義
 *
 * FireBugが無い環境やIEの場合
 */
try{
	if(!console){
		console=new Object;
		console.debug = function(){};
	}
} catch(e) {
	console=new Object;
	console.debug = function(){};
	console.log = function(){};
}
/**
 * 変数を配列化する
 * aが配列だった場合そのまま、それ以外の場合は$A(a)する。
 * @param	mixed	a
 * @return	enumbable
 */
function to_array( a ){
	if (typeof a == 'string') {
		return new Array(a);
	} else if ( is_array(a) ){
		return a;
	} else {
		return $A(a);
	}
}

/*************************
 * DOM HELPER SECTION
 * 
 * DOM操作関係のヘルパー関数
 * 
 *************************/
/**
 * INPUTコントローラ
 * 
 * ex.
 * 	チェックボックスを全部消す   cntl_checkbox( 親エレメント, false, 'checkbox')
 * 	チェックボックスを全部付ける cntl_checkbox( 親エレメント, true, 'checkbox')
 */
function cntl_checkbox( parent_id, value, tag_type ){
	if(!tag_type) tag_type='input';
	$A($(parent_id).getElementsByTagName(tag_type.toLowerCase())).each( function (s){
		s.checked=value;		
	});
}
/**
 * 子ノードをすべて削除する
 * @param	HTMLElement		parentNode
 * @return	HTMLElement		チェイン用にparentNodeをそのまま返す
 */
function cleanUpChild( parentNode ){
	$A(parentNode.childNodes).each(function(e){
		parentNode.removeChild(e);
	});
	return parentNode;
}

/**
 * 指定されたタグが出現するまでparentNodeをさかのぼる
 * @param	HTMLElement	element	
 * @param	string		tagName
 * @return	HTMLElement
 */
function parentNodeMatch( element, tagName ){
	if( element.parentNode ){
		console.debug('e',element.parentNode);
		if(element.parentNode.tagName.toLowerCase()==tagName.toLowerCase()){
			return element.parentNode;
		} else {
			return parentNodeMatch( element.parentNode, tagName );
		}
	} else {
		return null;
	}
}
/** 
 * 指定した要素の後に新しい要素を挿入する
 * @param	HTMLElement	element		この要素の次に挿入する
 * @param	HTMLElement	newElement	追加する新しい要素
 * @return  =newElement
 */
function insertAfter( element, newElement ){
	try{
		if(element.nextSibling){
			element.parentNode.insertBefore( newElement, element.nextSibling );
		} else {
			element.parentNode.appendChild( newElement );
		}
	} catch(e){
		alert('prototype-helper.js - insertAfter() Failed.');
	}
	return newElement;
}

/**
 * CSSを動的にロードする
 * @param	mixed	cssFilepaths	CSSファイルの配列または文字列
 * @return	none
 */
function loadCSS( cssFilepaths ){
	head=document.getElementsByTagName('head');
	if(head.length>0){
		to_array(cssFilepaths).each( function(css){
			head[0].appendChild( $c('link',{ 'rel':"stylesheet", 'href' : css, 'type':"text/css"}));
		});
	}
}
/**
 * $()が信用ならないので単純なgetElementByIdのエイリアス
 */
function $I( elem ){
	return document.getElementById(elem);
}

/**
 * 指定されたタグ要素のnextSiblingが見つかるまで探す
 */
AppendElementMethods = {
    forwardSibling : function ( element, tagName ){
        var target = element.nextSibling;
        while ( target ) {
        	if ( target.tagName && target.tagName.toLowerCase() == tagName.toLowerCase() ) {
        	    return target;
        	}
        	target=target.nextSibling;
        }
        console.debug("end");
        return null;
    }       
}

Element.addMethods( AppendElementMethods );

/* prototype拡張 */
/**
 * $c(tag,elem)
 * 
 * createElement(tag)してelem内を処理する
 * 
 * elemがStringの場合はinnerHTMLとしてタグを追加する
 *  ex e=$c('p','Pタグの中身');
 * 
 * elemがエレメントの場合はappendChildする
 *  ex. e=$c('a', element );
 *  ex. e=$c('ul', $c('li','LIの中身') ); 
 *  <ul><li>LIの中身</li></ul>という出力になる
 * 
 * elemがプロパティオブジェクトの場合は作成したエレメントのプロパティを設定する
 *  ex. $c('a',{ href : 'www.google.com', innerHTML : 'Google' } )
 * 
 */
$c = function (tag,elem){
	var e=document.createElement(tag);
	if(elem){ 
		if ( is_object(elem) ){
			// 無名オブジェクトの場合、プロパティを設定
			for(i in elem){
				try{
					switch (i) {
						case 'style':
							Element.setStyle(e, $H(elem[i]));
							break;
						case 'class':
							Element.addClassName(e, elem[i]);
							break;
						case 'colspan':
							e.setAttribute('colSpan',elem[i]);
							break;
						case 'rowspan':
							e.setAttribute('rowSpan',elem[i]);
							break;
						default:
							e[i]=elem[i];
							break;
					}

					if(i==='style'){
					} else if(i==='class'){
					} else{
					}
				} catch(e) {
					alert('$c error property -> '+i);
				}
			}
		} else {
			to_array(elem).each(function(c){
				if ( typeof c == 'string' ){
					e.innerHTML=c;	
				} else if ( is_object(c) ){
					alert( 'c type'+(typeof c) );
				} else {
					e.appendChild(c);
				}
			});
		}
	}
	return e;
};

/**
 * Dateオブジェクト拡張
 * 
 */
Object.extend(Date.prototype, {
	getLastDay : function (){
		pd = new Date(this.getFullYear(),this.getMonth()+1,0);
		return pd.getDate();
	},
	zeroPadding : function ( value ) {
		return (value.toString().length==1)?'0'+value:value;
	},
	getFirstDay : function (){
		return new Date(this.getFullYear(),this.getMonth(),1);
	},
	/**
	 * その月の最初の日に設定する
	 * @param modify 月の指定を差し引きする
	 */	setFirstDayOfMonth : function ( modify ){
		modify = modify || 0;
		this.setFullYear( this.getFullYear(), this.getMonth()+modify, 1 );
		return this;
	},
	/** その月の最後の日に設定する
	 * @param modify 月の指定を差し引きする
	 */
	setLastDayOfMonth : function ( modify ){
		modify = modify || 0;
		this.setFullYear( this.getFullYear(), this.getMonth()+modify, this.getLastDay() );
		return this;
	},
	setYesterday : function (){
		
	},
	setToday : function (){
		
	},
	setNextMonth : function (){
		this.setFullYear( this.getFullYear(), this.getMonth()+1, this.getDate() );
	},
	setPrevMonth : function (){
		this.setFullYear( this.getFullYear(), this.getMonth()-1, this.getDate() );
	},
	/**
	 * format文字列を返す
	 * Y : 2桁の年
	 * YY : 4桁の年
	 * M : 月
	 * MM : ゼロパディングされた月
	 * D : 日付
	 * DD : 0パディングされた日付(2桁)
	 * 
	 */
	formatString : function ( formatStr ){
		var YY = this.getFullYear();
		var DD = this.zeroPadding( this.getDate() );
		var MM = this.zeroPadding( this.getMonth()+1 );
		var M = this.getMonth()+1;
		var Y = this.getYear();
		var D = this.getDate();
		formatStr=formatStr.replace(/YY/,YY);
		formatStr=formatStr.replace(/DD/,DD);
		formatStr=formatStr.replace(/MM/,MM);
		formatStr=formatStr.replace(/Y/,Y);
		formatStr=formatStr.replace(/D/,D);
		formatStr=formatStr.replace(/M/,M);
		return formatStr;
	}
});

/**
 * $t(tag,obj)
 * エレメント内の子要素を評価関数でtrueを返すものだけを配列で返す
 * エレメント内の子要素をプロパティ比較して同じものだけを配列で返す
 * 
 * @param	string				tag	getElementsByTagNameするタグ名(inputとかaとかpとか)
 * @param	object | function	obj	プロパティオブジェクトまたは評価関数( 型はbool function(element){} )
 * 
 * objがObjectの場合、プロパティ比較を行ってすべてマッチする子要素を返す
 *  ex. $t('input', { type : 'text', size : '20' } );
 * 
 * objがfunctionの場合、obj()の返り値がtrueのもののみ返す(上のexと等価)
 *  ex $t('input', function(s){ return ( s.type=='text' && s.size=20 ) } );
 *  
 * @requires 'prototype.js'(>1.4)
 * 
 */
/*
Element.prototype.$t = function (tag,obj) {
	if(obj){
		if (typeof obj == 'function'){
			return $A(this.getElementsByTagName(tag)).findAll(obj.bind(this));
		} else if ( is_object(obj) ){
			return $A(this.getElementsByTagName(tag)).findAll( function(s){
				return $H(obj).all( function(f){
					return s[f[0]]==f[1];					
				});
			});
		}
	} else {
		return this.getElementsByTagName(tag);
	}
};
*/
/* String prototype拡張 */
// trim　前後の空白文字を切り落とす
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}
 