/*===================================================================
    File        : youfra_calendar.js
    Description : Calendar Generator
    Author      : OnionHead
    Require     : prototype-1.4.0.js
===================================================================*/
function YoufraCalendar(div) {
    if (div == null) {
        alert('YoufraCalendar(): No div define.');
    }
    this.div = div;
    this.div.innerHTML = '<div id="youfraCalendarPanel" style="position:absolute"/><div id="youfraCalendarNotes" style="position:absolute"/>';
    this.youfraCalendarPanel = $(youfraCalendarPanel);
    this.youfraCalendarNotes = $(youfraCalendarNotes);
    this.weekdayNameArray = ['日', '一', '二', '三', '四', '五', '六'];
    this.scheduleEvents = new Array();
    this.nowDate = new Date();
    this.displayDate = new Date();
}

/* addEvent: Add a single event
 * params: year - full year no., eg. 2006
 *         month - month no. range (1-12), eg. 12
 *         monthDay - day of the month, eg. 31
 *         topic - topic of the event
 *         desc  - description of the event
 */
YoufraCalendar.prototype.addScheduleEvent = function(year, month, monthDay, topic, desc) {
    this.scheduleEvents.push( {date: new Date(year, month-1, monthDay), topic: topic, desc: desc} );
}

/* addEvent: Add a single event
 * params: year - full year no., eg. 2006
 *         month - month no. range (1-12), eg. 12
 *         monthDay - day of the month, eg. 31
 */
YoufraCalendar.prototype.findMatchedScheduleEvents = function(year, month, monthDay) {
    var matchedScheduleEvents = new Array();
    var searchDate = new Date(year, month, monthDay);
    for (var i = 0; i < this.scheduleEvents.length; i++) {
        var oneScheduleEvent = this.scheduleEvents[i];
        if (oneScheduleEvent.date.getFullYear() == year &&
            oneScheduleEvent.date.getMonth() == month &&
            oneScheduleEvent.date.getDate() == monthDay) {
            matchedScheduleEvents.push(oneScheduleEvent);
        }
    }
    return matchedScheduleEvents;
}

YoufraCalendar.prototype.isLeapYear = function(year) {
    return (year % 4 == 0);
}

YoufraCalendar.prototype.getDays = function(year, month) {
    // create array to hold number of days in each month
    var ar = new Array(12);
    ar[0] = 31; // January;
    ar[1] = (this.isLeapYear(year)) ? 29 : 28; // February;
    ar[2] = 31; // March;
    ar[3] = 30; // April;
    ar[4] = 31; // May;
    ar[5] = 30; // June;
    ar[6] = 31; // July;
    ar[7] = 31; // August;
    ar[8] = 30; // September;
    ar[9] = 31; // October;
    ar[10] = 30; // November;
    ar[11] = 31; // December;

    // return number of days in the specified month (parameter)
    return ar[month];
}

YoufraCalendar.prototype.getMonthName = function(monthIdx) {
    return this.getChineseNumberName(monthIdx + 1) + '月';
}

YoufraCalendar.prototype.getYearName = function(year) {
    var strLen = ('' + year).length;
    if (strLen==2) {
        if (year > 70) {
            year=1900+(year-0);
        } else {
            year=2000+(year-0);
        }
    } else if (strLen == 3) {
        year = 2000 + (year - 100);
    }
    var targetStr = '';
    var yearStr = year + '';
    for (var i=0; i<yearStr.length; i++) {
        targetStr += this.getChineseNumberName(yearStr.substring(i,i+1));
    }
    return targetStr + '年';
}

YoufraCalendar.prototype.getChineseNumberName = function(num) {
    var numStr = '' + num;
    var CHINESE_NUM = ['零','一','二','三','四','五','六','七','八','九'];
    var CHINESE_UNIT= [
          '','十','百','千',
        '萬','十','百','千',
        '億','十','百','千',
        '兆','十','百','千',
        '京','十','百','千'
    ];

    var orgNumStrLen = numStr.length;
    var targetStr = '';
    var numContinusZero = 0;
    while (numStr.length > 0) {
        var char = numStr.substring(0,1);
        var unitIdx = numStr.length - 1;
        numStr = numStr.substring(1);

        //handle for zero
        if (char == '0') {
            if (unitIdx == 0 && orgNumStrLen == 1) {
                targetStr += CHINESE_NUM[0]; //can also only return CHINESE_NUM[0];
            }
            if (unitIdx == 4 || unitIdx == 8 || unitIdx == 12 || unitIdx == 16) {
                targetStr += CHINESE_UNIT[unitIdx];
            }
            numContinusZero++;
            continue;
        }

        //add prefix zero
        if (numContinusZero > 0) {
            targetStr += CHINESE_NUM[0];
        }
        numContinusZero = 0;

        //handle for 1
        if (char == '1') {
            //alert('unitIdx=' + unitIdx + ', orgNumStrLen=' + orgNumStrLen);
            if ((unitIdx == orgNumStrLen - 1) &&
                (orgNumStrLen == 2 || orgNumStrLen == 6 || orgNumStrLen == 10
                    || orgNumStrLen == 14 || orgNumStrLen == 18)
            ) {
                targetStr += CHINESE_UNIT[unitIdx]; //always return '十'
                continue;
            }
        }

        targetStr += CHINESE_NUM[char] + CHINESE_UNIT[unitIdx];

    }
    return targetStr;
}

YoufraCalendar.prototype.drawCalendar = function(displayDate, numMonthShow) {
    if (displayDate != null) {
        this.displayDate = displayDate;
    }
    if (numMonthShow == null) {
        numMonthShow = 1;
    }
    var calStr = '';
    var displayDate = new Date(this.displayDate.getTime());
    displayDate.setDate(1);
    for (var i=0; i<numMonthShow; i++) {
        var year  = displayDate.getFullYear();
        var month = displayDate.getMonth();
        var firstWeekDay = displayDate.getDay();

        // number of days in current month;
        var days = this.getDays(year, month);

        // call function to draw calendar;
        calStr += this.getCalendarHtmlStr(firstWeekDay + 1, days, year, month);
        calStr += '<br/>';
        displayDate.setMonth(displayDate.getMonth() + 1);
    }
    this.youfraCalendarPanel.innerHTML = calStr;
}

YoufraCalendar.prototype.getCalendarHtmlStr = function(firstDay, lastDate, year, month) {

    var calStr = '<table width="500" class="calendar_table">'
        + '<tr>'
        + '<th colspan="7">' + this.getYearName(year) + this.getMonthName(month) + '</td>'
        + '</tr>';
    calStr += '<tr class="weekday">'
            + '<td width="70" class="holiday">日</td>'
            + '<td width="70">一</td>'
            + '<td width="70">二</td>'
            + '<td width="70">三</td>'
            + '<td width="70">四</td>'
            + '<td width="70">五</td>'
            + '<td width="70" class="sat_day">六</td>'
        + '</tr>';

    // declaration and initialization of two variables to help with tables
    var todayDate = -1;
    if (year == this.nowDate.getFullYear() && month == this.nowDate.getMonth()) {
        todayDate = this.nowDate.getDate();
    }
    var digit = 1;
    var curCell = 1;
    var td_weekday_style_map = ['', 'holiday', 'normal_weekday', 'normal_weekday', 'normal_weekday', 'normal_weekday', 'normal_weekday', 'sat_day'];
    var td_non_weekday_style_map = ['', 'non_weekday_holiday', 'non_weekday', 'non_weekday', 'non_weekday', 'non_weekday', 'non_weekday', 'non_weekday_sat_day'];
    for (var row = 1; row <= Math.ceil((lastDate + firstDay - 1) / 7); ++row) {
        calStr += '<tr class="calendar_day">';
        for (var col = 1; col <= 7; ++col) {
            var non_weekday = (digit > lastDate || curCell < firstDay);
            if (non_weekday) {
                calStr += '<td class="' + td_non_weekday_style_map[col] + '">&nbsp';
                curCell++;
            } else if (digit == todayDate) {
                calStr += '<td class="today">';
            } else {
                calStr += '<td class="' + td_weekday_style_map[col] + '">';
            }
            if (!non_weekday) {
                calStr += digit;
                var matchedScheduleEvents = this.findMatchedScheduleEvents(year, month, digit);
                for (var eventIdx = 0; eventIdx < matchedScheduleEvents.length; eventIdx++) {
                    var oneScheduleEvent = matchedScheduleEvents[eventIdx];
                    calStr += '<br/><span class="event"><span class="eventheader">'
                        + oneScheduleEvent.topic
                        + '</span>'
                        + ((oneScheduleEvent.desc != null && oneScheduleEvent.desc.length >0)?'<br/>' + oneScheduleEvent.desc: '')
                        + '</span>';
                }
                digit++;

            }
            calStr += '</td>';
        }
        calStr += '</tr>';
    }

    // close all basic table tags
    calStr += '</table>';
    return calStr;
    //this.youfraCalendarPanel.innerHTML = calStr;
}

YoufraCalendar.prototype.gotoMonth = function (iCurrMonthDifference) {
    oCurrDate.setMonth(oCurrDate.getMonth()+ parseInt(iCurrMonthDifference));
    setCalender(oCurrDate);
}

