
var Namespace = new function() {

    function Calendar() {
        this.init_widget();
        this.title = "Kalendár";
        this.rows = null;
        this.last_date = new Date(2000, 0, 1);
        this.spolocne = null;
        this.timezone_offset = -3600;
        this.meniny = {};
        this.dirty = false;
        this.week_number = null;
        this.day_of_year = null;
    }

    Calendar.prototype = new Widget;
    Calendar.name = "Calendar";

    Calendar.prototype.init = function(div_name) {
        this.div_name = div_name;
    }

    Calendar.prototype.start = function() {
        timeservice.add_listener(this);
        var date = new Date();
        this.fetch_nameday(date.getDate(), date.getMonth() + 1);
        this.fetch_nameday(date.getDate() + 1, date.getMonth() + 1);
        this.fetch_nameday(date.getDate() + 2, date.getMonth() + 1);
    }

    Calendar.prototype.process_nameday = function(nmd_data) {
        var data = eval(nmd_data);
        var names = data.names;
        this.meniny[data.month + '_' + data.day] = names;
        this.dirty = true;
    }

    Calendar.prototype.stop = function() {
        timeservice.remove_listener(this);
    }

    Calendar.prototype.build = function() {
        this.core_build();
    }

    Calendar.prototype.build_inside = function(date) {
        //date = new Date(date.getTime() + (Math.random() * 5) * 100000000);
        this.create_datum_text(date);
        this.calc(date);
        this.spolocne = document.createElement("div");
        set_class(this.spolocne, "spolocne");
        this.spolocne.setAttribute("style", "width: 180px;");

        this.build_datum();
        this.build_calendar();
        this.build_meniny(date);
        this.canvas_div.appendChild(this.spolocne);
        var randomnumber;
        var color = '';
        randomnumber = Math.floor(Math.random()*100) + 155;
        color += randomnumber.toString(16);
        randomnumber = Math.floor(Math.random()*100) + 155;
        color += randomnumber.toString(16);
        randomnumber = Math.floor(Math.random()*100) + 155;
        color += randomnumber.toString(16);
//        this.canvas_div.style.backgroundColor = color;

//        this.nazov_dna.innerHTML = nazvi_den(date.getUTCDay());
//        this.den_a_mesiac.innerHTML = date.getUTCDate() + ". " + nazvi_mesiac(date.getUTCMonth());
    }

    Calendar.prototype.build_datum = function() {
        var text = document.createElement("span");
        set_class(text, "cal_datum_text");
        text.innerHTML = this.datum_text;
        var text2 = document.createElement("span");
        set_class(text2, "cal_datum_text2");
        text2.innerHTML = this.datum_text2;
        this.spolocne.appendChild(text);
        //this.spolocne.appendChild(text2);
    }

    Calendar.prototype.build_calendar = function() {
        var tabulka = document.createElement("div");
        set_class(tabulka, "cal_tabulka");
        tabulka.style.position = "absolute";
        for (var x=0; x<7; x++) {
            var bunka = document.createElement("div");
            var klass = 'cal_dow';
            bunka.style.position = "absolute";
            bunka.style.left = x*20 + "px";
            bunka.style.top = 0 + "px";
            bunka.style.width = "20px";
            bunka.style.height = "16px";
            bunka.innerHTML = nazvi_den_kratko(x);
            set_class(bunka, klass);
            tabulka.appendChild(bunka);
        }
        for (var y=0; y<this.rows.length; y++) {
            for (var x=0; x<7; x++) {
                var bunka = document.createElement("div");
                bunka.style.position = "absolute";
                bunka.style.left = x*20 + "px";
                bunka.style.top = (y*16+20) + "px";
                bunka.style.width = "20px";
                bunka.style.height = "16px";
                var klass = 'cal_day ';
                var day = this.rows[y][x];
                if (day.day) {
                    bunka.innerHTML = day.day;
                    if (day.today) {
                        klass += 'cal_today ';
                    }
                }
                set_class(bunka, klass);
                tabulka.appendChild(bunka);
            }
        }
        this.spolocne.appendChild(tabulka);
    }

    Calendar.prototype.build_meniny = function(date) {
        var meniny_today = this.get_meniny(date);
        var meniny_tomorrow = this.get_meniny(new Date(date.getTime() + 86400 * 1000));
        if (!(meniny_today && meniny_tomorrow))
            return;
        var meniny = document.createElement("span");
        set_class(meniny, "cal_meniny_text");
        var meniny_text1 = document.createTextNode("Meniny dnes: ");
        var meniny_meniny1 = document.createElement("span");
        set_class(meniny_meniny1, "cal_meniny_name");
        meniny_meniny1.innerHTML = meniny_today;
        var meniny_br = document.createElement("br");
        var meniny_text2 = document.createTextNode("Meniny zajtra: ");
        var meniny_meniny2 = document.createElement("span");
        set_class(meniny_meniny2, "cal_meniny_name");
        meniny_meniny2.innerHTML = meniny_tomorrow;
        meniny.appendChild(meniny_text1);
        meniny.appendChild(meniny_meniny1);
        meniny.appendChild(meniny_br);
        meniny.appendChild(meniny_text2);
        meniny.appendChild(meniny_meniny2);
        this.spolocne.appendChild(meniny);
    }

    Calendar.prototype.get_meniny = function(date) {
        var day = date.getDate();
        var month = date.getMonth() + 1;
        var names = this.meniny[month + "_" + day];
        if (names == undefined) {
            this.fetch_nameday(day, month);
            return undefined;
        }
        return names;
    }

    Calendar.prototype.timeservice_callback = function(ts) {
        var date = ts.ticked_date;
        if (date.getUTCSeconds() == this.last_date.getUTCSeconds()) {
            return;
        }
        if (this.dirty) {
            this.dirty = false;
            this.update_values(date);
            this.last_date = date;
            return;
        }
        if (date.getUTCDate() == this.last_date.getUTCDate()) {
            return;
        }
        this.update_values(date);
        this.last_date = date;
    }

    Calendar.prototype.update_values = function(normdate) {
        var curtime = normdate.getTime();
        var date = new Date(curtime + this.timezone_offset * 1000);
        if (this.spolocne) {
            this.canvas_div.removeChild(this.spolocne);
            this.spolocne = null;
        }
        this.build_inside(date);
    }

    Calendar.prototype.calc_week0 = function(date) {
        var onejan = new Date(date.getFullYear(), 0, 1);
        return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
    }

    Calendar.prototype.calc_week = function(date, dowOffset) {
        /* getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com
         * dowOffset is the day of week - the week "starts" on for your locale - it can be from 0 to 6.
         * If dowOffset is 1 (Monday), the week returned is the ISO 8601 week number. */

        dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
        var newYear = new Date(date.getFullYear(), 0, 1);
        var day = newYear.getDay() - dowOffset; //the day of week the year begins on
        day = (day >= 0 ? day : day + 7);
        var daynum = Math.floor((date.getTime() - newYear.getTime() - (
            date.getTimezoneOffset() - newYear.getTimezoneOffset()) * 60000) / 86400000) + 1;
        var weeknum;
        // if the year starts before the middle of a week
        if (day < 4) {
            weeknum = Math.floor((daynum + day - 1) / 7) + 1;
            if (weeknum > 52) {
                nYear = new Date(date.getFullYear() + 1, 0, 1);
                nday = nYear.getDay() - dowOffset;
                nday = nday >= 0 ? nday : nday + 7;
                /* if the next year starts before the middle of the week, it is week #1 of that year */
                weeknum = nday < 4 ? 1 : 53;
            }
        }
        else
            weeknum = Math.floor((daynum + day - 1) / 7);
        return weeknum;
    }

    function nazvi_den_kratko(cislo) {
        var nazvy_dni = new Array("Po", "Ut", "St", "Št", "Pi", "So", "Ne");
        return nazvy_dni[cislo];
    }

    function nazvi_den(cislo) {
        var nazvy_dni = new Array("Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota");
        return nazvy_dni[cislo];
    }

    function nazvi_mesiac(cislo) {
        var nazvy_mesiacov = new Array("január", "február", "marec", "apríl", "máj", "jún", "júl", "august", "september", "október", "november", "december");
        return nazvy_mesiacov[cislo];
    }

    function Day(day) {
        this.day = day;
    }

    function daysInMonth(month, year) {
        var dd = new Date(year, month, 0);
        return dd.getDate();
    }

    Calendar.prototype.create_datum_text = function(date) {
        this.datum_text = nazvi_den(date.getDay()) + ", " + date.getDate() + ". " + nazvi_mesiac(date.getMonth()) + " " + date.getFullYear();
        //this.datum_text2 = "Týždeň " + this.week_number + " | Deň " + this.day_of_year;
    }

    Calendar.prototype.fetch_nameday = function(day, month) {
        jQuery.ajax({
            url: '/get_nmd?day=' + day + "&month=" + month,
            context: this,
            success: function(data) {
                this.process_nameday(data);
            },
            error: function(jqXHR, status, error_thrown) {
                this.set_timezone_box('Chyba');
            }
        });
    }

    Calendar.prototype.calc = function(date) {
        var day_today = date.getDate();
        var days = daysInMonth(date.getMonth() + 1, date.getFullYear());
        var first_date = new Date(date.getTime());
        first_date.setDate(1);
        var dow = first_date.getDay();
        if (dow == 0) dow = 7;
        dow -= 1;
        var x = 0;
        var y = 0;
        var rows = new Array();
        var col = new Array();

        function add_day(day) {
            if (x >= 7) {
                col = new Array();
                rows.push(col);
                y += 1;
                x = 0;
            }
            col.push(day);
            x += 1;
        }

        rows.push(col);
        for (var i=0; i<dow; i++) {
            add_day(new Day(0));
        }

        for (var i=1; i<=days; i++) {
            day = new Day(i);
            if (i == day_today) {
                day.today = true;
            }
            add_day(day);
        }

        for (var i=x; i<7; i++) {
            add_day(new Day(0));
        }

        this.rows = rows;
    }

    return {
        Calendar: Calendar
    }
}

register_widget(Namespace.Calendar);

