
DatePicker = function()
{
	var self = arguments.callee;

	if( self.instance == null )
	{
		this.initialize.apply( this, arguments );
		self.instance = this;
	}

	return self.instance;
}

DatePicker.container_id = 'datepicker_container';

DatePicker.getAbsolutePosition = function( Obj )
{
	for( var sumTop=0,sumLeft=0;Obj!=document.body;sumTop+=Obj.offsetTop,sumLeft+=Obj.offsetLeft, Obj=Obj.offsetParent );
	return { left: sumLeft, top: sumTop }
}

DatePicker.prototype =
{
	initialize : function()
	{
		this.showing    = false;
		this.onselect   = null;
		this.current_id = null;

		document.getElementById( DatePicker.container_id ).onblur = function(){ DatePicker.instance.hide(); };

		var link_object = document.createElement( "link" );
		link_object.rel  = "stylesheet";
		link_object.href = DatePicker.path + 'css/datepicker.css';
		link_object.type = "text/css";
		document.getElementsByTagName( 'head' )[ 0 ].appendChild( link_object );
	},

	show : function( id )
	{
		this.current_id = id;
		this.showing    = true;

		var ObjCords = DatePicker.getAbsolutePosition( document.getElementById( id ) );

		document.getElementById( DatePicker.container_id ).style.left = ObjCords.left + 'px';
		document.getElementById( DatePicker.container_id ).style.top  = 1 + ObjCords.top  + document.getElementById( id ).offsetHeight + 'px';

		var cdate  = new Date();
		var cyear  = '';
		var cmonth = '';

		if( document.getElementById( id ).value != '' )
		{
			day = document.getElementById( id ).value.split( '/' );

			cyear  = day[ 0 ];
			cmonth = day[ 1 ];
		}

		if( (cyear == '') || isNaN(cyear) || (cmonth == '') || isNaN(cmonth) )
		{
			cyear  = cdate.getFullYear();
			cmonth = cdate.getMonth() + 1;
		}

		cyear  = parseInt( cyear  * 1 );
		cmonth = parseInt( cmonth * 1 );

		this.createDocument( cyear, cmonth );

		document.getElementById( DatePicker.container_id ).style.display = 'block';
		document.getElementById( DatePicker.container_id ).focus();
	},

	createDocument : function( cyear, cmonth )
	{
		var cheight_type = true;

		if( cmonth < 1 )
		{
			cyear -= 1;
			cmonth = 12;
		}
		else if( cmonth > 12 )
		{
			cyear += 1;
			cmonth = 1;
		}

		var csource = this.getCalendarSource
		(
			cyear,
			cmonth,
			cheight_type
		);

		document.getElementById( DatePicker.container_id ).innerHTML = csource;
	},

	hide : function( id )
	{
		if( this.showing == 1 )
		{
			document.getElementById( DatePicker.container_id ).blur();
			document.getElementById( DatePicker.container_id ).style.display = 'none';

			this.showing = false;

			document.onClick = null;
		}
	},

	select : function( fyear, fmonth, fday )
	{
		if( this.onselect != null )
		{
			this.onselect( this.current_id, fyear, fmonth + 1, fday );
		}
		else
		{
			document.getElementById( this.current_id ).value = fyear + '/' + parseInt( fmonth + 1 ) + '/' + fday;
		}

		this.hide();
	},

	cancel : function()
	{
		this.hide();
	},

	focusCell : function( col )
	{
		col._old_bgcolor          = col.style.backgroundColor;
		col.style.backgroundColor = '#ffeeaa';
		col.style.cursor = "hand";
	},

	blurCell : function( col )
	{
		col.style.backgroundColor = col._old_bgcolor;
		col.style.cursor = "pointer";
	},

	//-------------------------------------------
	// カレンダーソースの作成
	getCalendarSource : function
	(
		pyear,						// カレンダー表示年
		pmonth,						// カレンダー表示月
		pheight_type				// １ヶ月が６週間より短い月も６週間分の行を保つ（チェック）
	)
	{
		image_url = DatePicker.path + 'image/';

		fdate  = new Date();

		fnow_year  = fdate.getFullYear();
		fnow_month = fdate.getMonth();

		fyear  = pyear;
		fmonth = pmonth - 1;

		ftoday = fdate.getDate();

		// 日付設定の変更
		fdate.setFullYear( fyear );
		fdate.setDate( 1 );
		fdate.setMonth( fmonth );

		fweeks  = new Array( "日", "月", "火", "水", "木", "金", "土" );
		fmonths = new Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );

		if( ( ( fyear % 4 ) == 0 && ( fyear % 100 ) != 0 ) || ( fyear % 400 ) == 0 )
		{
			// 閏年処理
			fmonths[ 1 ] = 29;
		}

		fweek = fdate.getDay();
		fcals = new Array( 7 * 6 );

		// カレンダーの初期化
		for( i = 0; i < 7 * 6; i ++ )
		{
			fcals[ i ] = '　';
		}

		// 日付の設定
		for( i = 0; i < fmonths[ fmonth ]; i ++ )
		{
			fcals[ i + fweek ] = i + 1;
		}

		frow = ( fmonths[ fmonth ] + fweek ) / 7;
		frow = Math.ceil( frow );

		// カレンダーHTMLソースの作成
		var fsource = '';

		fsource += "<table unselectable='on' border='0' cellspacing='1' cellpadding='0' class='date_picker_obj'>";
		fsource += "<tr>";
		fsource += "<td unselectable='on' colspan='7' class='date_picker_header'>";
		fsource += "<table unselectable='on' border='0' cellspacing='0' cellpadding='0' class='date_picker_table'>";
		fsource += "<tr>";
		fsource += "<td unselectable='on' class='date_picker_button'>";
		fsource += "<!-- a href='JavaScript:DatePicker.instance.createDocument(" + ( pyear - 1 ) + "," + pmonth + ");'><img unselectable='on' src='" + image_url + "allow_left.gif' border='0'></a -->";
		fsource += "</td>";
		fsource += "<td unselectable='on' class='date_picker_button'>";
		fsource += "<a href='JavaScript:DatePicker.instance.createDocument(" + pyear + "," + ( pmonth - 1 ) + ");'><img unselectable='on' src='" + image_url + "allow_left.gif' border='0'></a>";
		fsource += "</td>";
		fsource += "<td unselectable='on' class='date_picker_main'>";
		fsource += fyear + "年" + ( fmonth + 1 ) + "月";
		fsource += "</td>";
		fsource += "<td unselectable='on' class='date_picker_button'>";
		fsource += "<a href='JavaScript:DatePicker.instance.createDocument(" + pyear + "," + ( pmonth + 1 ) + ");'><img unselectable='on' src='" + image_url + "allow_right.gif' border='0'></a>";
		fsource += "</td>";
		fsource += "<td unselectable='on' class='date_picker_button'>";
		fsource += "<!-- a href='JavaScript:DatePicker.instance.createDocument(" + ( pyear + 1 ) + "," + pmonth + ");'><img unselectable='on' src='" + image_url + "allow_right.gif' border='0'></a -->";
		fsource += "</td>";
		fsource += "</tr>";
		fsource += "</table>";
		fsource += "</td>";
		fsource += "</tr>";

		fsource += "<tr>";
		for( i = 0; i < 7; i ++ )
		{
			// 一行(１週間)ループ
			fsource += "<td unselectable='on' class='date_picker_week_base "

			if( i == 0 )
			{
				// 日曜のセルの色
				fsource += "date_picker_week_sunday'>";
			}
			else if( i == 6 )
			{
				// 土曜のセルの色
				fsource += "date_picker_week_saturday'>";
			}
			else
			{
				// 月～金のセルの色
				fsource += "date_picker_week_other'>";
			}

			fsource += fweeks[ i ];
			fsource += "</td>\n";
		}

		fsource += "</tr>\n";

		for( i = 0; i < frow; i ++ )
		{
			// 行ループ
			fsource += "<tr>\n";

			for( j = 0; j < 7; j ++ )
			{
				// 列ループ
				fsource += "<td unselectable='on' class='date_picker_day_base ";

				fvalue = fcals[ j + ( i * 7 ) ];

				if( fvalue == ftoday && fnow_year == fyear && fnow_month == fmonth )
				{
					// 今日のセルの色
					fsource += "date_picker_day_today'";
					fsource += ( fvalue != "　" ) ? ( " id='d_" + fvalue + "' onClick='JavaScript:DatePicker.instance.select(" + fyear + "," + fmonth + "," + fvalue + ");' onmouseover='DatePicker.instance.focusCell( this );' onmouseout='DatePicker.instance.blurCell( this );'" ) : "";
					fsource += ">";
					fsource += fvalue;
				}
				else if( j == 0 )
				{
					// 日曜のセルの色
					fsource += "date_picker_day_sunday'";
					fsource += ( fvalue != "　" ) ? ( " id='d_" + fvalue + "' onClick='JavaScript:DatePicker.instance.select(" + fyear + "," + fmonth + "," + fvalue + ");' onmouseover='DatePicker.instance.focusCell( this );' onmouseout='DatePicker.instance.blurCell( this );'" ) : "";
					fsource += ">";
					fsource += fvalue;
				}
				else if( j == 6 )
				{
					// 土曜のセルの色
					fsource += "date_picker_day_saturday'";
					fsource += ( fvalue != "　" ) ? ( " id='d_" + fvalue + "' onClick='JavaScript:DatePicker.instance.select(" + fyear + "," + fmonth + "," + fvalue + ");' onmouseover='DatePicker.instance.focusCell( this );' onmouseout='DatePicker.instance.blurCell( this );'" ) : "";
					fsource += ">";
					fsource += fvalue;
				}
				else
				{
					// 月～金のセルの色
					fsource += "date_picker_day_other'";
					fsource += ( fvalue != "　" ) ? ( " id='d_" + fvalue + "' onClick='JavaScript:DatePicker.instance.select(" + fyear + "," + fmonth + "," + fvalue + ");' onmouseover='DatePicker.instance.focusCell( this );' onmouseout='DatePicker.instance.blurCell( this );'" ) : "";
					fsource += ">";
					fsource += fvalue;
				}

				fsource += "</td>\n";
			}

			fsource += "</tr>\n";
		}

		if( pheight_type == true )
		{
			for( i = 0; i < 6 - frow; i ++ )
			{
				fsource += "<tr>\n";

				for( j = 0; j < 7; j ++ )
				{
					fsource += "<td unselectable='on' bgcolor='#FFFFFF' class='date_picker_day_base date_picker_day_other'\>&nbsp;</td>\n";
				}

				fsource += "</tr>\n";
			}
		}

		// firefoxのための閉じるボタン
		fsource += "<tr>\n";
		fsource += "<td unselectable='on' colspan=\"7\" class=\"date_picker_close\">\n";
		fsource += "<a href='javascript:DatePicker.instance.cancel();' class=\"date_picker_close_button\">閉じる</a>\n";
		fsource += "</td>\n";
		fsource += "</tr>\n";

		fsource += "</table>\n";

		return fsource;
	}
};

DatePicker.getInstance = function()
{
	if( DatePicker.instance == null )
	{
		new DatePicker();
	}

	return DatePicker.instance;
}

DatePicker.run = function()
{
	var div_object = document.createElement( "div" );
	div_object.id             = DatePicker.container_id;
	div_object.style.position = 'absolute';
	div_object.style.display  = 'none';
	div_object.style.zIndex   = '1';
	document.body.appendChild( div_object );

	f = 'datepicker.js';
	s = document.getElementsByTagName( 'script' );

	for( var i = 0, n = s.length; i < n; i ++ )
	{
		if( s[ i ].src.match( f ) )
		{
			DatePicker.path = s[i].src.replace( f, '' );
		}
	}

	t = document.getElementsByTagName( 'input' );

	for( var i = 0, n = t.length; i < n; i ++ )
	{
		if( t[ i ].className.match( 'datepicker' ) )
		{
			var	datepicker_id = t[ i ].id;

			var a_object = document.createElement( "a" );
			a_object.href             = '#';
			a_object.datepicker_id    = datepicker_id;
			a_object.style.marginLeft = '2px';
			a_object.onclick          = function()
			{
				DatePicker.instance.show( this.datepicker_id );
				return false;
			};

			var img_object = document.createElement( "img" );
			img_object.src = DatePicker.path + 'image/datepick.gif';
			img_object.style.border = 'none';

			t[ i ].parentNode.appendChild( a_object );
			a_object.appendChild( img_object );
		}
	}

	DatePicker.getInstance();
}

if( window.attachEvent )
{
	window.attachEvent( 'onload', DatePicker.run );
}
else
{
	window.addEventListener( 'DOMContentLoaded', DatePicker.run, false );
}
