/***** 	NOT DIRECTLY EDIT. CHECK OUT FROM CVS *****/
//rakutenTr_common.js
//共通ユーティリティ関数郡
//カレンダー／Draggable／Optionタグ操作など
//@使用ページ
//・TOPページ（国内・海外）
//・国内地図（楽天トラベル提供地図・ルートマップ・地図から探す・地図から検索）
//
// getElementById のエイリアス
function $$$(id){
	return document.getElementById(id);
}
function $$$H(tagname){
	return document.createElement(tagname);
}
//08.03.05追加
//タグ名で取得
//第1引数 タグ名（カンマ区切り可）
function $$$TN(tagName){
	tagName = tagName.split(',');
	var rtn = [];
	for(var i = 0,len = tagName.length;i<len;i++){
		var obj = document.getElementsByTagName(tagName[i]);
		for(var j = 0,len = obj.length;j<len;j++){
			rtn.push(obj[j]);
		}
	}
	return rtn;
}
//08.03.05追加
//クラス名で取得
//第1引数 クラス名（,区切り可）
//第2引数 タグ名（,区切り可）/html elementの配列
//取得結果がない場合は、空の配列を返す。
function $$$CN(className,elem){
	if(elem == undefined){
		elem = $$$TN('*');
	}
	else if(typeof elem == "string"){
		elem = $$$TN(elem);
	}
	var rtn = [];
	var classNameArray = className.split(',');
	for(var i = 0,len = elem.length;i<len;i++){
		for(var j=0,len2 = classNameArray.length;j<len2;j++){
			try{
			if( (' '+elem[i].className+' ').indexOf(classNameArray[j]) >= 0){
				rtn.push(elem[i]);
				//重複しないようにループを抜ける
				break;
			}
			}catch(e){}
		}
	}
	return rtn;
}
//HTMLElement を生成する
//第1引数:element名、第2引数:elementに与えるパラメータ、第3引数:textノードに加えたい文字列
function $$$E(elementName,attrObj,text){
	try{
	if(!elementName) return null;
	if(elementName == 'input' && attrObj['type']!= 'text' && isIE()){
		return (function(attrObj,text){
			//HTMLInputElement を生成する(IE限定)
			if(!attrObj['type'] || !attrObj['name'] || !attrObj['id']) return null;
			var checkedStr = '';
			if(attrObj['checked']) checkedStr = 'checked';
			var txt = "<input type='"+ attrObj['type'] +"' name='"+attrObj['name']+"' id='"+attrObj['id']+"' ";
			if(attrObj['value']) txt = txt + ' value="' + attrObj['value'] + '" ';
			txt = txt + checkedStr + ">";
			return document.createElement(txt);
		})(attrObj,text);
	}
	var rtn = $$$H(elementName);
	if(attrObj){
		for(prop in attrObj){
			rtn[prop]=attrObj[prop];
		}
	}
	if(text) apTextNode(rtn,text);
		return rtn;
	}catch(e){
		debugF(e.message);
	}
}

// 08.05.16追加
// イベントを貼り付ける関数
// 第1引数 : HTMLElement , 第2引数 : event名 ,第3引数 : 実行する関数
function $$$addEvent(elem,event,fn){
	if(elem){
		if (elem.addEventListener){
			elem.addEventListener(event, fn, false);
		}else{
			elem.attachEvent('on'+event, fn);
		}
	}
}
//ブラウザ判定関数群
function isIE(){
	return (navigator.userAgent.indexOf("MSIE") >= 0)
}
function isFF(){
	return (navigator.userAgent.indexOf("Firefox") >= 0)
}
function isFF3(){
	return (navigator.userAgent.indexOf("Firefox/3") >= 0)
}
function isOpera(){
	return (navigator.userAgent.indexOf("Opera") >= 0);
}
function isNS(){
	return  (navigator.userAgent.indexOf("Netscape") >= 0)
}

//ElementIdを受け取ってそのElement中のimgタグの画像を再取得する。
function $awake(id){
	var img = $$$(id).getElementsByTagName('img');
	if(img == null) return;
	for(var i=0; i<img.length; i++) {
		img[i].src = img[i].src;
	}
}

function $$$setDarkScreen(element){
	var d = document.createElement('div');
	d.id = 'rakutenTrDarkScreen';
	d.style.position = 'absolute';
	d.style.backgroundColor = '#000000';
	d.style.top = '0px';
	d.style.left = '0px';
	d.style.height = '100%';
	d.style.width = '100%';
	d.style.opacity = '.70';
	d.style.MozOpacity = '.70';
	d.style.filter = 'alpha(opacity=70)';
	if(element){
		if(!element.style.width && !element.style.height){
			element.style.width = '100px';
			element.style.height = '50px';
		}
		element.style.position = 'absolute';
		element.style.left = '50%';
		element.style.top = '50%';
		var width = 0 - ( parseInt(element.style.width)/2) ;
		element.style.marginLeft = width + 'px';
		var height = 0 - (parseInt(element.style.height)/2);
		element.style.marginTop = height + 'px';
		d.appendChild(element);
	}
	document.body.appendChild(d);
}

function $$$removeDarkScreen(){
	document.body.removeChild($$$('rakutenTrDarkScreen'));
}
//数値プルダウンを生成する
function createNumericOptions(selectNode,params){
	var defaultParams = {
		remove:true
		,from:0
		,to:0
		,selectedIndex:0
		,valuePadding:0
		,namePadding:0
	};

	(params.remove)? true : params.remove = defaultParams.remove;
	(params.from)? true : params.from = defaultParams.from;
	(params.to)? true : params.to = defaultParams.to;
	(params.selectedIndex)? true : params.selectedIndex = defaultParams.selectedIndex;
	(params.valuePadding)? true : params.valuePadding = defaultParams.valuePadding;
	(params.namePadding)? true : params.namePadding = defaultParams.namePadding;
	//error check
	if(!(params.from+'').match(/^\d+$/)||!(params.to+'').match(/^\d+$/)||!(params.selectedIndex+'').match(/^\d+$/)||!(params.valuePadding+'').match(/^\d+$/)||!(params.namePadding+'').match(/^\d+$/)) return;
	if(params.from > params.to) return;
	if(params.to - params.from < params.selectedIndex) return;
	//add options
//	if(params.remove) selectNode.options.length = 0;
//	if(params.remove){
//		var cnodes = selectNode.childNodes;
//		for(var i = 0,len = cnodes.length;i<len;i++){
//			cnodes[0].parentNode.removeChild(cnodes[0]);
//		}
//	}
	if(params.remove){
		while(selectNode.hasChildNodes()) {
			selectNode.removeChild(selectNode.firstChild);
		}
	}
	var padfunc = function(v,p){
		if((''+v).length < p){
			for(var i = 0,l = p - (v+'').length;i < l ;i++){
				v = '0' + v;
			}
		}
		return v;
	}
	for(var i=params.from,j=0;i<=params.to;i++,j++){
		selectNode.options[j] = new Option(padfunc(i,params.namePadding),padfunc(i,params.valuePadding));
//		var option =new Option(padfunc(i,params.namePadding),padfunc(i,params.valuePadding));
//		option.selected = (i==0);
//		selectNode.add(option);
	}
//	selectNode.selectedIndex = params.selectedIndex;
	if (isOpera()) {
		//Operaではこのように指定しないと、プルダウン中に空白の値が出力されてしまうことがある。
		selectNode.options[params.selectedIndex].defaultSelected = true;
	} else {
		selectNode.selectedIndex = params.selectedIndex;
	}
	return selectNode;
}
//日付プルダウン生成（年と月からそれに対応した日付プルダウンを生成する
function setDateOption(dateNode,year,month,valuePadding,namePadding){
	if(!year || !month) return;
	if(!year.match(/^\d{1,4}$/)) return;
	//if(!month.match(/^[0][1-9]$|^[1][0-2]$|^[0-9]$/)) return;

	var ifObj = {};
	(valuePadding) ? ifObj.valuePadding = valuePadding :ifObj.valuePadding = 0;
	(namePadding) ? ifObj.namePadding = namePadding : ifObj.namePadding = 0 ;

	var tmp = new Date(new Date(year,month).getTime() - 1000);
	var lastDay = tmp.getDate() - 0;
	var ind = (dateNode.selectedIndex<lastDay-1)?dateNode.selectedIndex:lastDay-1;
	if (isOpera()) {
		//Operaではこのように指定しないと、プルダウン中に空白の値が出力されてしまうことがある。
		dateNode.options[ind].defaultSelected = true;
	} else {
		dateNode.selectedIndex = ind;
	}
	ifObj.from = 1;
	ifObj.to = lastDay;
	ifObj.selectedIndex = ind;

	createNumericOptions(dateNode,ifObj);
}

//テキストノードを生成する
//第1引数:テキストノードをappendしたいelement、第2引数:appendしたいテキスト
function apTextNode(element,text){
	var tNode = document.createTextNode(text);
	element.appendChild(tNode);
}
//デバッグ用の関数
function debugF(obj){
//	try { console.log(obj)}catch(e){
//		var txt = '';
//		for(p in obj){
//			txt = txt + p + ':' + obj[p];
//		}
//		alert(txt);
//	};
}
//文字列を与えると指定した長さになるよう左側に0詰めする。
function $$$padZeroLeft(str,len) {
	str = '' + str;
	if(str.length < len) {
		var l = len -str.length;
		for(var i = 0;i < l ;i++) {
			str = '' + '0' + str;
		}
	}
	return str;
};
//HTMLエレメントにStyleをセットする。
function $$$setStyles(element,styleObj){
	if(styleObj instanceof Array == false){
		styleObj = [styleObj];
	}
	var style = element.style;
	for(var i = 0,len = styleObj.length;i<len;i++){
		for(p in styleObj[i]){
			try{style[p] = styleObj[i][p];}catch(e){alert(e);};
		}
	}
}
//オブジェクトをコピーする
function $$$copy(original){
	var copy = {};
	for(p in original){
		if(original[p] instanceof Object){
			copy[p] = $$$copy(original[p]);
		}else{
			copy[p] = original[p];
		}
	}
	return copy;
}
//第1～3引数で指定した日付に基づいて、第4～6引数で指定した日付プルダウンを、第7引数日分だけスリップさせる。
//08.05.01追加
function $$$slipDateSelectbox(ciy,cim,cid,coy,com,cod,slip){
	try{
	ciy = $$$(ciy),cim = $$$(cim),cid = $$$(cid),coy = $$$(coy),com = $$$(com),cod = $$$(cod);
	//parseIntして空文字を付加することで、01のような左を0詰めされた文字列の0を削除する
	var cidate = new Date(ciy.value,(parseInt(cim.value,10) - 1)+'',parseInt(cid.value,10)+'');
	cidate.setTime(cidate.getTime() + (slip*24*3600000));
	coy.value = cidate.getFullYear();
	com.selectedIndex = cidate.getMonth();
	cod.selectedIndex = cidate.getDate()-1;
	}catch(e){}
}
//楽天カレンダークラス
var calendarHoliday = ('20071224,20080101,20080114,20080211,20080320,20080429,20080503,20080505,20080506,20080721,20080915,20081013,20081103,20081123,20081124,20081223'
					+',20080101,20080114,20080211,20080320,20080429,20080503,20080504,20080505,20080721,20080915,20080923,20081013,20081103,20081123,20081124,20081223'
					+',20090101,20090112,20090211,20090320,20090429,20090503,20090504,20090505,20090506,20090720,20090921,20090922,20090923,20091012,20091103,20091123,20091223,'
					+',20100101,20100111,20100211,20100321,20100322,20100429,20100503,20100504,20100505,20100719,20100920,20100923,20101011,20101103,20101123,20101223'
					+',20110101,20110110,20110211,20110321,20110429,20110503,20110504,20110505,20110718,20110919,20110923,20111010,20111103,20111123,20111223'
					+',20120101,20120109,20120211,20120320,20120429,20120503,20120504,20120505,20120716,20120917,20120922,20121008,20121103,20121123,20121223'
					+',20130101,20130114,20130211,20130320,20130429,20130503,20130504,20130505,20130715,20130916,20130923,20131014,20131103,20131123,20131223'
					).split(',');
var RakutenCalendar = {
	dayOfWeek : {"0":"日","1":"月","2":"火","3":"水","4":"木","5":"金","6":"土"},
	holiday : {},
	//祝日データをセットする関数。YYYYMMDD形式の文字列の配列を渡す。
	setHoliday : function(arg){
		for(var i = 0,len = arg.length;i<len;i++){
			this.holiday[arg[i]] = arg[i];
		}
	},
	// CSSのオブジェクト。
	// カレンダーを表示する前に、ここのデータを置き換えることで、
	// 表示するカレンダーの見た目を変更することができる。
	styles : {
		BASE_DIV_STYLE : {"position":"absolute","zIndex":"100000","backgroundColor":"#E3F2D7","border":"1px solid #5CA71F","padding":"0px","margin":"0px","paddingBottom":"0px"}
		,HEADER_DIV_STYLE : {"position":"absolute","top":"0px","left":"0px","padding":"0px","fontSize":"10pt","height":"23px","backgroundColor":"#5CA71F","color":"#FFFFFF"}
		,HEADER_TITLE_SPAN_STYLE : {"cssFloat":"left","styleFloat":"left","margin":"3px"}
		,CLOSE_BTN_SPAN_STYLE : {"cssFloat":"right","styleFloat":"right","margin":"3px","padding":"0px"}
		,CLOSE_BTN_A_STYLE : {"fontSize":"10pt","color":"#FFFFFF"}
		,CONTROL_DIV_STYLE : {"fontSize":"10pt","height":"20px","margin":"0px","padding":"0px"}
		,PREV_A_STYLE:{"cssFloat":"left","styleFloat":"left","margin":"3px","marginBottom":"0px","cursor":"hand","color":"#000000"}
		,NEXT_A_STYLE:{"cssFloat":"right","styleFloat":"right","margin":"3px","marginBottom":"0px","cursor":"hand","color":"#000000"}
		,CONTENTS_AREA_BASE_STYLE : {"position":"absolute","top":"23px","left":"0px","margin":"0px","padding":"0px"}
		,CALENDAR_BASE_DIV : {"position":"absolute","margin":"0px","padding":"1px","width":"160px","height":"170px"}
		,CALENDAR_LABLE : {"fontSize":"10pt","fontWeight":"bold","textAlign":"center","color":"#333333"}
		,CALENDAR_TABLE : {"margin":"0px","zIndex":"100002","borderCollapse":"collapse","border":"1px solid #AAAAAA","padding":"1px 2px","textAlign":"center","fontSize":"10pt","width":"145px"}
		,CALENDAR_TABLE_TH : {"fontSize":"10pt","fontWeight":"bold","border":"1px solid #AAAAAA","padding":"2px 3px","height":"15px","width":"13px"}
		,CALENDAR_SUNDAY : {"color":"#BB2030","backgroundColor":"#E1E1E1"}
		,CALENDAR_SATURDAY : {"color":"#284B77","backgroundColor":"#E1E1E1"}
		,CALENDAR_WEEKDAY : {"color":"#333333","backgroundColor":"#E1E1E1"}
		,CALENDAR_TXT_BEFORE_TODAY : {"color":"#999999"}
		,CALENDAR_TXT_TODAY : {"fontWeight":"bold","color":"#B15314"}
		,CALENDAR_TXT_USUAL : {"color":"#000000"}
		,CALENDAR_TD_HOLIDAY :{"background":"#FFCECE"}
		,CALENDAR_TD_SATURDAY : {"background":"#B0D8FF"}
		,CALENDAR_TD_WEEKDAY :{"background":"#FFFFFF"}
		,CALENDAR_TD_UNUSE : {"background":"#FFFFFF","color":"#FFFFFF"}
		,CALENDAR_TD_BASE : {"border":"1px solid #AAAAAA","padding":"2px 3px","height":"16px","width":"13px"}
	},
	setStyles : function(styleObj){
		for(p in styleObj){
			var toObj = this.styles[p];
			if(toObj){
				var fromObj = styleObj[p];
				for(p2 in fromObj){
					toObj[p2] = fromObj[p2];
				}
			}
		}
	},
	replaceStyles : function(styleObj){
		this.styles = {};
		this.styles = styleObj;
	},
	// カレンダーで利用する文言
	// カレンダーを表示する前にここのオブジェクトを変更することで
	// カレンダーに表示する文言を変更することができる。
	words : {
		DEFAULT_HEADER_MESSAGE : '日付を選択してください。'
		,PREV_LINK : '<< 前の月'
		,NEXT_LINK : '次の月 >>'
		,YEAR : '年'
		,MONTH : '月'
		,CLOSE_BTN : "[×閉じる]"
	},
	//カレンダーを示すHTMLのID
	ids : {
		BASE_ID : "rakutenCalendar"
		,HEADER_AREA_ID : "rakutenCalendar_top"
		,CONTENTS_AREA_ID : "rakutenCalendar_contents"
	},

	// element : カレンダーをappendするHTMLElement
	// dispParam : 表示位置 {"top":"200px","left":100px}のように指定
	// date : 初期表示月日 Date型で渡す。nullのときは表示日の月日がデフォルト
	// func : カレンダーの日付をクリックしたときに動作する関数
	// funcParam : 関数に渡す引数（配列）
	// num : 表示するカレンダーの数
	// culumn : 表示するカラム数
	// headerMessage : ヘッダーに指定するメッセージ
	// mode : 0:すべてのカレンダーを表示 1:本日日付以前のカレンダーは表示しない
	createCalendar : function(element,dispParam,date,func,funcParam,num,culumn,headerMessage,mode){
		this.closeCalendar();
		if(!date) date = new Date();
		var sd = new Date()
		sd.setTime(date.getTime());
		this.selDate = sd;

		//
		//追加(受け取った日付のDate部分を1日にする)
		//
		//ts-hiroaki.irie
		//20081107
		//
		date.setDate(1);
		
		if(!num) num = 1;
		if(!culumn) culumn = 1;
		if(!mode) mode = 0;
		if(!funcParam) funcParam = [];
		this.parentElement = element;
		var div = $$$H('div');
		div.id = this.ids.BASE_ID;
		//height属性を計算して設定
		var linenum = num / culumn;
		if(num % culumn != 0) linenum ++;
		this.styles.BASE_DIV_STYLE.height = (parseInt(this.styles.HEADER_DIV_STYLE.height) + 30 + (linenum * (parseInt(this.styles.CALENDAR_BASE_DIV.height) + 2))) + 'px';
		//width属性を計算して設定
		this.styles.BASE_DIV_STYLE.width = ((parseInt(this.styles.CALENDAR_BASE_DIV.width) + 5) * culumn) + 'px';
		$$$setStyles(div,this.styles.BASE_DIV_STYLE);
		if(dispParam["top"]) div.style.top = dispParam["top"];
		if(dispParam["left"]) div.style.left = dispParam["left"];
		if(headerMessage == null) headerMessage = this.words.DEFAULT_HEADER_MESSAGE;
		// < IE7 判定
		// IE7 以前のIEのときはSelectプルダウンが透けないようiframeを下に敷く
		if(isIE() && !window.XMLHttpRequest){
			var iframe = $$$E('iframe',{src:'javascript:false;',width:'100%',height:'100%'});
			$$$setStyles(iframe,{'filter':'alpha(opacity=0)','zoom':'1'});
			div.appendChild(iframe);
		}
		var header = $$$E('div',{"id":this.ids.HEADER_AREA_ID});
		this.styles.HEADER_DIV_STYLE.width = this.styles.BASE_DIV_STYLE.width;
		this.styles.CONTROL_DIV_STYLE.width = this.styles.BASE_DIV_STYLE.width;
		$$$setStyles(header,this.styles.HEADER_DIV_STYLE);
		var headerTitle = $$$E('span',null,headerMessage);
		headerTitle.className = "cal_headerTitle";
		$$$setStyles(headerTitle,this.styles.HEADER_TITLE_SPAN_STYLE);
		header.appendChild(headerTitle);
		var closebtnSpan = $$$E('span');
		closebtnSpan.className = "cal_closeBtnSpan";
		$$$setStyles(closebtnSpan,this.styles.CLOSE_BTN_SPAN_STYLE);

		var closebtn = $$$E('a',{"href":"javascript:RakutenCalendar.closeCalendar();"},this.words.CLOSE_BTN);
		closebtn.id = "cal_closeBtn";
		closebtn.className = "cal_closeBtn";
		$$$setStyles(closebtn,this.styles.CLOSE_BTN_A_STYLE);
		closebtnSpan.appendChild(closebtn);
		header.appendChild(closebtnSpan);
		div.appendChild(header);
		var contents = $$$E('div',{"id":this.ids.CONTENTS_AREA_ID},null);
		$$$setStyles(contents,this.styles.CONTENTS_AREA_BASE_STYLE);

		this.createCalendarContentsArea(contents,dispParam,date,func,funcParam,num,culumn,headerMessage,mode);

		div.appendChild(contents);
		element.appendChild(div);
	},
	createCalendarContentsArea : function(contents,dispParam,date,func,funcParam,num,culumn,headerMessage,mode){
		var cont = $$$E('div',null,null);
		cont.className = "cal_controlDiv";
		$$$setStyles(cont,this.styles.CONTROL_DIV_STYLE);
		var prevDate = new Date(date.getTime());
		prevDate.setMonth(prevDate.getMonth() - num);
		var prev = $$$E('a',{"href":"javascript:void(0);","onclick":function(){RakutenCalendar.pagingCalendar(contents,dispParam,prevDate,func,funcParam,num,culumn,headerMessage,mode)}},this.words.PREV_LINK);
		prev.className = "cal_prevMonthBtn";
		$$$setStyles(prev,this.styles.PREV_A_STYLE);
		if(mode == 1){
			var startTime = new Date();
			startTime.setTime(date.getTime());
			startTime.setDate(1);
			startTime = startTime.getTime();
			var endTime = new Date();
			endTime.setTime(date.getTime());
			endTime.setMonth(endTime.getMonth() + num);
			endTime = endTime.getTime() - (24 * 3600000);
			var todayTime = new Date().getTime();
			if(startTime <= todayTime && todayTime <= endTime) prev.style.display = 'none';
		}
		var nextDate = new Date(date.getTime());
		nextDate.setMonth(nextDate.getMonth() + num);
		var next = $$$E('a',{"href":"javascript:void(0);","onclick":function(){RakutenCalendar.pagingCalendar(contents,dispParam,nextDate,func,funcParam,num,culumn,headerMessage,mode)}},this.words.NEXT_LINK);
		next.className = "cal_nextMonthBtn";
		$$$setStyles(next,this.styles.NEXT_A_STYLE);

		cont.appendChild(prev);
		cont.appendChild(next);
		contents.appendChild(cont);
		for(var i = 0;i<num;i++){
			var year = date.getFullYear();
			var month = date.getMonth();
			var caldiv = this.createCalendarBody(year,month + 1,func,funcParam,mode);
			caldiv.style.top = (function(culumn,i,topmargin,height){
				return ( parseInt(topmargin) + (parseInt(i / culumn) * parseInt(height))) + 'px' ;
			})(culumn,i,parseInt(this.styles.HEADER_DIV_STYLE.height) + 5,this.styles.CALENDAR_BASE_DIV.height);
			caldiv.style.left = (function(culumn,i,leftmargin,width){
				return (parseInt(leftmargin) + ((i % culumn) * parseInt(width))) + 'px';
			})(culumn,i,10,this.styles.CALENDAR_BASE_DIV.width);
			contents.appendChild(caldiv);
			date.setDate(1);
			date.setMonth(month + 1);
		}
		return contents;
	},
	//カレンダーのページング処理を行う
	pagingCalendar : function(contents,dispParam,date,func,funcParam,num,culumn,headerMessage,mode){
		var div = $$$(this.ids.BASE_ID);
		div.removeChild(contents);
		contents = $$$E('div',{"id":this.ids.CONTENTS_AREA_ID},null);
		$$$setStyles(contents,this.styles.CONTENTS_AREA_BASE_STYLE);
		this.createCalendarContentsArea(contents,dispParam,date,func,funcParam,num,culumn,headerMessage,mode);
		div.appendChild(contents);
	},
	//カレンダーをフロートタイプにする。
	createFloatCalendar :function(element,dispParam,date,func,funcParam,num,culumn,headerMessage,mode){
		this.createCalendar(element,dispParam,date,func,funcParam,num,culumn,headerMessage,mode);
		var win = new RakutenWindow(this.ids.BASE_ID);
		win.dragable(this.ids.HEADER_AREA_ID);
	},
	// element : カレンダーをappendするHTMLElement
	// dispParam : 表示位置 {"top":"200px","left":100px}のように指定
	// func : カレンダーの日付をクリックしたときに動作する関数
	// funcParam : 関数に渡す引数（配列）
	createRakutenTravelCalendar : function(element,dispParam,func,funcParam){
		this.createCalendar(element,dispParam,null,func,funcParam,2,2,null,1);
	},
	//楽天トラベル用のフロートカレンダーを生成する
	createRakutenTravelFloatCalendar : function(element,dispParam,func,funcParam){
		this.createRakutenTravelCalendar(element,dispParam,func,funcParam);
		var win = new RakutenWindow(this.ids.BASE_ID);
		win.dragable(this.ids.HEADER_AREA_ID);
	},
	//カレンダーを閉じる
	closeCalendar : function(){
		try{this.parentElement.removeChild($$$(this.ids.BASE_ID));}catch(e){};
	},
	//１月分のカレンダーを作る
	createCalendarBody : function(year,month,func,funcParam,mode){
		var checkDate = new Date();
		var dispDate = new Date(year,month - 1,1);
		var start = dispDate.getDay();
		var month = dispDate.getMonth();
		dispDate.setDate(dispDate.getDate() - start);

		var div = $$$H('div');
		div.className = "cal_baseDiv"
		$$$setStyles(div,this.styles.CALENDAR_BASE_DIV);

		var lbl = $$$E('label',null,year + this.words.YEAR + (month + 1) + this.words.MONTH);
		lbl.className = "cal_indexMonth";
		$$$setStyles(lbl,this.styles.CALENDAR_LABLE)

		var tbl = $$$E('table');
		$$$setStyles(tbl,this.styles.CALENDAR_TABLE)
		//Macではフォントが異なるため、普通にしていると文字サイズに押されてデザインが崩れる。
		//そこで、Macを判定して、フォントサイズを個別指定する。
		if(navigator.userAgent.match(/Mac|PPC/)){
			$$$setStyles(tbl,{"fontSize":"8pt"});
		}
		var tblbody = $$$H('tbody');

		for(var i = 0;i<7;i++){
			var tr  = $$$E('TR');
			if(i == 0){
				//1行目はHeaderを書き出す
				for(var j = 0;j<7;j++){
					var th = $$$E('th',null,this.dayOfWeek[j])
					if(j==0){
						th.className = "cal_tr_sunday";
						$$$setStyles(th,this.styles.CALENDAR_SUNDAY);
					}else if(j==6){
						th.className = "cal_tr_saturday";
						$$$setStyles(th,this.styles.CALENDAR_SATURDAY);
					}else{
						th.className = "cal_tr_weekday";
						$$$setStyles(th,this.styles.CALENDAR_WEEKDAY);
					}
					$$$setStyles(th,this.styles.CALENDAR_TABLE_TH);
					tr.appendChild(th);
				}
			}else{
				for(var j = 0;j<7;j++){
					var txt;
					var td = $$$E('TD',null);

					if((start && start <= j) ||(!start && month == dispDate.getMonth())){
						if(mode == 1 && dispDate.getTime() < (checkDate.getTime() - 24*3600000)){
							//mode=1 なので昨日より前はリンクをはらない。
							txt = $$$E('label',null,dispDate.getDate()+'');
							txt.className = "cal_label_beforeToday"
							$$$setStyles(txt,this.styles.CALENDAR_TXT_BEFORE_TODAY);
						}else{
							txt = $$$E('a',{"href":"javascript:void(0);","d":new Date(dispDate.getTime()),"onclick":function(){func.apply(this.d,funcParam);}},dispDate.getDate()+'');
							if(mode == 1 && this.selDate.getFullYear() == dispDate.getFullYear()
								&& this.selDate.getMonth() == dispDate.getMonth()
								&& this.selDate.getDate() == dispDate.getDate()){
								//mode=1 で本日の日付なのでフォントを特殊にする。
								txt.className = "cal_text_selectDay";
								$$$setStyles(txt,this.styles.CALENDAR_TXT_TODAY);
							}else if(mode == 1 && checkDate.getFullYear() == dispDate.getFullYear()
								&& checkDate.getMonth() == dispDate.getMonth()
								&& checkDate.getDate() == dispDate.getDate()){
								//mode=1 で本日の日付なのでフォントを特殊にする。
								txt.className = "cal_text_today";
								$$$setStyles(txt,this.styles.CALENDAR_TXT_TODAY);
							}else if(dispDate.getDay() == 0 || dateString in this.holiday){
								txt.className = "cal_text_holiday";
								$$$setStyles(txt,this.styles.CALENDAR_TXT_USUAL);
							}else if(dispDate.getDay() == 6){
								txt.className = "cal_text_saturday";
								$$$setStyles(txt,this.styles.CALENDAR_TXT_USUAL);
							}else {
								txt.className = "cal_text_weekday";
								$$$setStyles(txt,this.styles.CALENDAR_TXT_USUAL);
							}
						}
						//その月に入ったのでstartをfalseにする。このときまでstartには月の最初の日にちの曜日を表す数字0～6が入っている。
						start = false;
						var dateString = dispDate.getFullYear() + $$$padZeroLeft(dispDate.getMonth() + 1,2) + $$$padZeroLeft(dispDate.getDate(),2);
						if(mode == 1 && dispDate.getTime() < (checkDate.getTime() - 24*3600000)){
							td.className = "cal_td_beforeToday";
							$$$setStyles(td,this.styles.CALENDAR_TD_WEEKDAY);
						}else if(mode == 1 && this.selDate.getFullYear() == dispDate.getFullYear()
								&& this.selDate.getMonth() == dispDate.getMonth()
								&& this.selDate.getDate() == dispDate.getDate()){
							td.className = "cal_td_selectDay";
							$$$setStyles(td,this.styles.CALENDAR_TD_WEEKDAY);
						}else if(mode == 1 && checkDate.getFullYear() == dispDate.getFullYear()
								&& checkDate.getMonth() == dispDate.getMonth()
								&& checkDate.getDate() == dispDate.getDate()){
							td.className = "cal_td_today";
							$$$setStyles(td,this.styles.CALENDAR_TD_WEEKDAY);
						}else if(dispDate.getDay() == 0 || dateString in this.holiday){
							td.className = "cal_td_holiday";
							$$$setStyles(td,this.styles.CALENDAR_TD_HOLIDAY);
						}else if(dispDate.getDay() == 6){
							td.className = "cal_td_saturday";
							$$$setStyles(td,this.styles.CALENDAR_TD_SATURDAY);
						}else {
							td.className ="cal_td_weekday";
							$$$setStyles(td,this.styles.CALENDAR_TD_WEEKDAY);
						}
					}else{
						txt = document.createTextNode(dispDate.getDate()+'');
						td.className = "cal_td_unuse";
						$$$setStyles(td,this.styles.CALENDAR_TD_UNUSE);
					}
					td.appendChild(txt);
					$$$setStyles(td,this.styles.CALENDAR_TD_BASE);
					tr.appendChild(td);
					var d = dispDate.getDate() - 0 + 1;
					dispDate.setDate(d);
				}
			}
			tblbody.appendChild(tr);
		}
		tbl.appendChild(tblbody);
		div.appendChild(lbl);
		div.appendChild(tbl)
		return div;
	}
}



//ウィンドウクラス
//ドラッグ可能にするロジックのみ実装
//スライダー等拡張はこのクラスに対して行う
var RakutenWindow = function(element) {
	if (typeof element == "string" || element instanceof String) {
		this.element = $$$(element);
	} else {
		this.element = element;
	}
	this.style = this.element.style;
	this.isMoving = false;
	this.observers = new Array();
	this.currentStyle = this.element.currentStyle || document.defaultView.getComputedStyle(this.element, '');
	this.mouseX;
	this.mouseY;
};
RakutenWindow.prototype.destroy = function(){};
RakutenWindow.prototype.getX = function(){
	return parseInt(this.currentStyle.left);
}
RakutenWindow.prototype.getY = function(){
	return parseInt(this.currentStyle.top);
}
RakutenWindow.prototype.setX = function(_in){
	this.element.style.left = parseInt(_in) + 'px';
}
RakutenWindow.prototype.setY = function(_in){
	this.element.style.top = parseInt(_in) + 'px';
}
RakutenWindow.prototype.setPosition = function(_x,_y){
	this.setX(_x);
	this.setY(_y);
}
RakutenWindow.prototype.getPosition = function(){
	return [this.getX(),this.getY()];
}
RakutenWindow.prototype.observe = function(element, name, observer) {
	if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/)|| element.attachEvent)) name = 'keydown';
	var event;
	if (element.addEventListener) {
		event = name;
		element.addEventListener(event, observer, false);
	} else if (element.attachEvent) {
		event = "on" + name;
		element.attachEvent(event, observer);
	}
	if(event) this.observers.push([element,name,observer]);
	return observer;
};
RakutenWindow.prototype.selectDisabled = function(event) {
	if (isIE()) {
		document.body.onselectstart = function(e){ return false };
	} else {
		try { event.preventDefault(); } catch(e) {};
	}
};
RakutenWindow.prototype.selectEnabled = function() {
	if (isIE()) document.body.onselectstart = "";
};
RakutenWindow.prototype.detach = function(element, name, observer) {
	if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent)) name = 'keydown';
    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      try {
        element.detachEvent('on' + name, observer);
      } catch (e) {}
    }
};

RakutenWindow.prototype.allDetach = function(){
	if (!this.observers || this.observers.length == 0) return;
	for (var i = 0, length = this.observers.length; i < length; i++) {
      this.detach.apply(this, this.observers[i]);
      this.observers[i][0] = null;
    }
	this.observers = new Array();
};
RakutenWindow.prototype.disableSelect = function(event) {
	if (isIE()) {
		document.getElementsByTagName("body").item(0).onselectstart = function(e){ return false };
	} else {
		try { event.preventDefault(); } catch(e) {};
	}
};
RakutenWindow.prototype.enableSelect = function() {
	if (isIE()) document.getElementsByTagName("body").item(0).onselectstart = "";
};
RakutenWindow.prototype.pointerX = function(event){
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
}
RakutenWindow.prototype.pointerY = function(event){
    return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
}
RakutenWindow.prototype.dragMove = function(event){
	if(! this.isMoving) return;
	var oldX = this.mouseX;
	var oldY = this.mouseY;
	this.mouseX = this.pointerX(event);
	this.mouseY = this.pointerY(event);
	this.setPosition(this.getPosition()[0] - (oldX - this.mouseX),this.getPosition()[1]- (oldY - this.mouseY));
}
RakutenWindow.prototype.dragable = function(element){
	this.html = document.getElementsByTagName("html").item(0);
	this.dragArea = $$$(element);
	this.dragArea.style.cursor = 'move';
	var self = this;
	this.observers["mousedown"] = this.observe(this.dragArea, "mousedown", function(event) {
		if (self.isMoving) return;
		event = event || window.event;
		self.selectDisabled(event);
		self.mouseX = self.pointerX(event);
		self.mouseY = self.pointerY(event);
		self.isMoving = true;

	});
	this.observers["mousemove"] = this.observe(this.html, "mousemove", function(event){self.dragMove(event);});
	this.observers["mouseup"] = this.observe(this.html, "mouseup", function(event) {
		if (!self.isMoving) return;
		self.isMoving = false;
		self.selectEnabled();
	});

};

