/**
 * Возвращает перевод для строки, либо undefined, если ничего не найдено
 * Отличается от дефолтного вызова i18n тем, что не выкидывает ошибок при отсутствии перевода
 * @param {String} key ключ
 * @return {String} перевод
 */
var _i18n = function(key) {
    var res;
    if (typeof i18n.time.common[key] === 'function') {
        try {
            res = i18n.time.common[key]();
        } catch (x) {
            console.warn('Got error while translating '+key, x);
            res = undefined;
        }
    } else {
        console.warn('key '+key+' not found in translations');
    }
    return res;
};


/**
 * Подгружает JS с локализацией. Если вызвать без параметров, то будет пытаться взять язык из урла
 * @param {String} [lang] - язык с локализацией.
 */
var _yaWidgetLocale = function(lang, callback) {
    var self = this;
    var loadJS = function() {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = '/i18n/'+lang+'/_time.common.js';
        if (script.readyState){  //IE
            script.onreadystatechange = function(){
                if (script.readyState == "loaded" ||
                    script.readyState == "complete"){
                    script.onreadystatechange = null;
                    callback(lang);
                }
            };
        } else {
            script.onload = function(){
                callback(lang);
            };
        }
        document.getElementsByTagName("head")[0].appendChild(script);
    };

    var parseURL = function(i, max, tmp) {
        var pairs = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for (i = 0, max = pairs.length; i < max; i++) {
            tmp = pairs[i].split('=');
            if (tmp[0] == 'lang') {
                return decodeURIComponent(tmp[1]);
            }
        }
        return null;
    };

    if (!lang) {
        lang = parseURL();
        if (!lang || $.inArray(lang, ['en','ru','tt','be','tr','uk','kk']) == -1) {
            lang = 'ru'; //default
        }
    }

    loadJS();
    return lang;
};

var _yaWidgetInit = function(lang) {
    if (widget.fake) {
        $(function() { widget.clock.preInit(lang); });
    } else {
        widget.clock.preInit(lang);
    }
};

/**
 * Если существует widget, то делаем вывод, что нас запустили с морды яндекса,
 * иначе вставляем методы заглушки
 */

if (typeof widget == "undefined") {
    widget = { adjustIFrameHeight: function(){} }; // dumb wrapper
    widget.fake = 1;
    _yaWidgetLocale(null, _yaWidgetInit);
} else {
    _yaWidgetLocale(widget.getLocale(), _yaWidgetInit);
}

widget.clock = {
    _syncUrl: 'http://'+location.hostname+'/async/sync.json.xml',
    params  :{},

    /**
     * Дергает ручку на предмет получения геоданных
     * @param {Number}   geoID
     * @param {Function} callback
     * @return {Object} в случаем успеха дёргает callback с геопараметрами
     */
    getGeoData: function(geoID, callback) {
        var self = this;
        geoID = geoID.replace(/\s/, '+');
        $.ajax({
                   url: widget.clock._syncUrl,
                   dataType: 'json',
                   type: 'GET',
                   data: { geo: geoID, lang: self._lang},
                   timeout: 1000,
                   context: self,
                   success: function(data) {
                       callback.apply(self, [data]);
                   }
         });
    },

    /**
     * Парсит URL на предмет наличия в нём знакомых виджету параметров.
     * Список "знакомых" параметров захардкожен
     * @return {Object} - объект с опознанными параметрами
     */
    parseUrlParams: function() {
        var parseString = function(pairs) {
            var res = {},
            i = 0,
            max = 0,
            tmp = '',
            knownParams = { theme: 1, geoid: 1, comment: 1, layout: 1 };

            for (i = 0, max = pairs.length; i < max; i++) {
                tmp = pairs[i].split('=');
                if (knownParams.hasOwnProperty(tmp[0])) {
                    res[tmp[0]] = decodeURIComponent(tmp[1]);
                    if (tmp[0] === 'comment') {
                        res[tmp[0]] = res[tmp[0]].replace(/_amp_/g, '&');
                    }
                }
            }
            return res;
        };
        return parseString(window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'));

    },

    /**
     * Получение и проверка параметров.
     * Как только данные получены - запускает финальную инициализацию
     * @param {String} lang - язык локализации
     */
    preInit: function(lang) {
        var defaults = {},
        i = 0,
        p,
        numericParams = ['offset', 'now'];

        this.params = widget.clock.parseUrlParams();

        // язык
        this._lang = lang;
        $('html').attr('lang', this._lang);

        // adding Date.now() to IE
        if (typeof Date.now !== 'function') {
            Date.now = function() {
                return new Date().getTime();
            };
        }

        defaults = {
            now: new Date().getTime(), // can't used Date.now here. IE dies
            offset: new Date().getTimezoneOffset() * - 60000,  // user timezone
            theme: 'analog',
            sunrise: 0,
            sunset: 0,
            isNight: false
        };

        for (p in defaults) {
            if (defaults.hasOwnProperty(p)) {
                if (this.params[p] === undefined) {
                    this.params[p] = defaults[p];
                }
            }
        }

        // преобразуем строки в цифры
        for (i = 0; i < numericParams.length; i++) {
            this.params[numericParams[i]] = parseInt(this.params[numericParams[i]], 10);
        }

        if (!this.params.geoid) {
            // TODO FIXME DEBUG only
            this.params.geoid = '213'; // cause Msk is default city.
        }

        this.getGeoData(this.params.geoid, this.init);
    },


    /**
     * Инициализация часов
     * @param {Object} data геоданные, которые отдаёт ручка
     */
    init: function(data) {
        var p;
        this.params.now = data[0];
        for (p in data[1]) {
            if (data[1].hasOwnProperty(p)) {
                this.params[p] = data[1][p];
            }
        }

        this._bTime = $('.l-time').bem('l-time').findBlockInside('b-time');

        if (this.params.theme !== undefined) {
            this._bTime.setMod('type', this.params.theme);
        }
        $(window).resize(this.onResizeHandler);

        Ya=Ya||{};
        Ya.Time=Ya.Time||{};
        Ya.Time.Settings=Ya.Time.Settings||{};
        // определяем хост и язык
        Ya.Time.Settings.domain = location.hostname.replace(/[\S.]+yandex/, 'yandex');
        Ya.Time.Settings.lang   = this._lang || 'ru';

        // локализация ссылки для информера
        var link = $('.b-time__service-link', this._bTime.domElem);
        if (link.length > 0) {
            var linkText = link.html();
            link.html(linkText.replace('__ya_time__', _i18n('yandex time')));
            var domains = {
                'ru': ['time', 'ru'],
                'en': ['time','com'],
                'uk': ['time','ua'],
                'tr': ['saat','com.tr'],
                'tt': ['time','ru'],
                'be': ['time','by'],
                'kk': ['time','kz']
            };
            var _link = '';
            if (domains[this._lang] !== undefined) {
                _link = 'http://'+domains[this._lang][0]+'.yandex.'+ domains[this._lang][1]+'/';
            } else {
                _link = 'http://time.yandex.ru/';
            }

            link.attr('href', _link);
            link.css('visibility', 'visible');
        }

        this._bTime.setMod('widget', (widget.fake) ? 'informer' : 'static');
        this._bTime.init(this.params);

        // для таймзон скрываем города и страны
        if (/^\D/.test(this.params.geoid)) {
            var country = $('.b-time__country'),
                countryText = country.text().replace(/,.*/, '');
                country.text(countryText);
        }

        // Для КУБы показываем русское лого. Для остальных - yandex
        if ($.inArray(this._lang, ['en', 'tr']) !== -1) {
            var logo = $('.b-clock-'+this.params.theme+'__logo');
            logo.removeClass('b-clock-'+this.params.theme+'__logo_lang_ru')
                .addClass('b-clock-'+this.params.theme+'__logo_lang_en');
        }

        this.startTimer();

        this.setUTCPopup();
        // подстраиваем высоту виджета (для морды)
        widget.adjustIFrameHeight();

        // показываем виджет
        this._bTime.domElem.removeClass('hiddenWidget');
    },

    /**
     * Устанавливает для часов всплывающую подсказку со смещением относительно UTC
     */
    setUTCPopup: function() {
        var offset = this._bTime.offset(),
        offset_h  = Math.floor(offset / 60000 / 60),
        offset_m  = Math.abs(Math.floor(offset / 60000 % 60));
        $(this._bTime.clock.domElem[0]).attr({
            title: 'UTC'+((offset_h > 0) ? '+'+offset_h : offset_h)+((offset_m !== 0) ? ':'+offset_m : '')
        });
    },

    /**
     * Переключает виджет в горизонтальное положение, если ширина колонки > 270px
     */
    onResizeHandler: function() {
        if ($('body').width() > 270) {
            widget.clock._bTime.setMod('layout', 'horiz');
        } else {
            widget.clock._bTime.delMod('layout');
        }
        widget.adjustIFrameHeight();
    },

    /**
     * Таймер, который раз в секунду меняет время на часах (анимация)
     */
    startTimer: function() {
        var self = this;
        if (self.timer === undefined) {
            // sync data ~ once a minute
            setInterval(function() {
                            self.syncData.call(self);
                        }, 60000);

            var secTimer = function() {
                self._bTime.timestamp(self.params.now += 1000, true);
            };
            // установка стрелок в начальное положение
            secTimer();
            // стартуем таймер
            self.timer = setInterval(secTimer, 1000);
        }
    },


    /**
     * Дергает sync и обновляет данные о времени и погоде
     */
    syncData: function() {
        var self = this,
        time = Date.now();
        $.ajax({
            url: self._syncUrl,
            dataType: 'json',
            type: 'GET',
            data: { geo: self.params.geoid },
            timeout: 2500,
            success: function(data) {
                // синхронизируем основное время + половина времени выполнения запроса
                self.now = data[0]+Math.round((Date.now() - time) / 2);
                // обновляем погоду
                self._bTime.setWeather(data[1].weather);
                // обновляем sunrise/sunset/offset
                self._bTime._sunrise = data[1].sunrise;
                self._bTime._sunset  = data[1].sunset;
                self._bTime._offset  = data[1].offset;
            }
        });

    }

};

