/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			Begin jsCalendar Class
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

function jsCalendar()
{

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				Initialize Calendar Control
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    if (typeof(_calendar_prototype_called) == 'undefined')
    {
        _calendar_prototype_called = true;
        
        // Object methods
        this.BuildCalendar = _create;
        this.createCanvass = _createCanvass;
        this.showCalendar = _showCalendar;
        this.toggleCalendar = _toggleCalendar;
        this.moveTo = _positionCanvass;
        this.hide = _hide;
        this.show = _show;
        this.init = _init;
        this.GetDay = _getDayString;
        
        // Object properties
        this.name = 'default';
        this.currentDay = 0;
        this.currentMonth = 0;
        this.currentYear = 0;
        this.visible = false;
        this.posX = 10;
        this.posY = 10;
        this.isIE4 = new Boolean;
        this.isNav4 = new Boolean;
		this.isGecko = new Boolean;
		this.isMac = new Boolean;
        
        this.canvass = new Object;           // The DIV || LAYER that we display the calendar on.
        this.bindToElement = new Object;     // Bind to an ELEMENT on the page.
        
        // Array of day names
        this.days = new Array("Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday");
        // Array of month names
        this.months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
        // Array of total days in each month
        this.totalDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		
        // Call the Initialize() event.
        this.init();
    }
}


// Called on initialization of the Class
function _init()
{
    if ( parseInt( navigator.appVersion.charAt(0) ) >= 4 )
    // Browser check.
    {
		this.isNav4 = ( navigator.appName == "Netscape" && navigator.userAgent.toLowerCase().indexOf("gecko") == -1 ) ? true : false;
		this.isGecko = ( navigator.userAgent.toLowerCase().indexOf("gecko") != -1 ) ? true : false;
        this.isIE4 = ( navigator.appName.indexOf( "Microsoft" ) != -1 ) ? true : false;
		this.isMac = ( navigator.userAgent.toLowerCase().indexOf("mac") != -1 ) ? true : false;
    }
    
    // Populate the current Day|Month|Year properties
    var objDate = new Date();
    this.currentDay = objDate.getDate();
    this.currentMonth = objDate.getMonth(); 
    var curYear = objDate.getYear(); 
    this.currentYear = (curYear < 1000) ? curYear + 1900 : curYear; 
	
    this.month = this.currentMonth;
    this.year = this.currentYear;
    
    // create the canvass that we will be displaying the calendar on
    this.createCanvass( );
	
}


// Called on initialization of the Class to create the acutal DIV|LAYER Object
function _createCanvass( )
{
    if (this.isNav4) 
    { 
        this.canvass = new Layer(200);
    }
    else if (this.isIE4 || this.isGecko)
    {
        var objDiv = document.createElement("div");
		objDiv.style.position = 'absolute';
        document.body.appendChild ( objDiv );
        this.canvass = objDiv;
    }
    
    this.moveTo( this.posX, this.posY );
}


// 
function _positionCanvass( x, y )
{
    // if either x or y were not supplied, default to the current settings.
    if( x==null || y==null ) 
    {
        x=this.posX; 
        y=this.posY; 
    }
    
    if( isNaN( x ) || isNaN( y ) )
    {
        alert('You can only enter numbers for the x/y co-ordinates');
        return;
    }
    
    // apply Positioning
    if ( this.isNav4 ) 
    { 
		this.canvass.left = this.posX = x;
        this.canvass.top = this.posY = y;
    }
    else if ( this.isIE4 || this.isGecko )
    {
		this.canvass.style.left = this.posX = x + "px";
        this.canvass.style.top = this.posY = y + "px";
	}
}


// This function sets visibility of the canvass to Visible.
function _show( )
{
    if(this.isNav4)
    {
        this.canvass.visibility = 'show';
    }
    else if (this.isIE4 || this.isGecko)
    {
		this.canvass.style.visibility = 'visible';
    }
    
    this.moveTo( this.posX, this.posY );
    this.visible = true; 
}


// This function hides the objects canvass.
function _hide( )
{
    if(this.isNav4)
    {
        this.canvass.visibility = 'hide';
    }
    else if (this.isIE4 || this.isGecko)
    {
        this.canvass.style.visibility = 'hidden';
    }
    this.visible = false;
}

// Renders the calendar
function _showCalendar ( s )
{
    if( this.isNav4 )
    {
        this.canvass.document.open( );
        this.canvass.document.writeln( s );
        this.canvass.document.close( );
    }
    else if ( this.isIE4 || this.isGecko )
    {
        this.canvass.innerHTML = s;
    }
    
    this.show( );
}

// Toggles the Calendar by +/- 1 Month
function _toggleCalendar(n)
{
    if((this.month + n) < 0)
    {
        this.month = 11;
        -- this.year;
    }
    else if((this.month + n) >= 12) 
    { 
        this.month = 0; 
        ++ this.year; 
    }
    else
    {
        this.month = this.month + n;
    }
    
    this.BuildCalendar();
}


// Create and Display Calendar.
function _create()
{
    // Counters to count rows and days 
    var rowCount = 0;
    
    var sOut = new String;   // String to store calendar output.
    
    // Leap year correction
    if (this.year % 4 == 0 && (this.year % 100 != 0 || this.year % 400 == 0)) {
    	this.totalDays[1] = 29;
    }
    
    // Get the first and last Day numbers of the month being fetched
    var objDate = new Date( this.year, this.month, 1 );
    var firstDayOfMonth = objDate.getDay();
    objDate.setDate(31);
    var lastDayOfMonth = objDate.getDay();
    objDate = null;
    
    sOut = '<table cellpadding=\"0\" cellspacing=\"0\" id=\"calCalendar\">';
    
    /* CREATE THE CELLS FOR THE TABLE HEADER */
    sOut += "<tr id=\"calTitleBar\">";
	sOut += "<td>";
	sOut += "<a href=\"#\" onclick=\"toggleCalendar(-1) ; return false ;\" class=\"calArrows\" title=\"previous month\">";
	sOut += "&laquo;";
	sOut += "</a>";
	sOut += "</td>";
	sOut += "<td colspan=\"5\" id=\"calMonthTitle\">" + this.months[this.month] + ' \'' + this.year.toString().slice(2,4) + "</td>";
	sOut += "<td align=\"right\">";
	sOut += "<a href=\"#\" onclick=\"toggleCalendar(1) ; return false ;\" class=\"calArrows\" title=\"next month\">";
	sOut += "&raquo;";
	sOut += "</a>";
	sOut += "</td>";
	sOut += "</tr>";
    
    
    /* CREATE THE CELLS FOR THE DAY NAMES ie: MON, TUE... */
    sOut += "<tr id=\"calWeekDayRow\">";
    for (x=0; x<7; x++)
    {
        // call the method to create the cell contents
        sOut += this.GetDay ( this.days[x].substring(0,1).toUpperCase(), false );
    }
    sOut += "</tr>";

    /* START OF CALENDAR BODY */
    sOut += "<tr id=\"calMainRows\">" ;
    
    for (x=1; x<=firstDayOfMonth; x++)
    {
        /* pad the blank days at the beginning of the month. */
        rowCount++;
        sOut += this.GetDay ("&nbsp;", true);
    }
    
    /* create the cells for each day in the current month */
    var dayCount = 1;
    
    while (dayCount <= this.totalDays[this.month])
    {
    	/* display new row after each 7 day block.  */
    	if (rowCount % 7 == 0)
    	{
    	    sOut += "</tr><tr>";
    	}
    	
    	// Call the method to create the cell contents
    	sOut += this.GetDay ( dayCount, true );
    	++rowCount;
    	++dayCount;
    }

    while ( rowCount % 7 != 0 ) {
        /* pad the blank days at the end of the month. */
        ++rowCount;
       sOut += this.GetDay ( "&nbsp;", true );
    }
    sOut += "</tr>";
    // End of BODY
	
	sOut += "<tr><td id=\"calClearDate\" colspan=\"7\"><a href=\"#\" onclick=\"clearCalendar(); return false;\">x &nbsp; Clear Date &nbsp; x</a></td></tr>"
	
    sOut += "</table>";
	
    // Render the calendar
    this.showCalendar ( sOut );
}


/*
    Responsible for displaying a Cell on the calendar face
*/
function _getDayString ( dayNum, isDay )
{
	var blnIsCurrentMonth;
	var blnIsCurrentDay;
	
	if (isInteger(dayNum)) {
		blnIsCurrentMonth   = ( this.year == this.currentYear && this.month == this.currentMonth );
		blnIsCurrentDay = ( blnIsCurrentMonth && ( dayNum == this.currentDay ) );
	} else {
		blnIsCurrentMonth = true;
		blnIsCurrentDay = false;
    }
	
    if (blnIsCurrentDay) 
    {
		thisCellClassName = "calDayCurrent";
    }
    else
    {
		thisCellClassName = "calDay";
    }
    
    var tmpLinkStart = '';
	var tmpLinkEnd = '';
	var tmpCellOuter = '';
	
	// Display Cell as link ??
    if( isDay && isInteger(dayNum))
    {
		tmpCellOuter = "<td class=\"" + thisCellClassName + "\">";
    
        tmpLinkStart = "<a href=\"#\"";
        if ( isDay ) 
        {
            tmpLinkStart += ' onclick=\"clickCalendar(' + dayNum + ',' + this.month + ',' + this.year + ');';
			tmpLinkStart += ' return false;\" title=\"' + this.months[this.month] + ' ' + dayNum + ', ' + this.year + '\"';
        }
        tmpLinkStart += " class='calClickable'>";
    
        tmpLinkEnd  = "</a>";
    }
    else if( isDay && !isInteger(dayNum)) 
	{
		tmpCellOuter = "<td class=\"calNoClick\">";
	}
	else
    {
        tmpCellOuter = "<td class=\"calWeekDay\">";
    }
    
    var tmpCellInner = dayNum;
		    
    return tmpCellOuter + tmpLinkStart + tmpCellInner + tmpLinkEnd + "</td>\n";
}

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

function isInteger (s)

{   var i;

    if (isEmpty(s)) 
       if (isInteger.arguments.length == 1) return false;
       else return (isInteger.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			End Of jsCalendar Class
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	
var objCalendar ;

function produceCalendar(field, e)
{
	
    if ( typeof( objCalendar ) != 'object' ) objCalendar = new jsCalendar() ;

	if ( objCalendar.isIE4 || objCalendar.isGecko ) {

		objCalendar.posX = e.clientX + 14 ;
		 if ((!window.document.compatMode) || (window.document.compatMode == 'BackCompat')) {
			objCalendar.posY =  e.clientY + document.body.scrollTop - 10;
		} else {
			objCalendar.posY =  e.clientY + document.documentElement.scrollTop + document.body.scrollTop - 10;
		}
		
	} else {
        
		objCalendar.posX = 350 ;
        objCalendar.posY = 40 ;

    }

    // If the calendar is visible and the same button was pressed as was pressed
    // to create the Calendar then Hide the calendar and exit the Sub
    if( objCalendar.visible && field == objCalendar.bindToElement )
    {
        objCalendar.hide() ;
        return ;
    }else{
        objCalendar.bindToElement = field ;
    }

    objCalendar.BuildCalendar() ;
    return ;
}

function clearCalendar()
{
	objCalendar.bindToElement.value = '';
	objCalendar.hide();
}

function clickCalendar(d, m, y)
{
    m = m + 1  // month is a zero-based array, adding 1 will set it right...
    objCalendar.bindToElement.disabled = false;
    objCalendar.bindToElement.value = m + '/' + d + '/' + y;
    objCalendar.bindToElement.disabled = true;
    // hide the calendar object.
    objCalendar.hide();
}

function toggleCalendar(i)
{
    objCalendar.toggleCalendar(i);
}

function submitCalendar(theform) 
{
	theElems = theform.elements
	for (i = 0; i < theElems.length; i++) {
		theElem = theElems[i];
		if (theElem.disabled) {
       	 theElem.disabled = false;
      }
	}
	theform.submit();
}


/*****************************************************************************/
	