
// 親クラス

if ( typeof(JKL) == 'undefined' ) JKL = function() {};

// JKL.Calendar コンストラクタの定義

JKL.Calendar = function ( eid, fid, valname ) {
    this.eid = eid;
    this.formid = fid;
    this.valname = valname;
    this.__dispelem = null;  // カレンダー表示欄エレメント
    this.__textelem = null;  // テキスト入力欄エレメント
    this.__opaciobj = null;  // JKL.Opacity オブジェクト
    this.style = new JKL.Calendar.Style();
    return this;
};

// バージョン番号

JKL.Calendar.VERSION = "0.13";

// デフォルトのプロパティ

JKL.Calendar.prototype.spliter = "/";
JKL.Calendar.prototype.date = null;
JKL.Calendar.prototype.min_date = null;
JKL.Calendar.prototype.max_date = null;

// JKL.Calendar.Style

JKL.Calendar.Style = function() {
    return this;
};

// デフォルトのスタイル

JKL.Calendar.Style.prototype.frame_width        = "200px";      // フレーム横幅
JKL.Calendar.Style.prototype.frame_color        = "#cccccc";    // フレーム枠の色
JKL.Calendar.Style.prototype.font_size          = "12px";       // 文字サイズ
JKL.Calendar.Style.prototype.month_bgcolor      = "#f1f1f1";    // ○年○月部分の背景色
JKL.Calendar.Style.prototype.week_bgcolor       = "#f1f1f1";    // 曜日の背景色
JKL.Calendar.Style.prototype.day_bgcolor        = "#ffffff";    // カレンダーの背景色
JKL.Calendar.Style.prototype.month_hover_color  = "#000000";    // マウスオーバー時の≪≫文字色
JKL.Calendar.Style.prototype.month_hover_bgcolor = "#FFFFCC";   // マウスオーバー時の≪≫背景色
JKL.Calendar.Style.prototype.month_color        = "#000000";    // ○年○月部分の文字色
JKL.Calendar.Style.prototype.weekday_color      = "#000000";    // 月曜～金曜日セルの文字色
JKL.Calendar.Style.prototype.saturday_color     = "#0000FF";    // 土曜日セルの文字色
JKL.Calendar.Style.prototype.sunday_color       = "#FF0000";    // 日曜日セルの文字色
JKL.Calendar.Style.prototype.others_color       = "#999999";    // 他の月の日セルの文字色
JKL.Calendar.Style.prototype.day_hover_bgcolor  = "#FF9933";    // マウスオーバー時の日セルの背景
JKL.Calendar.Style.prototype.cursor             = "pointer";    // マウスオーバー時のカーソル形状

//  メソッド

JKL.Calendar.Style.prototype.set = function(key,val) { this[key] = val; }
JKL.Calendar.Style.prototype.get = function(key) { return this[key]; }
JKL.Calendar.prototype.setStyle = function(key,val) { this.style.set(key,val); };
JKL.Calendar.prototype.getStyle = function(key) { return this.style.get(key); };

// 日付を初期化する

JKL.Calendar.prototype.initDate = function ( dd ) {
    if ( ! dd ) dd = new Date();
    var year = dd.getFullYear();
    var mon  = dd.getMonth();
    var date = dd.getDate();
    this.date = new Date( year, mon, date );
    this.getFormValue();
    return this.date;
}

// 透明度設定のオブジェクトを返す

JKL.Calendar.prototype.getOpacityObject = function () {
    if ( this.__opaciobj ) return this.__opaciobj;
    var cal = this.getCalendarElement();
    if ( ! JKL.Opacity ) return;
    this.__opaciobj = new JKL.Opacity( cal );
    return  this.__opaciobj;
};

// カレンダー表示欄のエレメントを返す

JKL.Calendar.prototype.getCalendarElement = function () {
    if ( this.__dispelem ) return this.__dispelem;
    this.__dispelem = document.getElementById( this.eid )
    return this.__dispelem;
};

// テキスト入力欄のエレメントを返す

JKL.Calendar.prototype.getFormElement = function () {
    if ( this.__textelem ) return this.__textelem;
    var frmelms = document.getElementById( this.formid );
    if ( ! frmelms ) return;
    for( var i=0; i < frmelms.elements.length; i++ ) {
        if ( frmelms.elements[i].name == this.valname ) {
            this.__textelem = frmelms.elements[i];
        }
    }
    return this.__textelem;
};

// オブジェクトに日付を記憶する（YYYY/MM/DD形式で指定する）

JKL.Calendar.prototype.setDateYMD = function (ymd) {
    var splt = ymd.split( this.spliter );
    if ( splt[0]-0 > 0 &&
         splt[1]-0 >= 1 && splt[1]-0 <= 12 &&       // bug fix 2006/03/03 thanks to ucb
         splt[2]-0 >= 1 && splt[2]-0 <= 31 ) {
        if ( ! this.date ) this.initDate();
        this.date.setFullYear( splt[0] );
        this.date.setMonth( splt[1]-1 );
        this.date.setDate( splt[2] );
    } else {
        ymd = "";
    }
    return ymd;
};

// オブジェクトから日付を取り出す（YYYY/MM/DD形式で返る）
// 引数に Date オブジェクトの指定があれば、
// オブジェクトは無視して、引数の日付を使用する（単なるfprint機能）

JKL.Calendar.prototype.getDateYMD = function ( dd ) {
    if ( ! dd ) {
        if ( ! this.date ) this.initDate();
        dd = this.date;
    }
    var mm = "" + (dd.getMonth()+1);
    var aa = "" + dd.getDate();
    if ( mm.length == 1 ) mm = "" + "0" + mm;
    if ( aa.length == 1 ) aa = "" + "0" + aa;
    return dd.getFullYear() + this.spliter + mm + this.spliter + aa;
};

// テキスト入力欄の値を返す（ついでにオブジェクトも更新する）

JKL.Calendar.prototype.getFormValue = function () {
    var form1 = this.getFormElement();
    if ( ! form1 ) return "";
    var date1 = this.setDateYMD( form1.value );
    return date1;
};

// ■日付選択値の表示
//JKL.Calendar.prototype.setSelectDate = function (ymd) {
//    var selectDate = document.getElementById( "__"+this.eid+"_selectDate" );
//	selectDate.innerHTML = ymd;
//	alert(selectDate);
//};
// ■値の書き込み
//JKL.Calendar.prototype.setFormValue2 = function () {
//    var ymd = document.getElementById( "__"+this.eid+"_selectDate" ).innerHTML;
//    if ( ! ymd ) ymd = this.getDateYMD();
//
//    var hh  = document.getElementById( "__"+this.eid+"_hh" ).value;
//    var mm  = document.getElementById( "__"+this.eid+"_mm" ).value;
//
//	var ymdhhmm = ymd + " " + hh + ":" + mm;
//    var form1 = this.getFormElement();
//    if ( form1 ) form1.value = ymdhhmm;
//};

// フォーム入力欄に指定した値を書き込む

JKL.Calendar.prototype.setFormValue = function (ymd) {
    if ( ! ymd ) ymd = this.getDateYMD();   // 無指定時はオブジェクトから？
    var form1 = this.getFormElement();
    if ( form1 ) form1.value = ymd;
};

//  カレンダー表示欄を表示する

JKL.Calendar.prototype.show = function () {
    this.getCalendarElement().style.display = "";
};

//  カレンダー表示欄を即座に隠す

JKL.Calendar.prototype.hide = function () {
    this.getCalendarElement().style.display = "none";
};

//  カレンダー表示欄をフェードアウトする

JKL.Calendar.prototype.fadeOut = function (s) {
    if ( JKL.Opacity ) {
        this.getOpacityObject().fadeOut(s);
    } else {
        this.hide();
    }
};

// 月単位で移動する

JKL.Calendar.prototype.moveMonth = function ( mon ) {
    // 前へ移動
    if ( ! this.date ) this.initDate();
    for( ; mon<0; mon++ ) {
        this.date.setDate(1);   // 毎月1日の1日前は必ず前の月
        this.date.setTime( this.date.getTime() - (24*3600*1000) );
    }
    // 後へ移動
    for( ; mon>0; mon-- ) {
        this.date.setDate(1);   // 毎月1日の32日後は必ず次の月
        this.date.setTime( this.date.getTime() + (24*3600*1000)*32 );
    }
    this.date.setDate(1);       // 当月の1日に戻す
    this.write();    // 描画する
};

// イベントを登録する

JKL.Calendar.prototype.addEvent = function ( elem, ev, func ) {
//  prototype.js があれば利用する(IEメモリリーク回避)
    if ( window.Event && Event.observe ) {
        Event.observe( elem, ev, func, false );
    } else {
        elem["on"+ev] = func;
    }
}

// カレンダーを描画する

JKL.Calendar.prototype.write = function () {
    var date = new Date();
    if ( ! this.date ) this.initDate();
    date.setTime( this.date.getTime() );

    var year = date.getFullYear();          // 指定年
    var mon  = date.getMonth();             // 指定月
    var today = date.getDate();             // 指定日
    var form1 = this.getFormElement();

    // 選択可能な日付範囲
    var min;
    if ( this.min_date ) {
        var tmp = new Date( this.min_date.getFullYear(), 
            this.min_date.getMonth(), this.min_date.getDate() );
        min = tmp.getTime();
    }
    var max;
    if ( this.max_date ) {
        var tmp = new Date( this.max_date.getFullYear(), 
            this.max_date.getMonth(), this.max_date.getDate() );
        max = tmp.getTime();
    }

    // 直前の日曜日まで戻す
    date.setDate(1);                        // 1日に戻す
    var wday = date.getDay();               // 曜日 日曜(0)～土曜(6)
    if ( wday != 0 ) {
        date.setTime( date.getTime() - (24*3600*1000)*wday );
    }

    // 最大で7日×6週間＝42日分のループ
    var list = new Array();
    for( var i=0; i<42; i++ ) {
        var tmp = new Date();
        tmp.setTime( date.getTime() + (24*3600*1000)*i );
        if ( i && i%7==0 && tmp.getMonth() != mon ) break;
        list[list.length] = tmp;
    }

    // スタイルシートを生成する
    var month_table_style = 'width: 100%; ';
    month_table_style += 'background: '+this.style.frame_color+'; ';
    month_table_style += 'border: 1px solid '+this.style.frame_color+'; ';
    month_table_style += 'margin: 0; padding: 0; ';

    var week_table_style = 'width: 100%; ';
    week_table_style += 'background: '+this.style.week_bgcolor+'; ';
    week_table_style += 'border: 1px solid '+this.style.frame_color+'; ';
    week_table_style += 'margin: 0; padding: 0; ';

    var days_table_style = 'width: 100%; ';
    days_table_style += 'background: '+this.style.day_bgcolor+'; ';
    days_table_style += 'border: 1px solid '+this.style.frame_color+'; ';
    days_table_style += 'margin: 0; padding: 0; ';

    var month_td_style = "";
    month_td_style += 'font-size: '+this.style.font_size+'; ';
    month_td_style += 'color: '+this.style.month_color+'; ';
    month_td_style += 'padding: 1px; ';
    month_td_style += 'text-align: center; ';
    month_td_style += 'font-weight: bold; ';
    month_td_style += 'margin: 0; ';

    var week_td_style = "";
    week_td_style += 'font-size: '+this.style.font_size+'; ';
    week_td_style += 'padding: 1px; ';
    week_td_style += 'font-weight: bold;';
    week_td_style += 'text-align: center; ';
    week_td_style += 'margin: 0; ';

    var days_td_style = "";
    days_td_style += 'font-size: '+this.style.font_size+'; ';
    days_td_style += 'padding: 1px; ';
    days_td_style += 'text-align: center; ';
    days_td_style += 'font-weight: bold; ';
    days_td_style += 'margin: 0; ';

    var days_unselectable = "font-weight: normal; ";

    // HTMLソースを生成する
    var src1 = "";

    src1 += '<table border="0" cellpadding="0" cellspacing="0" style="'+month_table_style+'"><tr>';
    src1 += '<td style="'+month_td_style+'">&nbsp;</td>';
    src1 += '<td style="'+month_td_style+'">日付を選択してください</td>';
    src1 += '<td id="__'+this.eid+'_btn_close" title="閉じる" style="'+month_td_style+'">×</td>';
//    src1 += "</tr></table>\n";
//    src1 += '<table border="0" cellpadding="0" cellspacing="0" style="'+month_table_style+'"><tr>';
    src1 += "</tr>\n";
    src1 += "<tr>";
    src1 += '<td id="__'+this.eid+'_btn_prev" title="前の月へ" style="'+month_td_style+'">≪</td>';
    src1 += '<td style="'+month_td_style+'background: '+this.style.month_bgcolor+';">'+(year)+'年 '+(mon+1)+'月</td>';
    src1 += '<td id="__'+this.eid+'_btn_next" title="次の月へ" style="'+month_td_style+'">≫</td>';
    src1 += "</tr></table>\n";
    src1 += '<table border="0" cellpadding="0" cellspacing="0" style="'+week_table_style+'"><tr>';
    src1 += '<td style="color: '+this.style.sunday_color+'; '+week_td_style+'">日</td>';
    src1 += '<td style="color: '+this.style.weekday_color+'; '+week_td_style+'">月</td>';
    src1 += '<td style="color: '+this.style.weekday_color+'; '+week_td_style+'">火</td>';
    src1 += '<td style="color: '+this.style.weekday_color+'; '+week_td_style+'">水</td>';
    src1 += '<td style="color: '+this.style.weekday_color+'; '+week_td_style+'">木</td>';
    src1 += '<td style="color: '+this.style.weekday_color+'; '+week_td_style+'">金</td>';
    src1 += '<td style="color: '+this.style.saturday_color+'; '+week_td_style+'">土</td>';
    src1 += "</tr></table>\n";
    src1 += '<table border="0" cellpadding="0" cellspacing="0" style="'+days_table_style+'">';

    var curutc;
    if ( form1 && form1.value ) {
        var splt = form1.value.split(this.spliter);
        if ( splt[0] > 0 && splt[2] > 0 ) {
            var curdd = new Date( splt[0]-0, splt[1]-1, splt[2]-0 );
            curutc = curdd.getTime();                           // フォーム上の当日
        }
    }

    for ( var i=0; i<list.length; i++ ) {
        var dd = list[i];
        var ww = dd.getDay();
        var mm = dd.getMonth();
        if ( ww == 0 ) {
            src1 += "<tr>";                                     // 日曜日の前に行頭
        }
        var cc = days_td_style;
        if ( mon == mm ) {
            if ( ww == 0 ) {
                cc += "color: "+this.style.sunday_color+";";    // 当月の日曜日
            } else if ( ww == 6 ) {
                cc += "color: "+this.style.saturday_color+";";  // 当月の土曜日
            } else {
                cc += "color: "+this.style.weekday_color+";";   // 当月の平日
            }
        } else {
            cc += "color: "+this.style.others_color+";";        // 前月末と翌月初の日付
        }
        var utc = dd.getTime();
        if (( min && min > utc ) || ( max && max < utc )) {
            cc += days_unselectable;
        }
        if ( utc == curutc ) {                                  // フォーム上の当日
            cc += "background: "+this.style.day_hover_bgcolor+";";
        }

        var ss = this.getDateYMD(dd);
        var tt = dd.getDate();
        src1 += '<td style="'+cc+'" title='+ss+' id="__'+this.eid+'_td_'+ss+'">'+tt+'</td>';
        if ( ww == 6 ) {
            src1 += "</tr>\n";                                  // 土曜日の後に行末
        }
    }
    src1 += "</table>\n";


	// ■デフォルト表示値の設定
	var $selected_date = form1.value.substr(0,10);
	var $selected_hh = form1.value.substr(11,2);
	var $selected_mm = form1.value.substr(14,2);

	if ($selected_hh=="") {
		$selected_hh = "00";
	}
	if ($selected_mm=="") {
		$selected_mm = "00";
	}
//alert($selected_date + "," + $selected_hh + "," + $selected_mm);

//	// ■選択日付、時刻選択の表示
//    src1 += '<table border="0" cellpadding="0" cellspacing="0" style="'+days_table_style+'">';
//    src1 += "<tr>\n";
//    src1 += '<td style="font-size:8pt;padding-top:3px;">日付：</td>';
//    src1 += '<td colspan="3" style="font-size:10pt; font-weight:bold;"><span id="__'+this.eid+'_selectDate">' + form1.value.substr(0,10) +'</span></td>';
//    src1 += "</tr>\n";
//    src1 += "<tr>\n";
//    src1 += '<td style="font-size:8pt;">時刻：</td>';
//    src1 += '<td style="font-size:9pt;">';
//    src1 += '<select id="__'+this.eid+'_hh">';
//    for ($h=0; $h<24; $h++) {
//		if ((('0' + $h).slice(-2)) == $selected_hh) {
//	        src1 += '<option value="' + (('0' + $h).slice(-2)) + '" selected>' + (('0' + $h).slice(-2)) + '</option>';
//		} else {
//	        src1 += '<option value="' + (('0' + $h).slice(-2)) + '">' + (('0' + $h).slice(-2)) + '</option>';
//		}
//    }
//    src1 += '</select>';
//    src1 += '</td>';
//    src1 += '<td style="font-size:9pt;">';
//    src1 += '<select id="__'+this.eid+'_mm">';
//    for ($m=0; $m<60; $m+=30) {
//		if ((('0' + $m).slice(-2)) == $selected_mm) {
//	        src1 += '<option value="' + (('0' + $m).slice(-2)) + '" selected>' + (('0' + $m).slice(-2)) + '</option>';
//		} else {
//	        src1 += '<option value="' + (('0' + $m).slice(-2)) + '">' + (('0' + $m).slice(-2)) + '</option>';
//		}
//    }
//    src1 += '</select>';
//    src1 += '</td>';
//    src1 += '<td style="font-size:9pt;"><input type="button" id="__'+this.eid+'_btn_ok" value="OK"></td>';
//    src1 += "</tr>\n";
//    src1 += "</table>\n";

    // カレンダーを書き換える
    var cal1 = this.getCalendarElement();
    if ( ! cal1 ) return;
    cal1.style.width = this.style.frame_width;
    cal1.style.position = "absolute";

    // カレンダの表示位置を求める（入力ボックスの下）
    wkEl = this.getFormElement();
    var x = 0;
    var y = wkEl.offsetHeight;
    while(wkEl) {
      x += wkEl.offsetLeft;
      y += wkEl.offsetTop
      wkEl = wkEl.offsetParent;
    }
    // カレンダの表示位置を設定
    cal1.style.left = x + "px";
    cal1.style.top = y + "px";

    cal1.innerHTML = src1;

    // イベントを登録する
    var __this = this;
    var get_src = function (ev) {
        ev  = ev || window.event;
        var src = ev.target || ev.srcElement;
        return src;
    };
    var month_onmouseover = function (ev) {
        var src = get_src(ev);
        src.style.color = __this.style.month_hover_color;
        src.style.background = __this.style.month_hover_bgcolor;
    };
    var month_onmouseout = function (ev) {
        var src = get_src(ev);
        src.style.color = __this.style.month_color;
        src.style.background = __this.style.frame_color;
    };
    var day_onmouseover = function (ev) {
        var src = get_src(ev);
        src.style.background = __this.style.day_hover_bgcolor;
    };
    var day_onmouseout = function (ev) {
        var src = get_src(ev);
        src.style.background = __this.style.day_bgcolor;
    };
    var day_onclick = function (ev) {
        var src = get_src(ev);
        var srcday = src.id.substr(src.id.length-10);
        __this.setFormValue( srcday );
        __this.fadeOut( 1.0 );
//		// ■選択日付の表示
//        __this.setSelectDate( srcday );
    };

    var table_onmouseout = function () {
        var src = document.getElementById(__this.eid);
        if (!src.contains(event.toElement)) {
            __this.hide();
        }
    };

//	// ■OKボタン押下時の処理
//    var ok_onclick = function (ev) {
//        __this.setFormValue2();
//        __this.fadeOut( 1.0 );
//    };

    // 前の月へボタン
    var tdprev = document.getElementById( "__"+this.eid+"_btn_prev" );
    tdprev.style.cursor = this.style.cursor;
    this.addEvent( tdprev, "mouseover", month_onmouseover );
    this.addEvent( tdprev, "mouseout", month_onmouseout );
    this.addEvent( tdprev, "click", function(){ __this.moveMonth( -1 ); });

    // 閉じるボタン
    var tdclose = document.getElementById( "__"+this.eid+"_btn_close" );
    tdclose.style.cursor = this.style.cursor;
    this.addEvent( tdclose, "mouseover", month_onmouseover );
    this.addEvent( tdclose, "mouseout", month_onmouseout );
    this.addEvent( tdclose, "click", function(){ __this.hide(); });

    // 次の月へボタン
    var tdnext = document.getElementById( "__"+this.eid+"_btn_next" );
    tdnext.style.cursor = this.style.cursor;
    this.addEvent( tdnext, "mouseover", month_onmouseover );
    this.addEvent( tdnext, "mouseout", month_onmouseout );
    this.addEvent( tdnext, "click", function(){ __this.moveMonth( +1 ); });

//    // マウスが外れたらカレンダを消す
//    var caltbl = document.getElementById( this.eid );
//    this.addEvent( caltbl, "mouseout", table_onmouseout );

//    // OKボタン
//    var tdOK = document.getElementById( "__"+this.eid+"_btn_ok" );
//    tdOK.style.cursor = this.style.cursor;
//    this.addEvent( tdOK, "click", ok_onclick );

    // セルごとのイベントを登録する
    for ( var i=0; i<list.length; i++ ) {
        var dd = list[i];
        if ( mon != dd.getMonth() ) continue;       // 今月のセルにのみ設定する

        var utc = dd.getTime();
        if ( min && min > utc ) continue;           // 昔過ぎる
        if ( max && max < utc ) continue;           // 未来過ぎる
        if ( utc == curutc ) continue;              // フォーム上の当日

        var ss = this.getDateYMD(dd);
        var cc = document.getElementById( "__"+this.eid+"_td_"+ss );
        if ( ! cc ) continue;

        cc.style.cursor = this.style.cursor;
//        this.addEvent( cc, "mouseover", day_onmouseover );
//        this.addEvent( cc, "mouseout", day_onmouseout );
        this.addEvent( cc, "click", day_onclick );
    }

    // 表示する
    this.show();
};

// 旧バージョン互換（typo）
JKL.Calendar.prototype.getCalenderElement = JKL.Calendar.prototype.getCalendarElement;
JKL.Calender = JKL.Calendar;


// ＡＳＣＩＩ文字列かをチェックする
function chkAscii(targetVal) {
	var tempChar;
	var i;
	for(i = 0; i < targetVal.length; i++) {
		tempChar = targetVal.charCodeAt(i);
		if (tempChar < 0 || tempChar > 255) {
			return false;
		}
	}
	return true;
}

// 日付フォーマットをチェックする
function chkRegexpDate(strValue){
	var seiki=/^\d{4}\/\d(\d)?\/\d(\d)?$/;
	if(strValue.match(seiki)){
		return true;
	}else{
		return false;
	}
}

// 日付をチェックする
function chkDate(strYear, strMonth, strDay) {
	var intYear;
	var intMonth;
	var intDay;

	intYear = parseInt(strYear, 10);
	intMonth = parseInt(strMonth, 10);
	intDay = parseInt(strDay, 10);

	if(intMonth < 1 || intMonth > 12) {
		return false;
	}
	if(intDay < 1 || intDay > getLastDay(intYear, intMonth)) {
		return false;
	}
	return true;
}

// 月末日を取得する
function getLastDay(intYear, intMonth) {
	var lastDay;
	lastDay = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	if (intMonth == 2) {
		return isLeapYear(intYear) ? 29 : 28;
	}
	return lastDay[intMonth-1];
} 

// うるう年かをチェックする
function isLeapYear(intYear) {
	if((intYear % 4) == 0 && ((intYear % 100) != 0 || (intYear % 400) == 0)) {
		return true;
	}
	return false;
}

// yyyy/mm/ddをyyyymmddにする
	function jsfChgDate(dateval) {
		var dy = new Date(dateval);

		if (isNaN(dy)){
			return false;
		}
		var yyyy = String(dy.getYear());
		var mm = String(dy.getMonth()+1);
		if (mm.length == 1)  mm = "" + "0" + mm;
		var dd = String(dy.getDate());
		if (dd.length == 1)  dd = "" + "0" + dd;
		var ret = "" + yyyy + mm + dd;

		return ret;
	}

// 前後の空白を除く
function Trim(strOrg) {
	return strOrg.replace(/^[ ]+|[ ]+$/g, '');
}

