(function () {
    "use strict";

    /**
     * Возвращает единицу измерения с правильным окончанием
     * 
     * @param {Number} num      Число
     * @param {Object} cases    Варианты слова {nom: 'час', gen: 'часа', plu: 'часов'} или ["час", "часа", "часов"] или "час, часа, часов"
     * @return {String}            
     */
    function units(num, cases) {
        num = Math.abs(num);
        
        var word = '';

        if ($.type(cases) === "string") {
            cases = cases.split(",");
            cases = $.map(cases, function (item) {
                return item.trim();
            });
        }

        if ($.type(cases) === "array") {
            cases = {
                nom: cases[0] || "",
                gen: cases[1] || "",
                plu: cases[2] || ""
            };
        }
        
        cases.nom = cases.nom || "";
        cases.gen = cases.gen || "";
        cases.plu = cases.plu || "";

        if (num.toString().indexOf('.') > -1) {
            word = cases.gen;
        } else { 
            word = (
                num % 10 === 1 && num % 100 !== 11 
                    ? cases.nom
                    : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) 
                        ? cases.gen
                        : cases.plu
            );
        }
        
        return word;
    }

    $(".timer").ready(function () {
        $(".timer").each(function (value, item) {
            var block = $(item),
                message = block.data("message") || "",
                handler = null,
                endDate = parseInt(block.html());

            if (!block.data("milliseconds")) {
                endDate *= 1000;
            }

            function timerCallback() {
                var now = new Date(),
                    time, days, hours, minutes, seconds;

                function toFormat(param) {
                    return param >= 10 ? param : "0" + param; 
                }
                
                time = endDate - now.getTime();
                if (!parseInt(endDate) || time < 0) {
                    block.html(message);
                    if (handler) {
                        window.clearInterval(handler);
                        handler = null;
                    }
                } else {                
                    days = Math.floor(time / 864e5);
                    hours = Math.floor(time / 36e5) % 24; 
                    minutes = Math.floor(time / 6e4) % 60;
                    seconds = Math.floor(time / 1e3) % 60;  

                    days = toFormat(days);
                    hours = toFormat(hours);
                    minutes = toFormat(minutes);
                    seconds = toFormat(seconds);

                    if (!block.data("units")) {
                        if (parseInt(days)) {
                            block.html(days + "  " + hours + ":" + minutes + ":" + seconds);                        
                        } else {
                            block.html(hours + ":" + minutes + ":" + seconds);
                        }
                    } else {
                        if (parseInt(days)) {
                            block.html(
                                days + " " + units(parseInt(days), "День, Дня, Дней") +
                                " " + hours + " " + units(parseInt(hours), "Час, Часа, Часов") +
                                " " + minutes + " " + units(parseInt(minutes), "Минута, Минуты, Минут") +
                                " " + seconds + " " + units(parseInt(seconds), "Секунда, Секунды, Секунд"));
                        } else {
                            block.html(
                                hours + " " + units(parseInt(hours), "Час, Часа, Часов") +
                                " " + minutes + " " + units(parseInt(minutes), "Минута, Минуты, Минут") +
                                " " + seconds + " " + units(parseInt(seconds), "Секунда, Секунды, Секунд"));
                        }
                    }
                }

            }

            handler = window.setInterval(timerCallback, 1000);
            timerCallback();
        });
    });

}());