
function calendar(objName){
    this.objName = objName;
    this.objClass = 'bambo_calendar_date';
    this.fieldReturn = '';        // Return ISO date to field
    this.functionReturn = '';    // Return ISO date to function
    this.dateSet = '';
    this.originOffsetX = 0;
    this.originOffsetY = 0;
    this.offsetX = 0;
    this.offsetY = 0;
    this.mode = 'datenorm';
    this.buttonTextPrevious = '<< Previous';
    this.buttonTextNext = 'Next >>';
    this.events = new Array();
    
    // Subclass that holds classNames or styles to link to style sheet
    this.classNameObj = function () {
        this.dayName             = '';
        this.dayNameTable         = '';
        this.dayNames             = '';
        this.dayNumber             = '';
        this.dayNumberTable     = '';
        this.dayNumbers         = '';
        this.dayNumberSelected     = '';
        this.dayEvent             = '';
        this.title                 = '';
        this.nextButton         = '';
        this.backButton         = '';
    }
    
    this.className = new this.classNameObj();
    this.style = new this.classNameObj();

    // Add appointment function
    this.event = function (year, month, day){
        this.events[this.events.length] = new Array(year, month, day);
    }
    
    // ISO DateTime handler
    this.dateTimeStore = function () {
        this.dateTime = new Date();
        
        var weekday = this.dateTime.getDay();    // Returns day (0-6)
        var year     = this.dateTime.getYear();    // Returns year
        var month     = this.dateTime.getMonth();    // Returns month (0-11)
        var date     = this.dateTime.getDate();    // Returns day (1-31)
        
        if(year < 1900){year = year + 1900};
        
        this.date         = date;
        this.month         = month + 1;            // Lets start at 1
        this.year         = year;
        this.hours         = '';
        this.minutes     = '';
        this.seconds     = '';
        
        // Better time functions
        this.setDate = function (today){this.date = today; this.dateTime.setDate(today);}
        this.setMonth = function (month){this.month = month; this.dateTime.setMonth((month - 1));}
        this.setYear  = function (year){this.year = year; this.dateTime.setYear(year);}
    }
    
    this.dateNow = new this.dateTimeStore();
    this.dateSet = new this.dateTimeStore();
    this.dateTmp = new this.dateTimeStore();
    
    // Get postion of link that called the calendar
    this.findPosition = function (obj) {
    
        var Y = X = 0;
        if (obj.offsetParent) {
            X = obj.offsetLeft
            Y = obj.offsetTop
            while (obj = obj.offsetParent) {
                X += obj.offsetLeft
                Y += obj.offsetTop
            }
        }
        this.originOffsetX = X;
        this.originOffsetY = Y;
    }

    // Create calender layer
    this.display = function (obj){
        this.obj = obj;
        // Set Calendar position if popup is to be created object has been returned
        if(obj && typeof(obj) == 'object'){
            this.findPosition(obj);
        } 
        // Display inside div tag
        else if (obj && typeof(obj) == 'string'){
            this.objName = obj;
        }
        
        // Use Set Date, either from initial load or function update
        if(document.getElementById(this.fieldReturn) && !document.getElementById(this.fieldReturn).value == '' && document.getElementById(this.fieldReturn).value != '0000-00-00 00:00:00'){
            var failed = false;
            var getDate = document.getElementById(this.fieldReturn).value;
            
            if(this.mode == 'date'){
                var datetime_int = new Array();
                datetime_int[0] = getDate;
            }else if(this.mode == 'datenorm'){
                var datetime_int = new Array();
                datetime_int[0] = getDate;
            }else if (this.mode == 'datetime'){
                var datetime_int = getDate.split(" ");
            }
            
            if(datetime_int[0]){var date_int = datetime_int[0].split("/");}
            if(date_int[0]){this.dateSet.setYear(parseFloat(date_int[2]));}
            if(date_int[1]){this.dateSet.setMonth(parseFloat(date_int[1]));}
            if(date_int[2]){this.dateSet.setDate(parseFloat(date_int[0]));}
            
            // Set Temp Date Start
            this.dateTmp.setYear(this.dateSet.year);
            this.dateTmp.setMonth(this.dateSet.month);
            this.dateTmp.setDate(this.dateSet.date);
        }
        
        // If no calender display
        if(typeof(obj) == 'object' && !document.getElementById(this.objName)){
            this.layer = document.createElement('DIV');
            this.layer.id = this.objName;
            this.layer.className = this.objClass;
            this.layer.style.position = 'absolute';
            this.layer.style.left = (this.originOffsetX + this.offsetX) + 'px';
            this.layer.style.top = (this.originOffsetY + this.offsetY) + 'px';
            
            document.body.appendChild(this.layer);
            document.getElementById(this.objName).innerHTML = this.objName;
            
            this.render();
        } 
        else if (obj && typeof(obj) == 'string'){
            this.render();
        }
        // If calendar then destroy (use this.render to refreash calender
        else if (typeof(obj) == 'object' && this.layer) {
            document.body.removeChild(this.layer);
        }
    }
    
    // Set Field with date
    this.fieldSet = function(){
        this.returnDate(this.dateSet);
    }
    
    // Return data to field with an id of this.fieldoutput
    this.returnDate = function (dateReturn){    
        var datetime_int = dateReturn.split(" ");
        var date_int = datetime_int[0].split("-");
        var year = parseInt( date_int[0]);      // Returns year
        var month = parseInt(date_int[1]);    // Returns month (0-11)
        var date = parseInt(date_int[2]);    // Returns day (1-31)
        
        if(month < 10){month = '0' + month;}
        if(date < 10){date = '0' + date;}
        
        if(this.mode == 'date'){
            var dateReturn = year + '-' + month + '-' + date;
        } else if (this.mode == 'datetime'){
            var dateReturn = year + '-' + month + '-' + date + ' 00:00:00';
        } else if (this.mode == 'datenorm'){
            var dateReturn = date + '/' + month + '/' + year;
        }
        
        this.dateTmp.setYear(year);
        this.dateTmp.setMonth(month);
        this.dateTmp.setDate(date);
        
        this.dateSet.setYear(year);
        this.dateSet.setMonth(month);
        this.dateSet.setDate(date);
    
        // Output to field, if no field then alert output
        if(document.getElementById(this.fieldReturn)){
            document.getElementById(this.fieldReturn).value = dateReturn;
            this.display(this.obj);
        } else if (this.functionReturn != ''){
            eval(this.functionReturn + '(dateReturn)');
            this.render();
        } else {
            alert(dateReturn);
            this.render();
        }
        
        // Hide display on return
        if(document.getElementById(this.objName)){this.display();}
    }
    
    // Modify Month
    this.changeMonth = function (monthModifier){
        var year_modifier = 0;
        var month = parseInt(this.dateTmp.month);
        var year = parseInt(this.dateTmp.year);
        month = month + monthModifier;
        
        // If moving months forward
        if(month > 12){
            year_modifier = Math.floor(month / 12);
            month = month - (year_modifier * 12);
            year = year + year_modifier;
        }
        // If moving month backwards
        else if(month < 1){
            year_modifier = Math.floor(month / 12) + 1;
            year = year - year_modifier;
            year_modifier = Math.floor(month / 12) - 1;
            month = month - (year_modifier * 12);
        }
        
        this.dateTmp.setMonth(month);
        this.dateTmp.setYear(year);
        
        // If calendar is visable refresh calendar
        if(document.getElementById(this.objName)){this.render();}
    }

    // Modify Day
    this.changeDay = function (dayModifier){
        var datetime_int = this.dateSet.split(" ");
        var date_int = datetime_int[0].split("-");
        year = parseInt( date_int[0]);      // Returns year
        month = parseInt(date_int[1]);    // Returns month (0-11)
        today = parseInt(date_int[2]) + dayModifier;    // Returns day (1-31)

        // If moving days forwards
        if(today > 0){
            while(today > (32 - new Date((year - 1900), month, 32).getDate())){
                today = today - (32 - new Date((year - 1900), month, 32).getDate());
                month++;
                
                // Modify Month and Year
                if(month > 12){
                    year_modifier = Math.floor(month / 12);
                    month = month - (year_modifier * 12);
                    year = year + year_modifier;
                }
            }
        }
        // If moving days backwards
        else if (today < 0){
            while(today > (32 - new Date((year - 1900), month, 32).getDate())){
                today = today + (32 - new Date((year - 1900), month, 32).getDate());
                month--;
                
                // Modify Month and Year
                if(month < 1){
                    year_modifier = Math.floor(month / 12) + 1;
                    year = year - year_modifier;
                    year_modifier = Math.floor(month / 12) - 1;
                    month = month - (year_modifier * 12);
                }
            }
        }
        
        this.dateSet = year + '-' + month + '-' + today + ' 00:00:00';

        // If calendar is visable refresh calendar
        if(document.getElementById(this.objName)){this.render();}
    }

    // Render Calender
    this.render = function (){
        //  SET CALENDAR PROPORTIONS
        var month_of_year = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
        var DAYS_OF_WEEK = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
        var FIRST_DAY_WEEK = 1;                // Sunday is 0
        var DAYS_OF_MONTH = 31;                // "constant" for number of days in a month
        var index = 0;
        
        // Working Data Memory
        this.dateTmp.dateTime.setDate(1);
                
        // ADJUST for first day of week, build offset
        if(FIRST_DAY_WEEK > 0 && FIRST_DAY_WEEK < 7){
            var new_DAYS_OF_WEEK = new Array();
            for(index=0; index<DAYS_OF_WEEK.length; index++){
                if(index < FIRST_DAY_WEEK){new_index = (DAYS_OF_WEEK.length - FIRST_DAY_WEEK) + index;} 
                else if(index >= FIRST_DAY_WEEK){new_index = index - FIRST_DAY_WEEK;}
                new_DAYS_OF_WEEK[new_index] = DAYS_OF_WEEK[index];
            }
            DAYS_OF_WEEK = new Array();
            DAYS_OF_WEEK = new_DAYS_OF_WEEK;
        }
        
        // BEGIN CODE FOR CALENDAR
        var cal =  '<table cellspacing="0" cellpadding="0" border="0">\n';
        cal += '<tr><td colspan="2"';
        if(this.className.title){cal += ' class="' + this.className.title + '" ';}
        if(this.style.title){cal += ' class="' + this.style.title + '" ';}
        cal += '><h1>';
        cal += month_of_year[this.dateTmp.month - 1]  + '&nbsp;' + this.dateTmp.year;
        cal += '</h1></td></tr>\n<tr><td colspan="2">\n';
        
        // Calendar Days Header Table
        cal += '<table border="0" cellspacing="0" cellpadding="0"';
        if(this.className.dayNameTable != ''){cal += ' class="' + this.className.dayNameTable + '" ';}    // Add Class
        if(this.style.dayNameTable != ''){cal += ' class="' + this.style.dayNameTable + '" ';}            // Add Style
        cal += '>\n';
        cal += '<tr>';
        
        // Loop through each day of the week
        for(index=0; index < DAYS_OF_WEEK.length; index++)    {
            cal += '<th';
            if(this.dateNow.date == index) {    // Class for today
                if(this.className.dayName != ''){cal += ' class="' + this.className.dayName + '" ';}    // Add Class
                if(this.style.dayName != ''){cal += ' class="' + this.style.dayName + '" ';}            // Add Style
            } else {
                if(this.className.dayNames != ''){cal += ' class="' + this.className.dayNames + '" ';}    // Add Class
                if(this.style.dayNames != ''){cal += ' class="' + this.style.dayNames + '" ';}            // Add Style
            }
            cal += '>' + DAYS_OF_WEEK[index] + '</th>';
        }
        cal += '</tr>\n</table>\n';
        cal += '<table border="0" cellspacing="0" cellpadding="0"';
        if(this.className.dayNumberTable != ''){cal += ' class="' + this.className.dayNumberTable + '" ';}    // Add Class
        if(this.style.dayNumberTable != ''){cal += ' class="' + this.style.dayNumberTable + '" ';}            // Add Style
        cal += '>\n';
        
        // FILL IN BLANK GAPS UNTIL FIRST DAY OF MONTH
        for(index=0; index < (this.dateTmp.dateTime.getDay() - FIRST_DAY_WEEK); index++) {
            if(index==0){cal += '<tr>';}
            cal += '<td>&nbsp;</td>';
        }
        if((this.dateTmp.dateTime.getDay() - FIRST_DAY_WEEK) == -1){
            cal += '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';
        }
        
        // EVENTS - Check for events in this month
        var events = new Array();
        for(index=0; index < this.events.length; index++) {
            if(this.events[index][0] == this.dateTmp.year && this.events[index][1] == this.dateTmp.month){
                events[this.events[index][2] - 1] = true;
            }
        }
        
        // LOOPS FOR EACH DAY IN CALENDAR
        var row_count = 0;    // Count rows, make sure there is 6
        for(index=0; index < DAYS_OF_MONTH; index++) {
            if( this.dateTmp.dateTime.getDate() > index ){
                week_day = this.dateTmp.dateTime.getDay();        // Return day date number
                if(week_day == FIRST_DAY_WEEK) {cal += '<tr>';}    // Start new row for first day of week
                
                // Calander Event
                cal += '<td><a';
                if (events[index]) {
                    if(this.className.dayEvent != ''){cal += ' class="' + this.className.dayEvent + '" ';}    // Add Class
                    else if(this.className.dayNumbers != ''){cal += ' class="' + this.className.dayNumbers + '" ';}    // Add Class
                    
                    if(this.style.dayEvent != ''){cal += ' style="' + this.style.dayEvent + '" ';}            // Add Style
                    else if(this.style.dayNumbers != ''){cal += ' style="' + this.style.dayNumbers + '" ';}            // Add Style
                    
                    if(this.dateNow.date == (index + 1) && this.dateNow.month == this.dateTmp.month && this.dateNow.year == this.dateTmp.year){
                        if(this.style.dayNumber != ''){cal += ' style="';}            // Add Style
                    }
                    else if(this.dateSet.date == (index + 1) && this.dateSet.month == this.dateTmp.month && this.dateSet.year == this.dateTmp.year){
                        if(this.style.dayNumberSelected != ''){cal += ' style="';}            // Add Style
                    }
                    
                    if(this.dateNow.date == (index + 1) && this.dateNow.month == this.dateTmp.month && this.dateNow.year == this.dateTmp.year){
                        if(this.style.dayNumber != ''){cal += this.style.dayNumber;}            // Add Style
                    }
                    if(this.dateSet.date != this.dateNow.date && this.dateSet.date == (index + 1) && this.dateSet.month == this.dateTmp.month && this.dateSet.year == this.dateTmp.year){
                        if(this.style.dayNumberSelected != ''){cal += this.style.dayNumberSelected ;}            // Add Style
                    }
                    
                    if(this.dateNow.date == (index + 1) && this.dateNow.month == this.dateTmp.month && this.dateNow.year == this.dateTmp.year){
                        if(this.style.dayNumber != ''){cal += '" ';}            // Add Style
                    }
                    else if(this.dateSet.date == (index + 1) && this.dateSet.month == this.dateTmp.month && this.dateSet.year == this.dateTmp.year){
                        if(this.style.dayNumberSelected != ''){cal += '" ';}            // Add Style
                    }
                }
                // Highlight todays date (set class/style)
                else if(this.dateNow.date == (index + 1) && this.dateNow.month == this.dateTmp.month && this.dateNow.year == this.dateTmp.year){
                    if(this.className.dayNumber != ''){cal += ' class="' + this.className.dayNumber + '" ';}    // Add Class
                    if(this.style.dayNumber != ''){cal += ' style="' + this.style.dayNumber + '" ';}            // Add Style
                }
                // Highlight selected date (set class/style)
                else if(this.dateSet.date == (index + 1) && this.dateSet.month == this.dateTmp.month && this.dateSet.year == this.dateTmp.year){
                    if(this.className.dayNumberSelected != ''){cal += ' class="' + this.className.dayNumberSelected + '" ';}    // Add Class
                    if(this.style.dayNumberSelected != ''){cal += ' style="' + this.style.dayNumberSelected + '" ';}            // Add Style
                    else if(this.className.dayNumbers != ''){cal += ' class="' + this.className.dayNumbers + '" ';}    // Add Class
                    else if(this.style.dayNumbers != ''){cal += ' style="' + this.style.dayNumbers + '" ';}            // Add Style
                }
                // Public Holiday
                else if (1==2) {
                    if(this.className.dayNumber != ''){cal += ' class="' + this.className.dayNumber + '" ';}    // Add Class
                    if(this.style.dayNumber != ''){cal += ' style="' + this.style.dayNumber + '" ';}            // Add Style
                }
                // Weekend
                else if (1==2) {
                    if(this.className.dayNumber != ''){cal += ' class="' + this.className.dayNumber + '" ';}    // Add Class
                    if(this.style.dayNumber != ''){cal += ' style="' + this.style.dayNumber + '" ';}            // Add Style
                }
                // Normal Day (set class/style)
                else {
                    if(this.className.dayNumbers != ''){cal += ' class="' + this.className.dayNumbers + '" ';}    // Add Class
                    if(this.style.dayNumbers != ''){cal += ' style="' + this.style.dayNumbers + '" ';}            // Add Style
                }
                cal += ' href="javascript:' + this.objName + '.returnDate(\'' + this.dateTmp.year + '-' + this.dateTmp.month + '-' + (index + 1) + ' 00:00:00\')">' + (index + 1) + '</a></td>';
            
                if(week_day == (FIRST_DAY_WEEK - 1)){
                    cal += '</tr>\n';    // End row for last day of week
                    row_count++;    // Start new row for first day of week
                }
            }
            
            this.dateTmp.setDate(this.dateTmp.dateTime.getDate()+1);    // Increments until end of month
        }
        
        // Finish up remaining table cells
        for(i=week_day; i <= (DAYS_OF_WEEK.length - FIRST_DAY_WEEK); i++){
            cal += '<td>&nbsp;</td>';
            if(i == (DAYS_OF_WEEK.length - FIRST_DAY_WEEK)){
                cal += '</tr>\n';    // End row for last day of week
                row_count++;    // Start new row for first day of week
            }
        }
        for(i=row_count; i <= 5; i++){
            cal += '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n';
        }
        cal += '</table>';
        
        // Complete navigation
        cal += '</td></tr>\n';
        cal += '<tr><td';
        if(this.className.backButton != ''){cal += ' class="' + this.className.backButton + '" ';}    // Add Class
        if(this.style.backButton != ''){cal += ' class="' + this.style.backButton + '" ';}            // Add Style
        cal += ' class="left">';
        cal += '<a href="javascript:' + this.objName + '.changeMonth(-1)">' + this.buttonTextPrevious + '</a>';
        cal += '</td><td';
        if(this.className.nextButton != ''){cal += ' class="' + this.className.nextButton + '" ';}    // Add Class
        if(this.style.nextButton != ''){cal += ' class="' + this.style.nextButton + '" ';}            // Add Style
        cal += ' class="right">';
        cal += '<a href="javascript:' + this.objName + '.changeMonth(1)">' + this.buttonTextNext + '</a>';
        cal += '</td></tr>\n'
        cal += '</table>';
        
        //  PRINT CALENDAR
        var calendar_div = document.getElementById(this.objName);
        calendar_div.innerHTML = cal;
        
        if(document.getElementById("debug")){
            document.getElementById("debug").value = cal;
        }
    }
}
