var _calCurrent;

//declare note types
noteTypes = ['Statutory', 'Working groups', 'Other', 'Courses'];

// these are labels for the days of the week
cal_days_labelsFull = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
cal_days_labels = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];

// these are human-readable month name labels, in order
cal_months_labels = ['January', 'February', 'March', 'April',
                     'May', 'June', 'July', 'August', 'September',
                     'October', 'November', 'December'];

// these are the days of the week for each month, in order
cal_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

// this is the current date
cal_current_date = new Date();

function Calendar(name, calendarData, admin_mode, year, month, day) {
    this.name = name;
    this.calendarData = calendarData;
    this.admin_mode = admin_mode;
    this.allowDayInfo = false;

    this.month = (isNaN(month) || month == null) ? cal_current_date.getMonth() : month;
    this.year = (isNaN(year) || year == null) ? cal_current_date.getFullYear() : year;
    this.day = (isNaN(day) || day == null) ? cal_current_date.getDate() : day;
    this.html = '';

    this.agendaShowType = "tooltype";
    this.cellspacing = 0;
    this.cellpadding = 0;
}

Calendar.prototype.calendar_click = function(year, month, day) {
    if (this.day) {
        $('cday' + this.day).style.backgroundColor = '#003366';
    }
    this.day = day;
    $('cday' + this.day).style.backgroundColor = '#005090';
    if (this.click) {
        this.click(year, month, day);
    }
}

Calendar.prototype.calendar_prev = function() {
    this.month = this.month - 1;
    if (this.month < 0) {
        this.month = 11;
        this.year -= 1;
    }
    this.day = null;
    this.render();
}

Calendar.prototype.calendar_next = function() {
    this.month = this.month + 1;
    if (this.month > 11) {
        this.month = 0;
        this.year += 1;
    }
    this.day = null;
    this.render();
}

Calendar.prototype._getDayAgenda = function(year, day) {
    if (typeof (this.calendarData['y' + year]) != "undefined")
        if (typeof (this.calendarData['y' + year]['m' + this.month]) != "undefined")
        if (typeof (this.calendarData['y' + year]['m' + this.month]['d' + day]) != "undefined") {
        var a = [];
        var d = this.calendarData['y' + year]['m' + this.month]['d' + day];
        var sDay = d.day;
        if (sDay < 10) {
            sDay = "0" + sDay;
        }
        for (var ee = 0; ee < d.events.length; ee++) {
            var e = d.events[ee];
            
            /* popup -> "day, notes, place" */
            /*var s = sDay + getSuffix(sDay) + " ";
            s += e.notes;
            if (e.place && e.place.length > 0 && e.notes && e.notes.length > 0) {
            s += ", "
            }
            s += e.place;*/
            
            /* popup -> title */
            var s = e.title;
            a[a.length] = { day: d.day, line: s };
        }
        return a;
    }
    return [];
}

Calendar.prototype._getMonthAgenda = function(year) {
    if (typeof (this.calendarData['y' + year]) != "undefined")
        if (typeof (this.calendarData['y' + year]['m' + this.month]) != "undefined") {
        var a = [];
        for (var dd in this.calendarData['y' + year]['m' + this.month]) {
            var d = this.calendarData['y' + year]['m' + this.month][dd];
            var day = d.day;
            if (day < 10) day = "0" + day;
            for (var ee = 0; ee < d.events.length; ee++) {
                var e = d.events[ee];
                var s = day + getSuffix(day) + " ";
                s += e.notes;
                if (e.place && e.place.length > 0 && e.notes && e.notes.length > 0) s += ", "
                s += e.place;
                a[a.length] = { day: d.day, line: s };
            }
        }
        return a;
    }
    return [];
}

Calendar.prototype.updateAgenda = function() {
    var divCalendar = $('divCurrentCalendar');
    var divMonthCase = $('divMonthCase');
    var divMonthCalendar = $('divMonthCalendar');
    var divMonthComent = $('divMonthComent');

    var monthTable = divCalendar.firstChild.cloneNode(true);
    if (divMonthCalendar.firstChild != null) {
        divMonthCalendar.removeChild(divMonthCalendar.firstChild);
    }
    divMonthCalendar.appendChild(monthTable);

    // set info at bottom
    divMonthComent.innerHTML = 'Calendar | ' + cal_months_labels[this.month] + ' ' + this.year;

    // set bg layer
    if (monthTable.rows.length > 7) {
        divMonthCase.className = 'long';
    }
    else {
        divMonthCase.className = 'short';
    }

    for (var rowNum = 2; rowNum < monthTable.rows.length; rowNum++) {
        var row = monthTable.rows[rowNum];
        for (var colNum = 0; colNum < row.cells.length; colNum++) {
            var cell = row.cells[colNum];
            var newCell = document.createElement("td");
            newCell.id = cell.id.replace('cday', 'day');

            if (cell.className == 'calendar-DTCday') {
                newCell.className = cell.className;
            }

            if (cell.innerHTML.length > 0) {
                if (rowNum > 1) {
                    var toolTip = _calCurrent.getFormatedTooltip(document.all != null ? cell.innerText : cell.textContent, false);
                    var div = document.createElement('div');
                    div.setAttribute('class', 'day');
                    div.className = 'day';
                    if (toolTip.length > 0) {
                        div.innerHTML = toolTip;
                    }
                    newCell.appendChild(div);
                }
            }

            //newCell.setAttribute('onclick', 'showDay(this)');
            newCell.onclick = function() { showDay(this); };
            row.insertBefore(newCell, cell);
            row.removeChild(cell);
        }
    }
}

Calendar.prototype.getTooltip = function(day) {
    var a = this._getDayAgenda(this.year, day).concat(this._getDayAgenda(0, day));
    var s = "";
    for (var i = 0; i < a.length; i++) {
        if (i > 0) s += "<br />";
        s += a[i].line;
    }
    return s;
}

Calendar.prototype._getFormatedDayAgenda = function(year, day, extendDate) {
    var a = [];
    var s;
    var date = new Date(this.year, this.month, day)

    if (year == 0) {
        if (extendDate && this.admin_mode) {
            s = '<div id="divDayHeader" class="title">' +
                    '<span id="btnAdd" onclick="btnClick(this);">add</span>' +
                    '<span id="btnEdit" onclick="btnClick(this);">edt</span>' +
                    '<span id="btnDelete" onclick="btnClick(this);">del</span>' +
                    '<span id="btnSave" onclick="btnClick(this);">save</span>' +
                    '&nbsp;|&nbsp;<span class="dayNum">' + day + getSuffix(day) + '</span>' +
                '</div>';
        }
        else if (extendDate) {
            s = '<div id="divDayHeader" class="title"><span class="dayNum">' + cal_days_labelsFull[date.getDay()] + ' ' + day + getSuffix(day) + ' ' + cal_months_labels[this.month] + '</span></div>';
        }
        else {
            s = day;
        }

        a[0] = { day: -1, line: s };
    }
    if (typeof (this.calendarData['y' + year]) != "undefined")
        if (typeof (this.calendarData['y' + year]['m' + this.month]) != "undefined")
        if (typeof (this.calendarData['y' + year]['m' + this.month]['d' + day]) != "undefined") {
        var d = this.calendarData['y' + year]['m' + this.month]['d' + day];
        for (var ee = 0; ee < d.events.length; ee++) {
            var e = d.events[ee];
            s = this._getEventHTML(year, e, extendDate);
            a[a.length] = { day: d.day, line: s };
        }
    }
    return a;
}

Calendar.prototype._getEventHTML = function createEventHTML(year, e, extendDate) {
    var type = e.type;

    var click = this.admin_mode ? 'onclick = "selectDiv(this);"' : '';
    var s = extendDate ? '<div class="type' + e.type + '"></div>' : '';
    s = '<div class="title' + (e.isPrimary ? ' primary' : '') + '">' + s +
    ((extendDate && this.admin_mode) ? ('<input type="radio" name="radioPrimary" onclick="changePrimary();" ' + (e.isPrimary ? 'checked="checked"' : '') + '/>') : '') +
    e.title + '</div>';
    s += '<div>' + e.place;
    if (e.place && e.place.length > 0 && e.notes && e.notes.length > 0) s += "<br />"
    s += e.notes + '</div>';
    if (extendDate && this.admin_mode)
        s = '<div style="cursor:hand;" year="' + year + '" type="' + type + '" place="' + e.place + '" notes="' + e.notes + '" title="' + e.title + '" ' + click + '>'
        + s + '</div>';
    else if (extendDate)
        s = '<div>' + s + '</div>';
    return s;
}

Calendar.prototype.getFormatedTooltip = function(day, extendDate) {
    var a = this._getFormatedDayAgenda(0, day, extendDate).concat(this._getFormatedDayAgenda(this.year, day, extendDate));
    var s = "";
    for (var i = 0; i < a.length; i++) {
        if (s.length > 0 && !extendDate) s += "<br />";
        s += a[i].line;
    }
    return s;
}

Calendar.prototype.render = function() {
    this.generateHTML();
    $(this.name).innerHTML = this.getHTML();
    this.updateAgenda();
}

Calendar.prototype.hasDay = function(day) {
    var test_year = this.calendarData['y' + this.year];
    var test_month;
    var test_day;

    if (test_year) {
        test_month = test_year['m' + this.month];
        if (test_month) {
            test_day = test_month['d' + day];
        }

    }
    test_year = this.calendarData['y0'];
    if (test_year) {
        test_month = test_year['m' + this.month];
        if (test_month) {
            if (!test_day) test_day = test_month['d' + day];
            else if (test_day.events && test_month['d' + day] && test_month['d' + day].events) {
                test_day = cloneObj(test_day);
                test_day.events = test_day.events.concat(test_month['d' + day].events);
            }
        }

    }

    if (test_day) return test_day;
    return false;
}

Calendar.prototype.generateHTML = function() {
    //close day window
    var divDayCase = $('divDayCase');
    if (divDayCase) {
        divDayCase.style.display = 'none';
    }

    // get first day of month
    var firstDay = new Date(this.year, this.month, 1);
    var startingDay = firstDay.getDay() - 1;
    if (startingDay < 0) {
        startingDay = 6;
    }

    // find number of days in month
    var monthLength = cal_days_in_month[this.month];

    // compensate for leap year
    if (this.month == 1) { // February only!
        if ((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0) {
            monthLength = 29;
        }
    }

    // do the header
    var monthName = cal_months_labels[this.month];

    var html = '<table class="calendar" cellspacing="' + this.cellspacing + '" cellpadding="' + this.cellpadding + '">';
    html += '<tr><th colspan="7" class="title"><img onclick="monthPrev();" class="prev" src="/images/arrowLeft.png" /><span>';
    html += monthName + "&nbsp;" + this.year;
    html += '</span><img class="next" onclick="monthNext();" src="/images/arrowRight.png" /></th></tr>';
    html += '<tr class="header">';
    for (var i = 0; i <= 6; i++) {
        html += '<th>';
        html += cal_days_labels[i];
        html += '</th>';
    }
    html += '</tr><tr class="dayRow" onclick="showDetailedMonth();">';

    // fill in the days
    var day = 1;
    // this loop is for is weeks (rows)
    for (var i = 0; i < 9; i++) {
        // this loop is for weekdays (cells)
        for (var j = 0; j <= 6; j++) {
            if (day <= monthLength && (i > 0 || j >= startingDay)) {
                var objDay = this.hasDay(day);
                var c = "day";
                var todayStyle = "";
                var types = new Object();
                var text = '<div class="dayNum">' + day + "</div>";
                for (typeNum = 0; typeNum < 3; typeNum++)
                    types[typeNum] = false;

                if (objDay) {
                    c = "";
                    for (var ee = 0; ee < objDay.events.length; ee++) {
                        if (objDay.events[ee].isPrimary)
                            c += " type" + objDay.events[ee].type;
                    }
                    if (c == "" && objDay.events.length > 0) c += " type" + objDay.events[0].type;
                }

                if (day == cal_current_date.getDate() && cal_current_date.getMonth() == this.month && cal_current_date.getFullYear() == this.year)
                    c += " today";


                if (objDay || this.admin_mode) {
                    var tooltip = this.getTooltip(day);
                    var onmousemove = '';
                    var onclick = "";

                    if (tooltip.length > 0) {
                        if (this.agendaShowType == "tooltype") {
                            tooltip = tooltip.split("'").join("\\'");
                            if (this.allowDayInfo) {
                                onmousemove = 'onmouseout="UnTip()" onmouseover="Tip(\'' + tooltip + '\', DELAY, 0)"';
                            }
                        }
                        else if (this.agendaShowType == "text") {
                            text += '<div class="agenda">' + tooltip + '</div>';
                        }
                    }

                    if (this.allowDayInfo && this.agendaShowType == "text") {
                        onclick = "showDay(this);";
                        todayStyle += "cursor:pointer;";
                    }

                    html += '<td id="cday' + day + '" style="' + todayStyle + '" onclick="' + onclick + '" class="' + c + '" ' + onmousemove + ' >';
                } else {
                    html += '<td id="cday' + day + '" style="' + todayStyle + '" class="' + c + '">';
                }
                html += text;
                day++;
            } else {
                html += '<td>';
            }
            html += '</td>';
        }
        // stop making rows if we've run out of days
        if (day > monthLength) {
            break;
        } else {
            html += '</tr><tr class="dayRow" onclick="showDetailedMonth();">';
        }
    }
    html += '</tr></table>';
    this.html = html;
}

Calendar.prototype.getHTML = function() {
    return this.html;
}

function changePrimary() {
    $('btnSave').style.display = '';
}

function showDay(obj) {
    var btnSave = $('btnSave');
    var day = obj.id.substr(3);
    var divDayCase = $('divDayCase');
    var divDayForm = $('divDayForm');
    var divDay = $('divDay');
    var row = obj.parentNode; //$$('#divCurrentCalendar table .dayRow')[1];
    var table = row.parentNode.parentNode; //$$('#divCurrentCalendar table')[0];
    var cell = null;
    var topLeftDiv;
    var pos = 0;

    if (divDayCase.style.display == '' && ((divDayForm && divDayForm.style.display == '') || (btnSave && btnSave.style.display == '')))
        return;

    //find cell position
    for (var i = 0; i < row.cells.length; i++) {
        if (row.cells[i] == obj)
            pos = i;
    }

    //find not last position
    if (obj.nextSibling == null) {
        pos--;
    }

    //find not last row
    if (row.nextSibling == null) {
        row = row.previousSibling;
    }

    cell = row.cells[pos];
    topLeftDiv = cell.firstChild;

    var divDayHeader = $('divDayHeader');
    if (divDayHeader && divDayHeader.parentNode) {
        divDayHeader.parentNode.removeChild(divDayHeader);
    }
    divDay.day = day;
    divDay.innerHTML = _calCurrent.getFormatedTooltip(day, true);

    divDayHeader = $('divDayHeader');
    if (divDayHeader) {
        divDay.parentNode.insertBefore(divDayHeader, divDay);
    }

    //divDayCase.style.left = (table.offsetLeft + cell.offsetLeft + topLeftDiv.offsetLeft - 4) + 'px';
    //divDayCase.style.top = (table.offsetTop + cell.offsetTop + topLeftDiv.offsetTop + 4) + 'px';
    divDayCase.style.left = '17%';
    divDayCase.style.top = '12%';
    
    divDayCase.style.height = "";
    divDayCase.style.display = '';

    divDay.style.height = "";
    divDay.style.display = '';

    if (divDayForm) {
        divDayForm.className = 'noDisplay';
    }

    var rowsHeight = table.offsetHeight - table.rows[0].offsetHeight - table.rows[1].offsetHeight - 40;
    while (divDay.offsetHeight < divDay.scrollHeight && divDayCase.offsetHeight < rowsHeight) {
        divDayCase.style.top = (divDayCase.offsetTop - 1) + 'px';
        divDayCase.style.height = (divDayCase.offsetHeight + 2) + 'px';
        divDay.style.height = (divDayCase.offsetHeight - 30) + 'px';
    }

    if (_calCurrent.admin_mode) {
        $('btnEdit').style.display = 'none';
        $('btnDelete').style.display = 'none';
        $('btnSave').style.display = 'none';
        var divSelectedDayEvent = $('divSelectedDayEvent');
        if (divSelectedDayEvent) {
            divSelectedDayEvent.id = '';
        }
        var selYear = $('selYear');
        var currentYear = selYear.options[selYear.options.length - 1];

        currentYear.value = _calCurrent.year;
        currentYear.text = _calCurrent.year;
    }
}

function showDetailedMonth() {
    $('divMonthCase').style.display = '';
}

function selectDiv(obj) {
    var divSelectedDayEvent = $('divSelectedDayEvent');
    if (divSelectedDayEvent) {
        divSelectedDayEvent.id = '';
    }
    obj.id = 'divSelectedDayEvent';
    
    // set checkBoxes
    divSelectedDayEvent.childNodes[0].childNodes[1].checked = false;
    obj.childNodes[0].childNodes[1].checked = true;

    $('btnEdit').style.display = '';
    $('btnDelete').style.display = '';
}

function btnClick(btn) {
    if (!btn || !btn.id) return;
    var divSelectedDayEvent = $('divSelectedDayEvent');
    var selType = $('selType');
    var inpPlace = $('inpPlace');
    var inpNote = $('inpNote');
    var inpTitle = $('inpTitle');
    var selYear = $('selYear');
    var divDay = $('divDay');
    var divDayCase = $('divDayCase');
    var divDayForm = $('divDayForm');
    var divDayHeader = $('divDayHeader');
    var btnSave = $('btnSave');

    switch (btn.id) {
        case 'btnAdd':
            selYear.selectedIndex = 1;
            selType.selectedIndex = 1;
            inpPlace.value = '';
            inpNote.value = '';
            inpTitle.value = '';
            divDay.style.display = 'none';
            divDayForm.className = '';
            divDayForm.style.display = '';
            if (divSelectedDayEvent) divSelectedDayEvent.id = '';
            divDayHeader.style.display = 'none';

            break;

        case 'btnEventOk':

            var e = new Object();
            e.type = selType.value;
            e.notes = inpNote.value.escapeHTML().replace(new RegExp("\r|\n", "ig"), "<br />").replace(new RegExp("<br /><br />", "ig"), "<br />");
            e.title = inpTitle.value;
            e.place = inpPlace.value;

            if (e.notes.length > 1024) {
                alert('Maximum length of field "Note" 1024, but now length ' + e.notes.length);
                return;
            }

            e = _calCurrent._getEventHTML(selYear.value, e, true);
            divDay.innerHTML += e;
            divSelectedDayEvent = $('divSelectedDayEvent');

            e = divDay.lastChild;
            if (divSelectedDayEvent && divSelectedDayEvent.parentNode) {
                var isPrimary = divSelectedDayEvent.firstChild.childNodes[1];
                isPrimary = (isPrimary && isPrimary.checked);

                divDay.insertBefore(e, divSelectedDayEvent);
                divSelectedDayEvent.parentNode.removeChild(divSelectedDayEvent);
                e.firstChild.childNodes[1].checked = isPrimary;
            }
            e.id = 'divSelectedDayEvent';

            if (document.all) {
                for (var i = 0; i < divDay.childNodes.length; i++) {
                    var child = divDay.childNodes[i];
                    if (child && child.type && child.firstChild && child.firstChild.nodeName == 'IMG')
                        child.firstChild.src = 'img/calendar/type' + child.type + '-12.png';
                }
            }
            divDay.style.display = '';
            divDayForm.style.display = 'none';

            $('btnEdit').style.display = '';
            $('btnDelete').style.display = '';
            btnSave.style.display = '';
            divDayHeader.style.display = '';
            break;


        case 'btnEdit':
            if (!divSelectedDayEvent) {
                alert('No selected item to edit.');
                return;
            }

            selYear.selectedIndex = divSelectedDayEvent.getAttribute("year") == 0 ? 0 : 1;
            var type = divSelectedDayEvent.getAttribute("type");
            for (var i = 0; i < selType.options.length; i++)
                if (selType.options[i].value == type) selType.selectedIndex = i;

            inpPlace.value = divSelectedDayEvent.getAttribute("place");
            inpNote.value = divSelectedDayEvent.getAttribute("notes").replace(new RegExp("<br />", "ig"), "\r");
            inpTitle.value = divSelectedDayEvent.getAttribute("title");
            divDay.style.display = 'none';
            divDayForm.className = '';
            divDayForm.style.display = '';
            divDayHeader.style.display = 'none';

            break;

        case 'btnDelete':
            if (!divSelectedDayEvent) {
                alert('No selected item to delete.');
                return;
            }
            btnSave.style.display = '';
            if (divSelectedDayEvent && divSelectedDayEvent.parentNode) {
                divSelectedDayEvent.parentNode.removeChild(divSelectedDayEvent);
            }
            if (divDay.firstChild) divDay.firstChild.id = 'divSelectedDayEvent';
            break;


        case 'btnEventCancel':
        case 'btnDayCancel':
        case 'btnMonthCancel':
            if (((divDayCase == null || divDayCase.style.display == 'none' || btnSave == null || btnSave.style.display == 'none') &
                  btn.id != 'btnEventCancel') || window.confirm('All change in this day will be canceled. Are you sure?')) {
                btn.parentNode.style.display = 'none';
                divDayForm.style.display = 'none';

                selYear.selectedIndex = 1;
                selType.selectedIndex = 1;
                inpPlace.value = '';
                inpNote.value = '';
                inpTitle.value = '';

                if (btn.id == 'btnEventCancel') divDay.style.display = '';
                if (divDayHeader) divDayHeader.style.display = '';
            }
            break;

        case 'btnSave':
            var s = ''
            var arr = divDay.select("div[type]");
            var isPrimaryExists = false;
            for (var i = 0; i < arr.length; i++)
                if (arr[i].firstChild.childNodes[1].checked)
                isPrimaryExists = true;
            if (!isPrimaryExists & arr.length > 0) arr[0].firstChild.childNodes[1].checked = true;

            for (var i = 0; i < arr.length; i++) {
                var e = arr[i];

                var type = e.getAttribute("type");
                var place = e.getAttribute("place").escapeHTML();
                var notes = e.getAttribute("notes").replace(new RegExp("<br />", "ig"), "\r").escapeHTML();
                var year = e.getAttribute("year");
                var title = e.getAttribute("title").escapeHTML();
                var isPrimary = e.firstChild.childNodes[1];
                isPrimary = (isPrimary && isPrimary.checked);


                if (year == null) year = "0";
                s += '<event type="' + type + '" place="' +
                place + '" notes="' +
                notes + '" year="' +
                year + '" title="' + title + '" isPrimary ="' + isPrimary + '" />';
            }
            s = '<root day="' + divDay.day + '" month="' + _calCurrent.month + '" year="' + _calCurrent.year + '">' + s + '</root>';
            $('saveText').value = s;
            document.forms[0].submit();
            break;
    }
}

function cloneObj(objToClone) {
    var clone = [];
    for (i in objToClone) {
        clone[i] = objToClone[i];
    }
    return clone;
}

function getSuffix(number) {
    if (number > 3 && number < 21)
        return "th";
    switch (number - Math.floor(number / 10) * 10) {
        case 1: return "st";
        case 2: return "nd";
        case 3: return "rd";
        default: return "th";
    }
}