﻿function Calendar( testDate, preventFutureBrowse )
{
    this.customObject = true;
    
    if( typeof preventFutureBrowse != "undefined" )
        this.preventFutureBrowse = preventFutureBrowse;
    else
        this.preventFutureBrowse = false;
        
    this.eventDayList = {};
    
    this.htmlElement = document.createElement( "span" );
    
    this.currentDate = testDate;
    
    this.onDateClick = new CustomEvent( "onDateClick", this );
    
    //if( typeof eventDays == "undefined" ) eventDays = {};
    
    this.ultraShortDayNames = [ 'S','M','T','W','R','F','S' ];
    this.shortMonthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
    this.monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];

    this.renderCalendar( testDate );
}

Calendar.prototype.renderCalendar = function( testDate )
{
    this.htmlElement.innerHTML = "";

    // my calendar
    var today = new Date( testDate );
    var currentMonth = today.getMonth();
    var previousMonth = currentMonth === 1 ? 12 : currentMonth - 1;
    var nextMonth = currentMonth === 11 ? 0 : currentMonth + 1;
    
    var currentYear = this.currentYear = today.getFullYear();
    var previousYear = this.previousYear = currentMonth === 1 ? currentYear - 1 : currentYear;
    var nextYear = this.nextYear = currentMonth === 11 ? currentYear + 1 : currentYear;
    
    currentMonth++;
    previousMonth++;
    nextMonth++;
    
    this.currentMonth = currentMonth;
    this.previousMonth = previousMonth;
    this.nextMonth = nextMonth;
    
    var firstDateOfMonth = new Date(testDate);
        firstDateOfMonth.setDate( 1 );
        firstDateOfMonth = firstDateOfMonth.getDay();

    var lastDateOfMonth = new Date(testDate);
        lastDateOfMonth.setDate( 1 );
        lastDateOfMonth.setMonth(lastDateOfMonth.getMonth() + 1);
        lastDateOfMonth.setDate( lastDateOfMonth.getDate() - 1 );
        lastDateOfMonth = lastDateOfMonth.getDate();

    var lastDayOfPreviousMonth = new Date(testDate);
        lastDayOfPreviousMonth.setDate( 1 );
        lastDayOfPreviousMonth.setDate(lastDayOfPreviousMonth.getDate()-1);
        lastDayOfPreviousMonth = lastDayOfPreviousMonth.getDate();
    	
    var calendar = [];

    //if( firstDateOfMonth > 0 )
    {

	    // start with previous month's ending.
	    var calendarIndex = 0;
    	
	    calendar[ calendarIndex ] = [];
    	
	    for( var i = 0; i < 7; i++ )
	    {
	        if( i >= firstDateOfMonth )
	            calendar[ calendarIndex ][ i ] = i - firstDateOfMonth + 1;
	        else
	            calendar[ calendarIndex ][ i ] = lastDayOfPreviousMonth + i - firstDateOfMonth + 1;
	    }
    	
	    var nextDay = 8 - firstDateOfMonth;
    	

        //calendarIndex++;
        //calendar[ calendarIndex ] = [];
        //debugger;
        for( var i = nextDay, j = 0; i <= lastDateOfMonth; i++, j++ )
        {
            if( j % 7 == 0 )
            {
                calendarIndex++;
                calendar[ calendarIndex ] = [];
            }
            
            calendar[ calendarIndex ][ j % 7 ] = nextDay;
            nextDay++;
        }

        for( var i = calendar[ calendarIndex ].length, j = 1; i < 7; i++, j++ )
        {
            calendar[ calendarIndex ][ i ] = j;
        }


    }

    var table = this.tableElement = document.createElement( "table" );
        table.cellPadding = "0";
        table.cellSpacing = "0";
        
    var row = table.insertRow( -1 ), cell;
    cell = row.insertCell( -1 );
    cell.className = "previousMonth";
    cell.date = new Date( previousMonth + "/" + dateNumber + "/" + previousYear );
    cell.innerHTML = "«";
    addEvent( cell, "click", this.previousMonth_onClick, this );
    
    cell = row.insertCell( -1 );
    cell.colSpan = 5;
    cell.innerHTML = this.monthNames[ currentMonth-1 ] + " " + currentYear;
    cell.className = "monthYearTitle";
    
    cell = row.insertCell( -1 );
    
    today = new Date();
    if( this.preventFutureBrowse && today.getMonth()+1 == currentMonth && today.getFullYear() == currentYear )
    {
        cell.style.cursor = "default";
        cell.innerHTML = "&nbsp;";
    }    
    else
    {
        cell.className = "nextMonth";
        cell.innerHTML = "»";
        addEvent( cell, "click", this.nextMonth_onClick, this );
    }
    
    row = table.insertRow( -1 );

    for( var i = 0; i < 7; i++ )
    {
        cell = row.insertCell( -1 );
            
        cell.innerHTML = this.ultraShortDayNames[ i ];
        
        cell.className = "dayTitle";
    }
    
    for( var i = 0; i < calendar.length; i++ )
    {
        row = table.insertRow( -1 );
        
        for( var j = 0; j < 7; j++ )
        {
            cell = row.insertCell( -1 );

            var dateNumber = calendar[ i ][ j ];
            var dateObject;
            var className;
            var dateString;
            var hasEvent = false;
            
            if( i === 0 && dateNumber > 7 )
            {
                dateString = previousMonth + "/" + dateNumber + "/" + previousYear;
                dateObject = new Date( dateString );
                if( this.eventDayList[ dateString ] )
                {
                    className = "otherMonthDayWithEvent";
                    hasEvent = true;
                }
                else
                    className = "otherMonthDay";
            }
            else if( i === calendar.length-1 && dateNumber < 8 )
            {
                dateString = nextMonth + "/" + dateNumber + "/" + nextYear;
                dateObject = new Date( dateString );
                if( this.eventDayList[ dateString ] )
                {
                    className = "otherMonthDayWithEvent";
                    hasEvent = true;
                }
                else
                    className = "otherMonthDay";   
            }
            else
            {
                dateString = currentMonth + "/" + dateNumber + "/" + currentYear;
                dateObject = new Date( dateString );
                if( this.eventDayList[ dateString ] )
                {
                    className = "currentMonthDayWithEvent";
                    hasEvent = true;   
                }
                else
                    className = "currentMonthDay";
            }
            
            cell.innerHTML = dateNumber;
            cell.date = dateObject;
            cell.className = className;
            
            if( hasEvent )
                addEvent( cell, "click", this.dateCell_onClick, this );
            //cell.onclick = this.dateCell_onClick;
        }
    }
    
    this.htmlElement.appendChild( this.tableElement );
}
Calendar.prototype.previousMonth_onClick = function( caller )
{
    var previousDate = new Date( this.previousMonth + "/" + 1 + "/" + this.previousYear );
    
    this.renderCalendar( previousDate );
}
Calendar.prototype.nextMonth_onClick = function( caller )
{
    var nextDate = new Date( this.nextMonth + "/" + 1 + "/" + this.nextYear );
    
    this.renderCalendar( nextDate );
}
Calendar.prototype.dateCell_onClick = function(caller)
{
    var date = caller.date;
    
    var dateString = ( date.getMonth() + 1 ) + "/" + date.getDate() + "/" + date.getFullYear();
    this.onDateClick.fire( dateString );
    
    //alert( date );
}
Calendar.prototype.setEventDayList = function( value )
{
    this.eventDayList = value;
    
    this.renderCalendar( this.currentDate );
}