
var Namespace = new function() {

    function DigitalClock() {
        this.init_widget();
        this.title = "Digitálne";
        this.last_date = new Date(2000, 0, 1);
        this.timezone_offset = 0;
        this.timezone_name = "Bratislava";
        this.timezone_tzname = "Europe/Bratislava";
        this.next_trans = null;
        this.next_timezone_offset = 0;
    }

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

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

    DigitalClock.prototype.start = function() {
        timeservice.add_listener(this);
    }

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

    DigitalClock.prototype.set_initial_values = function(dct) {
        if (dct.timezone_offset != 'undefined') this.timezone_offset = dct.timezone_offset;
        if (dct.timezone_name != 'undefined') {
            this.timezone_name = dct.timezone_name;
            this.set_timezone_box(dct.timezone_name);
        }
        if (dct.timezone_tzname != 'undefined') {
            this.timezone_tzname = dct.timezone_tzname;
            this.change_timezone(this.timezone_name, this.timezone_tzname);
        }
    }

    DigitalClock.prototype.get_settings = function() {
        var data = "DigitalClock__";
        data += this.timezone_offset + ":";
        data += this.timezone_name + ":";
        data += this.timezone_tzname;
        return escape(data);
    }

    DigitalClock.prototype.set_settings = function(data) {
        var parts = data.split("__", 2);
        if (parts.length < 2) return;
        if (parts[0] != "DigitalClock") return;
        parts = unescape(parts[1]).split(":");
        if (parts.length < 3) return;
        this.timezone_offset = parseInt(parts[0]);
        this.timezone_name = parts[1];
        this.timezone_tzname = parts[2];
        this.set_timezone_box(this.timezone_name);
        this.change_timezone(this.timezone_name, this.timezone_tzname);
    }

    DigitalClock.prototype.build = function() {
        this.core_build();
        this.spolocne = document.createElement("div");
        set_class(this.spolocne, "spolocne");
        this.spolocne.setAttribute("style", "display: none; width: 180px;");
        this.cas = document.createElement("div");
        this.cas.setAttribute("id", "cas");
        this.hodina = document.createElement("span");
        set_class(this.hodina, "hodina");
        this.cas.appendChild(this.hodina);
        var dvojbodka1 = document.createElement("span");
        set_class(dvojbodka1, "dvojbodka");
        dvojbodka1.innerHTML = ":";
        this.cas.appendChild(dvojbodka1);
        this.minuta = document.createElement("span");
        set_class(this.minuta, "minuta");
        this.cas.appendChild(this.minuta);
        var dvojbodka2 = document.createElement("span");
        set_class(dvojbodka2, "dvojbodka");
        dvojbodka2.innerHTML = ":";
        this.cas.appendChild(dvojbodka2);
        this.sekunda = document.createElement("span");
        set_class(this.sekunda, "sekunda");
        this.cas.appendChild(this.sekunda);
//        var stobodka = document.createElement("span");
//        set_class(stobodka, "stobodka");
//        stobodka.innerHTML = " . ";
//        this.cas.appendChild(stobodka);
//        this.milisek = document.createElement("span");
//        set_class(this.milisek, "milisek");
//        this.cas.appendChild(this.milisek);
        this.spolocne.appendChild(this.cas);

        this.date_box = document.createElement("span");
        set_class(this.date_box, "date_box");
        this.spolocne.appendChild(this.date_box);

        this.tzinfo_box = document.createElement("span");
        set_class(this.tzinfo_box, "tzinfobox");
        this.spolocne.appendChild(this.tzinfo_box);

        this.tzinfo_icon = document.createElement("img");
        set_class(this.tzinfo_icon, "tzinfo_icon");
        jQuery(this.tzinfo_icon).attr('src', '/images/warning.png');
        this.spolocne.appendChild(this.tzinfo_icon);

        this.timezonebox = document.createElement("span");
        set_class(this.timezonebox, "timezonebox");
        this.timezonebox_a = document.createElement("a");
        set_class(this.timezonebox_a, "button");
        this.timezonebox_a.onclick = callback(this.timezone_click, {bind: this})
        this.timezonebox_span = document.createElement("span");
        this.set_timezone_box(this.timezone_name);
        this.timezonebox_a.appendChild(this.timezonebox_span);
        this.timezonebox.appendChild(this.timezonebox_a);
        this.spolocne.appendChild(this.timezonebox);

        this.canvas_div.appendChild(this.spolocne);

        var self = this;
        jQuery(this.tzinfo_icon).tipsy({gravity: 'n', html: true, trigger: 'manual', title: function() {
            return self.get_timeshift_tooltip();
            }
        });
    }

    function zeroize(number, places) {
        var text = number + '';
        while (text.length < places) {
            text = '0' + text;
        }
        return text;
    }

    DigitalClock.prototype.timeservice_callback = function(ts) {
        var date = ts.ticked_date;
        this.update_values(date);
        this.last_date = date;
        if (this.next_trans) {
            if (this.next_trans_date < date) {
                this.next_trans = null;
                this.next_trans_date = null;
                this.timezone_offset = this.next_timezone_offset;
                var self = this;
                // in case of time shift, wait randomly 100 - 600 seconds before updating timezone data from server
                setTimeout(function() { self.refresh_timezone(self.timezone_tzname); }, (100 + Math.random(500)) * 1000);
            }
        }
    }

    DigitalClock.prototype.get_timeshift_text = function(curtime) {
        if (! this.next_trans) return '';       // unknown next transition, return empty text
        var date_ts = new Date();
        date_ts.setTime((this.next_trans + this.timezone_offset) * 1000);
        var days_diff = (this.next_trans - (curtime / 1000)) / 86400;
        if (days_diff < 0) return '';           // if it's already in past, return empty text
        if (days_diff > 60) return '';          // more than 60 days in future, return empty text
        if (days_diff >= 8) return 'Posun času: ' + date_ts.getUTCDate() + '.' + (date_ts.getUTCMonth() + 1) + '. o ' + zeroize(date_ts.getUTCHours(), 2) + ':' + zeroize(date_ts.getUTCMinutes(), 2);
        if (days_diff >= 5) return 'Posun času o ' + Math.floor(days_diff) + ' dní';
        if (days_diff >= 2) return 'Posun času o ' + Math.floor(days_diff) + ' dni';
        var hours_diff = days_diff * 24;
        if (hours_diff >= 5) return 'Posun času o ' + Math.floor(hours_diff + 0.5) + ' hodín';
        if (hours_diff >= 1) return 'Posun času o ' + Math.floor(hours_diff) + 'h ' + Math.floor((hours_diff * 60 + 0.5) % 60) + 'min';
        var mins_diff = hours_diff * 60;
        if (mins_diff >= 5) return 'Posun času o ' + Math.floor(mins_diff + 0.5) + ' minút';
        return 'Posun času o ' + zeroize(Math.floor(mins_diff), 2) + ':' + zeroize(Math.floor((mins_diff * 60 + 1) % 60), 2);
    }

    DigitalClock.prototype.get_timeshift_text_for_tooltip = function(curtime) {
        if (! this.next_trans) return '';       // unknown next transition, return empty text
        var date_ts = new Date();
        date_ts.setTime((this.next_trans + this.timezone_offset) * 1000);
        var days_diff = (this.next_trans - (curtime / 1000)) / 86400;
        if (days_diff < 0) return '';           // if it's already in past, return empty text
        if (days_diff > 60) return '';          // more than 60 days in future, return empty text
        return 'Posun času: ' + date_ts.getUTCDate() + '.' + (date_ts.getUTCMonth() + 1) + '.' + date_ts.getUTCFullYear();
    }

    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 nice_date(date) {
        //return date.getUTCDate() + '. ' + nazvi_mesiac(date.getUTCMonth());
        return date.getUTCDate() + '. ' + nazvi_mesiac(date.getUTCMonth()) + ' ' + date.getUTCFullYear();
    }

    DigitalClock.prototype.get_timeshift_tooltip = function() {
        if (! this.next_trans) return '';
        if (! this.tzinfo_box.innerHTML) return '';

        var ts_text = this.get_timeshift_text_for_tooltip(this.last_date.getTime());

        var date_ts = new Date((this.next_trans + this.timezone_offset) * 1000);
        var date_ts_next = new Date((this.next_trans + this.next_timezone_offset) * 1000);
        var text = 'Zmena o ' + zeroize(date_ts.getUTCHours(), 2) + ':' + zeroize(date_ts.getUTCMinutes(), 2) + ' na ' +
                   zeroize(date_ts_next.getUTCHours(), 2) + ':' + zeroize(date_ts_next.getUTCMinutes(), 2);
        return ts_text + '<br />' + text;
    }

    DigitalClock.prototype.update_values = function(normdate) {
        var curtime = normdate.getTime();
        var date = new Date();
        date.setTime(curtime + this.timezone_offset * 1000);

        this.odhal();
        this.hodina.innerHTML = zeroize(date.getUTCHours(), 2);
        this.minuta.innerHTML = zeroize(date.getUTCMinutes(), 2);
        this.sekunda.innerHTML = zeroize(date.getUTCSeconds(), 2);
        //this.milisek.innerHTML = Math.floor(date.getUTCMilliseconds()/100.0);
        var timeshift_text = this.get_timeshift_text(curtime);
        this.tzinfo_box.innerHTML = timeshift_text;
        if (timeshift_text) {
            jQuery(this.tzinfo_icon).show();
        } else {
            jQuery(this.tzinfo_icon).hide();
        }
        this.date_box.innerHTML = nice_date(date);
    }

    DigitalClock.prototype.process_timezone_data = function(timezone_data) {
        var data = eval(timezone_data);
        this.timezone_offset = data.offset;
        this.next_trans = data.next_trans;
        this.next_trans_date = new Date(this.next_trans * 1000);
        this.next_timezone_offset = data.next_offset;
        this.set_timezone_box(this.timezone_name);
        var date = this.last_date;
        this.update_values(date);
        this.emit_settings_changed();
    }

    DigitalClock.prototype.refresh_timezone = function(timezone_tzname) {
        jQuery.ajax({
            url: '/get_tz?tzname=' + timezone_tzname,
            context: this,
            success: function(data) {
                this.process_timezone_data(data);
            },
            error: function(jqXHR, status, error_thrown) {
                this.set_timezone_box('Chyba');
            }
        });
    }

    DigitalClock.prototype.change_timezone = function(timezone_name, timezone_tzname) {
        this.refresh_timezone(timezone_tzname);
        this.timezone_name = timezone_name;
        this.timezone_tzname = timezone_tzname;
        this.set_timezone_box('Načítavam...');
    }

    DigitalClock.prototype.timezone_chosen = function(originator) {
        this.change_timezone(originator.timezone_name, originator.timezone_tzname);
    }

    DigitalClock.prototype.timezone_click = function(evt) {
        new TimeZoneChooser(this.canvas_div, callback(this.timezone_chosen, {bind: this}));
    }

    DigitalClock.prototype.odhal = function() {
        this.spolocne.style.display = "";
    }

    DigitalClock.prototype.set_timezone_box = function(name) {
        this.timezonebox_span.innerHTML = name + ' ▼';
    }

    return {
        DigitalClock: DigitalClock
    }
}

register_widget(Namespace.DigitalClock);

