/**
 * Класс для отрисовки карты городов
 * @requires jQuery
 * @namespace RadioCon
 */

RadioCon.Map = function() {

    var T_ANIMATED = 1, T_STATIC = 2;

    /** @type {Number} Вермя анимации при наведении */
    var ANIMATION_DURATION = 300;

    /** @type {Number} Коэффициент сокращения расстояния */
    var DIST_COEFF = 1.5;

    /** @type {Array} массив городов */
    var cities = new Array();

    var $wrap = $();

    var type = T_ANIMATED

    var mode = 'rollover';
    mode = 'nearest';

    var offset;

    /**
     * Собираем красивый массив городов
     * @param {Object} d JSON-данные
     */
    function _init(d) {
        for (var i = 0; i < d.length; i++) {
            var _d = d[i];
            var city = {
                name : _d.n,
                coords : {
                    left : parseInt(_d.g[0]),
                    top : parseInt(_d.g[1])
                },
                textOffset : {
                    left : parseInt(_d.g[2]),
                    top : parseInt(_d.g[3])
                },
                cRadius : parseInt(_d.g[4])
            }
            if (_d.s) {
                city.stations = _d.s;
            }
            cities.push(city);
        }
        $wrap = $(document.getElementById('map'));
        getOffset();
    }

    /**
     * Отрисуем города
     */
    function draw() {
        for (var i = 0; i < cities.length; i++) {
            _drawCity(cities[i]);
        }
        if ((type === T_ANIMATED) && (mode === 'nearest')) {
            $wrap.mousemove(mapMouseHandler);
            $wrap.mouseout(mapOutHandler);
            $(window).resize(getOffset);
        }
    }

    function _drawCity(city) {
        var $o = $(document.createElement('div'))
            .addClass('city')
            .html('<ins></ins>')
            .css({
                left : city.coords.left,
                top : city.coords.top
            })
            .appendTo($wrap);
        if (city.name == 'Челябинск') {
            $o.addClass('capital');
        }
        city.$o = $o;
        var $n = $(document.createElement('div'))
            .addClass('n')
            .css({
                left : city.textOffset.left || 0,
                top : city.textOffset.top || 0
            })
            .html(city.name)
            .appendTo($o);
        city._$im = $(document.createElement('em'))
            .hide()
            .appendTo($o);
        if ((jQuery.browser.msie) && (jQuery.browser.version < 9)) {
            city._$im.css({
                'background' : 'transparent',
                'filter' : "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/i/mc.png',sizingMethod='scale')"
            });
        }

        if (city.stations) {
            city.$stations = $(document.createElement('div'))
                .addClass('st')
                .html(city.stations.join('<br>'))
                .hide()
                .appendTo($n);
        }
        if (type === T_STATIC) {
            var r = city.cRadius;
            city._$im
                .css({
                    left : -r,
                    top : -r,
                    width : r * 2,
                    height : r * 2
                })
                .show();
            city.$stations.show();
        } else {
            if (city.$stations)
                city.$stations.css({ opacity : 0 });

        }
        if ((type === T_ANIMATED) && (mode === 'rollover')) {
            $o.hover(
                function() {
                    showCity(city);
                },
                function() {
                    hideCity(city);
                }
            );
        }
    }

    /**
     * Показать город
     * @param {Object} city
     */
    function showCity(city) {
        var r = city.cRadius;
        city._$im.show().stop().animate({
            left : -r,
            top : -r,
            width : r * 2,
            height : r * 2
        }, ANIMATION_DURATION, 'swing');
        city.$stations
            .show()
            .stop()
            .animate({
                opacity : 1
            }, ANIMATION_DURATION * 2, 'swing');
    }

    /**
     * Скрыть город
     * @param {Object} city
     */
    function hideCity(city) {
        city._$im.stop().animate({
            left : 0,
            top : 0,
            width : 0,
            height : 0
        }, ANIMATION_DURATION, 'swing', __hide);
        city.$stations
            .stop()
            .animate({
                opacity : 0
            }, ANIMATION_DURATION, 'swing', __hide);

    }
    /**
     * Подсветить город
     * @param {Object} city город
     * @param {Number} k коэффициент
     */
    function setCity(city, k) {
        var r = city.cRadius * k;
        city._$im.show().css({
            left : -r,
            top : -r,
            width : r * 2,
            height : r * 2
        });
        city.$stations
            .show()
            .css({
                opacity : k
            });
    }

    function mapMouseHandler(e) {

        var x = e.pageX - offset.left;
        var y = e.pageY - offset.top;

        for (var i = 0; i < cities.length; i++) {
            var city = cities[i];
            var dist = Math.sqrt(Math.pow(x - city.coords.left, 2) + Math.pow(y - city.coords.top, 2));
            var k = (city.cRadius - dist/DIST_COEFF) / city.cRadius;
            if (k < 0)
                k = 0;
            setCity(city, k);
        }
    }

    function mapOutHandler(e) {
        var t = e.relatedTarget;
        while ((t) && (t != document.body)) {
            if (t == this)
                return;
            t = t.parentNode;
        }
        for (var i = 0; i < cities.length; i++) {
            hideCity(cities[i]);
        }
    }


    function getOffset() {
        offset = $wrap.offset();
    }

    function __hide() {
        $(this).hide();
    }

    return {
        init : function(_mode) {
            if (RadioCon.mapData) {
                if (RadioCon.mapType)
                    type = T_STATIC;
                if (_mode)
                    mode = _mode;
                _init(RadioCon.mapData);
                delete RadioCon.mapData;
                draw();
            }
        }
    }

}();

