/**********************************************************************************
 * 
 * LastChangedDate:		$Date: 2007-01-12 08:06:05 +0100 (Fri, 12 Jan 2007) $
 * LastChangedRevision	$Rev: 33 $
 * LastChangedBy:		$Author: $
 * HeadURL:				$URL: http://linux/cd/balance/trunk/httpdocs/js/nl/xd/form/calendar.js $
 * ID:					$Id: calendar.js 33 2007-01-12 07:06:05Z  $
 * 
/**********************************************************************************/

nl.xd.form.Calendar = function( root , name , date , tabindex ) {
	this.name = name ;
	this.date = date ;
	this.tabindex = tabindex ;
	
	if ( date == '0000-00-00' ) {
		date = null ;
	} ;
	
	this.currentDate = new nl.xd.util.Date( new Date() ) ;
	this.displayDate = new nl.xd.util.Date( date || new Date() ) ;
	this.selectedDate = new nl.xd.util.Date( date ) ;
	
	this.months = new Array( 'Januari' , 'Februari' , 'Maart' , 'April' , 'Mei' , 'Juni' , 'Juli' , 'Augustus' , 'September' , 'Oktober' , 'November' , 'December' ) ;
	this.container = nl.xd.util.DOM.get( root ) ;
	
	this.calendar = null ;
	this.input = null ;
	
	this.grid() ;
	this.initialize() ;
} ;

nl.xd.form.Calendar.prototype.render = function() {
	var startDay = new Date( this.displayDate.year , this.displayDate.month , 1 ) ;
	var endDay = new Date( this.displayDate.year , this.displayDate.month + 1 , 1 ) ;
	var numberOfDays = Math.round( ( endDay - startDay ) / 1000 / 60 / 60 / 24 ) ;
	var dateCounter = 1 ;
	var counter = 0 ;
	var day ;
	var a ;
	
	for ( var row = 0; row <= 5; row++ ) {
		for ( var col = 0; col <= 6; col++ ) {
			day = nl.xd.util.DOM.get( 'calendar_day_' + row + '_' + col + '_' + this.name ) ;
			day.innerHTML = '' ;						
			
			if ( ( counter >= startDay.getDay() ) && ( counter <= ( numberOfDays + ( startDay.getDay() - 1 ) ) ) ) {
				a = document.createElement( 'a' ) ;
				a[ 'href' ] = 'javascript:void(null);' ;
				a.innerHTML = dateCounter ;
				a.calendar = this ;
				a.day = dateCounter ;
				a.onclick = function() {
					this.calendar.select( this.day ) ;
				} ;
				
				if ( ( this.selectedDate.year == this.displayDate.year ) && ( this.selectedDate.month == this.displayDate.month ) && ( this.selectedDate.day == dateCounter ) ) {
					nl.xd.util.DOM.addClass( a , 'selected' ) ;
				} ;
				if ( ( this.currentDate.year == this.displayDate.year ) && ( this.currentDate.month == this.displayDate.month ) && ( this.currentDate.day == dateCounter ) ) {
					nl.xd.util.DOM.addClass( a , 'current' ) ;
				} ;
				
				day.appendChild( a ) ;
				
				dateCounter++;
			} ;
			
			counter++ ;
		} ;
	};
	
	var monthSelect = nl.xd.util.DOM.get( 'calendar_months_' + this.name ) ;
	monthSelect.selectedIndex = this.displayDate.month ;
	
	var yearSelect = nl.xd.util.DOM.get( 'calendar_years_' + this.name ) ;
	yearSelect.selectedIndex = this.displayDate.year - 1900 ;
	
	var firstDayOfTheYear = new Date( this.displayDate.year , 0 , 1 ) ; 
	var totalDays = firstDayOfTheYear.getDay() ;
	
	for ( var i = 0 ; i < this.displayDate.month ; i++ ) {
		var startDay = new Date( this.displayDate.year , i , 1 ) ;
		var endDay = new Date( this.displayDate.year , i + 1 , 1 ) ;
		totalDays += ( endDay - startDay ) / 1000 / 60 / 60 / 24 ;
	} ;
	
	var weekNumber = Math.floor( totalDays / 7 ) + 1 ;
	var day ;
	var week ;
	
	for ( var i = 0 ; i <= 5 ; i++ ) {
		day = nl.xd.util.DOM.get( 'calendar_day_' + i + '_0_' + this.name ) ;
		week = nl.xd.util.DOM.get( 'calendar_week_' + i + '_' + this.name ) ;
		
		if ( ( day.innerHTML != '' ) || ( i == 0 ) ) {
			if ( weekNumber > 52 ) {
				weekNumber = 1 ;
			} ;
			
			week.innerHTML = weekNumber++ ;
		} else {
			week.innerHTML = '' ;
		} ;
	} ;
} ;

nl.xd.form.Calendar.prototype.grid = function() {
	var html = '' ;
	
	html += '<div class="calendar none" id="calendar_' + this.name + '">' ;
	
	// top
	html += '<div class="calendar_close" id="calendar_close_' + this.name + '"></div>' ;
	
	// navigation
	html += '<table cellpadding="0" cellspacing="0" class="calendar_navigation">' ;
	html == '<tr>' ;
	html += '<td class="calendar_previous" id="calendar_previous_' + this.name + '"></td>' ;
	html += '<td class="calendar_month" id="calendar_month_' + this.name + '"></td>' ;
	html += '<td class="calendar_year" id="calendar_year_' + this.name + '"></td>' ;
	html += '<td class="calendar_next" id="calendar_next_' + this.name + '"></td>' ;
	html += '</tr>' ;
	html += '</table>' ;
	
	// weekdays
	html += '<table cellpadding="0" cellspacing="0" class="calendar_weeks">' ;
	html += '<tr class="calendar_weekdays">' ;
	html += '<td></td>' ;
	html += '<td class="calendar_day">Z</td>' ;
	html += '<td class="calendar_day">M</td>' ;
	html += '<td class="calendar_day">D</td>' ;
	html += '<td class="calendar_day">W</td>' ;
	html += '<td class="calendar_day">D</td>' ;
	html += '<td class="calendar_day">V</td>' ;
	html += '<td class="calendar_day">Z</td>' ;
	html += '</tr>' ;
	
	for ( i = 0; i <= 5; i++ ) {
		html += '<tr class="calendar_week">' ;
		html += '<td class="calendar_number" id="calendar_week_' + i + '_' + this.name + '"></td>' ;
		
		for ( j = 0; j <= 6 ; j++ ) {
			html += '<td class="calendar_day" id="calendar_day_' + i + '_' + j + '_' + this.name + '"></td>' ;
		} ;
		
		html += '</tr> ' ;
	} ;

	html += '</table>' ;
	html += '</div>' ;
	
	this.container.innerHTML = html ;
} ;

nl.xd.form.Calendar.prototype.initialize = function() {
	this.calendar = nl.xd.util.DOM.get( 'calendar_' + this.name ) ;
	
	var close = nl.xd.util.DOM.get( 'calendar_close_' + this.name ) ;
	var a = document.createElement( 'a' ) ;
	a[ 'href' ] = 'javascript:void(null);' ;
	a.innerHTML = 'X' ;
	a.calendar = this ;
	a.onclick = function() {
		this.calendar.hide() ;
	} ;
	close.appendChild( a ) ;
	
	var previous = nl.xd.util.DOM.get( 'calendar_previous_' + this.name ) ;
	var a = document.createElement( 'a' ) ;
	a[ 'href' ] = 'javascript:void(null);' ;
	a.innerHTML = '&lt;' ;
	a.calendar = this ;
	a.onclick = function() {
		this.calendar.previous() ;
	} ;
	previous.appendChild( a ) ;
	
	var next = nl.xd.util.DOM.get( 'calendar_next_' + this.name ) ;
	var a = document.createElement( 'a' ) ;
	a[ 'href' ] = 'javascript:void(null);' ;
	a.innerHTML = '&gt;' ;
	a.calendar = this ;
	a.onclick = function() {
		this.calendar.next() ;
	} ;
	next.appendChild( a ) ;
	
	var option ;
	var select = document.createElement( 'select' ) ;
	select.id = 'calendar_months_' + this.name ;
	select.calendar = this ;
	select.onchange = function() {
		this.calendar.gotoDate( 'month' , parseInt( this.options[ this.selectedIndex ].value ) ) ;
	} ;
	
	for ( var i = 0; i < this.months.length; i++ ) {
		option = document.createElement( 'option' ) ;
		option.innerHTML = this.months[ i ] ;
		option.value = i ;
		select.appendChild( option ) ;
	} ;
	
	var month = nl.xd.util.DOM.get( 'calendar_month_' + this.name ) ;
	month.appendChild( select ) ;
	
	var select = document.createElement( 'select' ) ;
	select.id = 'calendar_years_' + this.name ;
	select.calendar = this ;
	select.onchange = function() {
		this.calendar.gotoDate( 'year' , parseInt( this.options[ this.selectedIndex ].value ) ) ;
	} ;
	
	for ( var i = 1900; i < 2100; i++ ) {
		option = document.createElement( 'option' ) ;
		option.innerHTML = i ;
		option.value = i ;
		select.appendChild( option ) ;
	} ;
	
	var year = nl.xd.util.DOM.get( 'calendar_year_' + this.name ) ;
	year.appendChild( select ) ;
	
	this.input = document.createElement( 'input' ) ;
	this.input.type = 'text' ;
	this.input.name = this.name ;
	this.input.id = this.name ;
	this.input.className = 'formtext' ;
	this.input.value = this.selectedDate.toString() ;
	this.input.calendar = this ;
	
	this.input.onfocus = function() {
		this.calendar.show() ;
	} ;
	
	this.container.appendChild( this.input ) ;
} ;

nl.xd.form.Calendar.prototype.gotoDate = function( type , value ) {
	if ( type == 'month' ) {
		this.displayDate.month = value ;
	} else {
		this.displayDate.year = value ;
	} ;
	
	this.render() ;
} ;

nl.xd.form.Calendar.prototype.hide = function() {
	nl.xd.util.DOM.addClass( this.calendar , 'none' ) ;
	this.input.style[ 'visibility' ] = 'visible' ;
} ;

nl.xd.form.Calendar.prototype.show = function() {
	this.render() ;
	
	this.input.style[ 'visibility' ] = 'hidden' ;
	nl.xd.util.DOM.removeClass( this.calendar , 'none' ) ;
} ;

nl.xd.form.Calendar.prototype.select = function( day ) {
	this.selectedDate = new nl.xd.util.Date( new Date( this.displayDate.year , this.displayDate.month , day ) ) ;
	this.input.value = this.selectedDate.toString() ;
	
	this.hide() ;
} ;

nl.xd.form.Calendar.prototype.next = function() {
	if ( this.displayDate.month < 11 ) {
		this.displayDate.month++ ;
	} else {
		this.displayDate.month = 0 ;
		this.displayDate.year++ ;
	} ;
	
	this.render() ;
} ;

nl.xd.form.Calendar.prototype.previous = function() {
	if ( this.displayDate.month > 0 ) {
		this.displayDate.month-- ;
	} else {
		this.displayDate.month = 11 ;
		this.displayDate.year-- ;
	} ;
	
	this.render() ;
} ;

/**
 * Date Class
 */
nl.xd.util.Date = function( date , format ) {
	this.day = null ;
	this.month = null ;
	this.year = null ;
	
	this.format = format || new Array( 'd' , 'm' , 'y' ) ;
	
	this.initialize( date ) ;
} ;
nl.xd.util.Date.prototype.initialize = function( date ) {
	if ( typeof date == 'string' ) {
		date = this.stringToDate( date ) ;
		
		if ( date != null ) {
			this.day = date.getDate() ;
			this.month = date.getMonth() ;
			this.year = date.getFullYear() ;
		} ;
	} else if ( date != null && typeof date == 'object' ) {
		// It's date
		this.day = date.getDate() ;
		this.month = date.getMonth() ;
		this.year = date.getFullYear() ;
	} ;
} ;
nl.xd.util.Date.prototype.toString = function() {
	var string = '' ;
	
	if ( ! ( ( this.year == null ) || ( this.month == null ) || ( this.day == null ) ) ) {
		for ( var i = 0; i < this.format.length; i++ ) {
			if ( string != '' ) {
				string += '-' ;
			} ;
			
			switch ( this.format[ i ] ) {
				case 'y' :
					string += this.year ;
					
					break ;
				case 'm' :
					string += ( this.month + 1 ) ;
					
					break ;
				case 'd' :
					string += this.day ;
					
					break ;
			} ;
		} ;
	} ;
	
	return string ;
} ;
nl.xd.util.Date.prototype.stringToDate = function( date ) {
	var items = date.split( '-' ) ;
	var y = null ;
	var m = null ;
	var d = null ;
	
	if ( items.length != 3 ) {
		return null ;
	} ;
	
	for ( var i = 0; i < this.format.length; i++ ) {
		switch ( this.format[ i ] ) {
			case 'y':
				if ( this.isValidYear( items[ i ] ) ) {
					y = items[ i ] ;
				} ;
				break ;
			case 'm':
				if ( this.isValidMonth( items[ i ] ) ) {
					m = ( items[ i ] - 1 ) ;
				} ;
				break ;
			case 'd':
				if ( this.isValidDay( items[ i ] ) ) {
					d = items[ i ] ;
				} ;
				break ;
		} ;
	} ;
	
	if ( y != null && m != null && d != null ) {
		return new Date( y , m , d ) ;
	} else {
		return null ;
	} ;
} ;
nl.xd.util.Date.prototype.isValidYear = function( year ) {
	if ( year < 2100 && year > 1900 ) {
		return true ;
	} ;
	
	return false ;
} ;
nl.xd.util.Date.prototype.isValidMonth = function( month ) {
	if ( month <= 12 && month >= 1 ) {
		return true ;
	} ;
	
	return false ;
} ;
nl.xd.util.Date.prototype.isValidDay = function( day ) {
	if ( day <= 31 && day >= 1 ) {
		return true ;
	} ;
	
	return false ;
} ;