var SimpleCalendar = Class.create({

    /*
    * initialDate: ennek a honapjat rajzoljuk ki
    * selectedDate: ez lesz beszinezve
    *
    *
    */

    initialize: function( containerElement ) {
        this.containerElement = containerElement;
        this.options = Object.extend({
            onCalChange: Prototype.emptyFunction,
            initialDate: new Date(),
            selectedDate: undefined,
            weekdaystart: 1,
            dateRangeStart: new Date(),
            dateRangeEnd: new Date(2147483648000),
            highlightSelectedDate: true,
            daynames: ['V','H','K','Sz','Cs','P','Sz']
        }, arguments[1] || { });
        this.html = '';
        this.currentDate = new Date();
        this.options.dateRangeEnd.setTime(this.options.dateRangeEnd.getTime());
        this._resetDate(this.options.dateRangeStart);
        this._resetDate(this.options.dateRangeEnd);

        //http://prototypejs.org/api/event/stopObserving
        this._onClickCallbackBackup = this._onClickCallback.bind(this);

        this.render();
    },

    render: function() {
        var html = '';
        html += '<table class="cal_table"><tbody>';
        html += this._buildDayNames();
        html += this._buildMonth();
        html += '</tbody></table>';


        this.containerElement.innerHTML = html;
        this.selectedDateElement = $(this.containerElement).down('td.dayselected');

        Event.stopObserving(this.containerElement, 'click', this._onClickCallbackBackup);
        Event.observe(this.containerElement, 'click', this._onClickCallbackBackup);
    },

    nextMonth: function() {
        if(this.options.initialDate.getMonth() < 11) {
            this.options.initialDate.setMonth(this.options.initialDate.getMonth()+1);
        }else{
            this.options.initialDate.setMonth(0);
            this.options.initialDate.setFullYear(this.options.initialDate.getFullYear()+1);
        }
        this.render();
    },

    prevMonth: function() {
        if(this.options.initialDate.getMonth() > 0){
            this.options.initialDate.setMonth(this.options.initialDate.getMonth()-1);
        }else{
            this.options.initialDate.setMonth(11);
            this.options.initialDate.setFullYear(this.options.initialDate.getFullYear()-1);
        }
        this.render();
    },

    _onClickCallback: function(e) {
        if(e.target.tagName.toLowerCase() != 'div'){
            return;
        }
        if(!($(e.target).up().hasClassName('intherange') && $(e.target).up().hasClassName('dayinmonth'))){
            return;
        }

        var dateClass = $(e.target).classNames().find(function(className){
            return className.indexOf('date_') != -1 ? true : false;
        });
        this.options.selectedDate = new Date(Number(dateClass.slice(5,9)), Number(dateClass.slice(9,11))-1, Number(dateClass.slice(11,13)));
        if(this.selectedDateElement){
            this.selectedDateElement.removeClassName('dayselected');
        }
        this.selectedDateElement = $(e.target).up().addClassName('dayselected');
        this.options.onCalChange(this.options.selectedDate);
    },

    _resetDate: function(d) {
        d.setHours(0);
        d.setMinutes(0);
        d.setSeconds(0);
        d.setMilliseconds(0);
    },

    _arrayRotate: function(a, p){
        //+ Jonas Raoni Soares Silva
        //@ http://jsfromhell.com/array/rotate [v1.1]
        for(var l = a.length, p = (Math.abs(p) >= l && (p %= l), p < 0 && (p += l), p), i, x; p; p = (Math.ceil(l / p) - 1) * p - l + (l = p))
            for(i = l; i > p; x = a[--i], a[i] = a[i - p], a[i - p] = x);
        return a;
        return [];
    },

    _buildDayNames: function() {
        var html = '';
        var days = this.options.daynames.clone();

        if(this.options.weekdaystart != 0) {
            days = this._arrayRotate(days, this.options.weekdaystart*-1);
        }

        html += '<tr class="weekbox weekboxname">';
        days.each( function(el, idx) {
            html += '<td class="daybox dayboxname">' + el + '</td>';
        });
        html += '</tr>';

        return html;
    },

    _buildMonth: function() {
        var html = '';
        var firstOfMonth = new Date(this.options.initialDate.getFullYear(),this.options.initialDate.getMonth(),1);
        //elseje
        this.currentDate.setFullYear(this.options.initialDate.getFullYear());
        this.currentDate.setMonth(this.options.initialDate.getMonth());
        this.currentDate.setDate(1);
        this.currentDate.setHours(0);
        this.currentDate.setMinutes(0);
        this.currentDate.setSeconds(0);

        if(firstOfMonth.getDay() != this.options.weekdaystart){
            //hetElsoNapja = elseje-(elseje-elsoNap)
            var diffTime = (this.currentDate.getDay() - this.options.weekdaystart)*24*3600*1000;
            if(diffTime < 0) {
                diffTime = (7*24*3600*1000)+diffTime;
            }
            this.currentDate.setTime( this.currentDate.getTime() - diffTime );
        }

        //week
        for(var w=0; w<6; w++){
            html += this._buildWeek(w);
        }

        return html;
    },

    _buildWeek: function(week) {
        var html = '';
        var trClasses = [];

        trClasses.push('cal_week_' + week);
        trClasses.push('weekbox');

        html += '<tr class="' + trClasses.join(' ') + '">';
        for(var d=0; d<7; d++){
            html += this._buildDay();
        }
        html += '</tr>';

        return html;

    },

    _buildDay: function() {
        this._resetDate(this.currentDate);
        var html = '';
        var cd = this.currentDate;
        var initd = this.options.initialDate;
        var dayClasses = ['dayboxsunday','dayboxmonday','dayboxtuesday','dayboxwednesday','dayboxthursday','dayboxfriday','dayboxsaturday'];
        var tdClasses = [];
        var divClasses = [];
        var inTheRange = cd.getTime() >= this.options.dateRangeStart.getTime() && cd.getTime() <= this.options.dateRangeEnd.getTime() ? true : false;
        var dayInMonth = cd.getMonth() == initd.getMonth() ? true : false;
        var now = new Date();

        tdClasses.push('daybox');
        tdClasses.push(dayClasses[this.currentDate.getDay()]);
        tdClasses.push(dayInMonth ? 'dayinmonth' : 'dayoutmonth');
        tdClasses.push(
            now.getFullYear() == cd.getFullYear() &&
            now.getMonth() == cd.getMonth() &&
            now.getDate() == cd.getDate()
            ? 'currentdate' : ''
        );

        if(this.options.selectedDate){
            tdClasses.push(
                dayInMonth &&
                this.options.selectedDate.getFullYear() == cd.getFullYear() &&
                this.options.selectedDate.getMonth() == cd.getMonth() &&
                this.options.selectedDate.getDate() == cd.getDate() &&
                this.options.highlightSelectedDate ? 'dayselected' : ''
            );
        }
        tdClasses.push(inTheRange ? 'intherange' : 'outofrange');

        divClasses.push('dayboxdate');
        divClasses.push('date_' + String(cd.getFullYear()) + (cd.getMonth()+1).toPaddedString(2) + String(cd.getDate().toPaddedString(2)));

        divHandlers = inTheRange && dayInMonth ? ' onmouseover="$(this).addClassName(\'hover\')" onmouseout="$(this).removeClassName(\'hover\')"' : '';

        html += '<td class="' + tdClasses.join(' ') + '"><div class="' + divClasses.join(' ') + '"' + divHandlers + '">' + this.currentDate.getDate() + '</div></td>';
        this.currentDate.setTime(this.currentDate.getTime()+24*3600*1000);

        return html;
    }
});