function dCalendarClass() {
    this.holderId = 'news_calendar_holder';
    this.calendarHolder = {};
    this.items = {};
    this.activeId = 0;

    this.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    this.monthNames = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
    this.setDate();
}

dCalendarClass.prototype.setDate = function(stamp) {
    if (stamp && (typeof(stamp) != 'undefined') && (stamp > 0)) {
        this.curDate = new Date(stamp * 1000);
    } else {
        this.curDate = new Date(); /* Now */
    }

    this.countFebruary();
}

dCalendarClass.prototype.addItem = function(item) {
    if (item && (typeof(item) != 'undefined') && (item.stamp > 0)) {
        var dt = new Date(item.stamp * 1000);

        this.items[dt.getFullYear() + '-' + dt.getMonth() + '-' + dt.getDate()] = item;
    }
}

dCalendarClass.prototype.print = function(firstLaunch) {
    var firstWD = false;
    var lastWD = false;
    var active = false;
    var i = 0;

    /* Leading empty day placeholders */
    var dt = new Date(this.curDate.getFullYear(), this.curDate.getMonth(), 1, 0, 0, 0);
    var introEmptyDays = dt.getDay() - 1;
    if (introEmptyDays < 0) {
        introEmptyDays = 6;
    }

    /* Ending empty day placeholders */
    var outroEmptyDays = 7 - ((this.daysInMonth[this.curDate.getMonth()] + introEmptyDays) % 7);
    if (outroEmptyDays == 7) {
        outroEmptyDays = 0;
    }

    if (typeof(firstLaunch) == 'undefined') {
        firstLaunch = false;
    }

    var item = {};

    this.calendarHolder = $('#' + this.holderId);

    if (this.calendarHolder.length == 1) {
        var year = this.curDate.getFullYear();
        var mnth = this.curDate.getMonth();

        if (mnth < 11) {
            var nextMnth = mnth + 1;
            var nextYear = year;
        } else {
            var nextMnth = 0;
            var nextYear = year + 1;
        }

        if (mnth > 0) {
            var prevMnth = mnth - 1;
            var prevYear = year;
        } else {
            var prevMnth = 11;
            var prevYear = year - 1;
        }

        var html = '<a href="#" class="cal_list list_up" onclick="return dCalendar.prevMonth();"><span>&uarr;</span></a>';
        html += '<ul><li><dl class="click clearfix" onclick="return dCalendar.prevMonth();"><dt>' + prevYear + '</dt><dd>' + this.monthNames[prevMnth] + '</dd></dl></li>';

        html += '<li class="act"><dl class="clearfix"><dt>' + year + '</dt><dd>' + this.monthNames[mnth] + '</dd></dl>';
        html += '<table><tr><th>Пн</th><th>Вт</th><th>Ср</th><th>Чт</th><th>Пт</th><th>Сб</th><th class="last">Вс</th></tr>';

        if (introEmptyDays > 0) {
            html += '<td>';
            for (i = 1; i < introEmptyDays; i++) {
                html += '<td><span></span></td>';
            }
        }

        for (i = 1; i <= this.daysInMonth[this.curDate.getMonth()]; i++) {
            firstWD = (((i + introEmptyDays) % 7) == 1);
            lastWD = (((i + introEmptyDays) % 7) == 0);

            item = this.items[this.curDate.getFullYear() + '-' + this.curDate.getMonth() + '-' + i];
            if (item && (typeof(item) != 'undefined')) {
                active = (this.activeId == item.id);
            } else {
                active = false;
            }

            if (firstWD) {
                html += '<tr>';
            }

            if (active) {
                html += '<td class="act' + (lastWD ? ' last' : '') + '">';
            } else {
                html += '<td' + (lastWD ? ' class="last"' : '') + '>';
            }
            if (item && (typeof(item) != 'undefined')) {
                html += '<a href="' + item.path + '"><span>' + i + '</span></a>';
            } else {
                html += '<span>' + i + '</span>';
            }
            html += '</td>';

            if (lastWD) {
                html += '</tr>';
            }
        }

        if (outroEmptyDays > 0) {
            for (i = 1; i < outroEmptyDays; i++) {
                html += '<td><span></span></td>';
            }
            html += '<td class="last"><span></span></td></tr>';
        }

        html += '</table></li>';

        html += '<li><dl class="click clearfix" onclick="return dCalendar.nextMonth();"><dt>' + nextYear + '</dt><dd>' + this.monthNames[nextMnth] + '</dd></dl></li></ul>';
        html += '<a href="#" class="cal_list list_down" onclick="return dCalendar.nextMonth();"><span>&darr;</span></a>';

        this.calendarHolder.html(html);
    }
}

dCalendarClass.prototype.prevMonth = function() {
    var year = this.curDate.getFullYear();
    var mnth = this.curDate.getMonth();

    if (mnth > 0) {
        this.curDate = new Date(year, mnth - 1, 1);
    } else {
        this.curDate = new Date(year - 1, 11, 1);
    }

    this.countFebruary();

    this.print();

    return false;
}

dCalendarClass.prototype.nextMonth = function() {
    var year = this.curDate.getFullYear();
    var mnth = this.curDate.getMonth();

    if (mnth < 11) {
        this.curDate = new Date(year, mnth + 1, 1);
    } else {
        this.curDate = new Date(year + 1, 0, 1);
    }

    this.countFebruary();

    this.print();

    return false;
}

dCalendarClass.prototype.countFebruary = function() {
    this.daysInMonth[1] = (this.curDate.getFullYear() % 4) ? 28 : 29;
}

dCalendarClass.prototype.proto = function() {
}

var dCalendar = new dCalendarClass();

$(document).ready(function() {
    dCalendar.print(true);
});
