/**
 * Синглтон для работы с каталогом
 * аккумулирует в себе обработчики
 */
$G.Catalog = function() {

    var PATH_SLIDE_DURATION = 250;

    var HASH_CHECK_INTERVAL = 400;

    var eshopTable, basketTable, eshopForm;

    var $basket = $(), $searchForm = $(), $headPath = $();
    var searchType = 'local';

    var _hash, hashCheckTimer;

    var origTitle = document.title;

    /**
     * Хэндлер выбора элемента в дереве
     * @param {Object} item элемент
     * @param {Boolean} justHightlight только выделить в списке дерева
     */
    function selectTreeItemHandler(item, justHightlight) {
        var id = (((item.type == 'branch') && (!justHightlight)) || (!item.parent))
            ? item.id
            : item.parent.id;
        setLocationHash(item.id);
        $G.Catalog.Table.load(id, item.id);
        updateDocumentTitleAndPath(id);
    }

    /**
     * Хэндлер выбора элемента в таблице
     * @param {Object} item элемент
     */
    function selectTableItemHandler(item) {
        var id = item.id;
        $G.Catalog.Tree.selectById(id);
        setLocationHash(id);
    }

    function getIdFromHash() {
        var id = window.location.hash.substring(2);
        if (/\D/.test(id))
            id = '';
        return id;
    }

    /**
     * Устанавливает хэш для location
     * @param {String} id идентификатор объекта
     */

    function setLocationHash(id) {
        if ((!id) || ($G.Catalog.Tree.getRoot().id == id))
            id = '';
        window.location.hash = '/' + id;
        _hash = window.location.hash;
        setupHashChecker();
    }

    /**
     * Настроивает слежение за хэшем (эмуляция хистори)
     */
    function setupHashChecker() {
        hashCheckTimer = window.setInterval(function() {
            if ((_hash) && (window.location.hash != _hash)) {
                window.clearInterval(hashCheckTimer);
                var id = getIdFromHash();
                if (id) {
                    $G.Catalog.Tree.selectById(id, true);
                } else {
                    $G.Catalog.Tree.getRoot().select();
                }
            }
        }, HASH_CHECK_INTERVAL);
    }

    /**
     * Настроить формы поиска
     * @param {String} type тип {global, local}
     */
    function setupSearch(type) {
        searchType = type;
        $searchForm = $(document.getElementById('eshop-search'));
        $searchForm.find('a').click(function() {
            resetSearch();
            return false;
        });
        $searchForm.find('input[type="text"]').keydown(function(e) {
            if (e.which == 13)
                submitSearch();
        })
        $searchForm.find('input[type="submit"]').click(function() {
            submitSearch();
        });
    }

    /**
     * Отменить поиск
     */
    function resetSearch() {
        $searchForm.find('input[type="text"]').val('');
        if (searchType == 'global') {
            $G.Catalog.Tree.getRoot().clear();
            $G.Catalog.Tree.getRoot().open(true);
        } else {
            $G.Catalog.Table.resetFilter();
        }
    }

    /**
     * Выполнить поиск
     */
    function submitSearch() {
        var code = $searchForm.find('input[name="code"]').val().trim();
        var name = $searchForm.find('input[name="name"]').val().trim();
        if ((code == '') && (name == ''))
            return resetSearch();
        if (searchType == 'global') {
            $G.getJSON({
                _do  : 'eshop_search',
                root : $G.Catalog.Tree.getRoot().id,
                code : code,
                name : name
            }, _searchHandler)
        } else {
            $G.Catalog.Table.filter(code, name);
        }
    }

    function _searchHandler(data) {
        if ((data) && (data.length)) {
            $G.Catalog.Tree.construct(data);
            $G.Catalog.Tree.openAll();
            $G.Catalog.Tree.getFirstLeaf().select(false, true);
        } else {
            var w = new $G.Window({
                align          : 'center-center',
                width          : 300,
                height         : 36,
                animation      : true
            });
            w.attachEventListener('draw', function(_window) {
                _window.$content.html('<div class="eshop-search-null">По вашему запросу ничего не найдено</div>');
            });
            w.show();
        }
    }

    function basketHandler(id) {
        $G.getJSON({
            _do : 'eshop_to_basket',
            id  : id
        }, _basketResponseHandler);
    }

    function countHandler(id, count) {
        $G.getJSON({
            _do   : 'eshop_change_count',
            id    : id,
            count : count
        }, _countResponseHandler);
    }

    function _basketResponseHandler(data) {
        if (data.basket)
            updateBasket(data.basket);
        if (eshopTable) {
            if (data.add)
                $G.Catalog.Table.inBasket(data.add, 1);
            if (data.remove)
                $G.Catalog.Table.inBasket(data.remove, 0);
        }
        if (basketTable) {
            if (data.remove)
                $G.Catalog.BasketTable.deleteRow(data.remove);
        }
    }

    function _countResponseHandler(data) {
        if (data.basket)
            updateBasket(data.basket);
        if ((data.row) && (basketTable)) {
            $G.Catalog.BasketTable.updateRow(data.row);
        }
    }

    function getBasket(getContent) {
        $G.getJSON({
            _do  : 'eshop_basket',
            cnt  : (getContent) ? '1' : '0'
        }, updateBasket);
    }

    function updateBasket(data) {
        var price = $G.GetPrice(data.price, true) || 0;
        var discount = $G.GetPrice(data.discount, true) || 0;
        var count = data.count + ' ' + $G.GetCountStr(data.count);
        if (data.count > 0) {
            $basket.addClass('basket-full');
        } else {
            $basket.removeClass('basket-full');
        }
        $basket.find('.count').html(count);
        $basket.find('.price').html(price + ' руб.');
        $basket.find('.discount').html(discount + ' руб.');
        if (data.content) {
            for (var i = 0; i < data.content.length; i ++)
                $G.Catalog.Table.inBasket(data.content[i], 1);
        }
    }

    /**
     * Сделать ссылку с заголовка на корень дерева
     */
    function setupHeaderLink() {
        $('#cnt-wrap h1 a').click(function () {
            $G.Catalog.Tree.getRoot().select();
            return false;
        });

    }


    /**
     * Обновить тайтл страницы и путь в заголовке
     * @param {Number} id ID элемента
     */
    function updateDocumentTitleAndPath(id) {
        var str = '';
        var root = $G.Catalog.Tree.getRoot();
        var item = root.getChildById(id);
        if ((item) && (item != root)) {
            str = item.name.replace(/<[^>]+>/g, ' ') + ' - ';
        }
        document.title = str + origTitle;
        var html = '';
        if (item) {
            while (item.parent) {
                html = '<td><a href="#/' + item.id + '">'+ item.name + '</a></td>' + html;
                item = item.parent;
            }
            html = '<tr>' + html + '</tr>';
        }
        $headPath.html(html);
    }


    return {
        init: function() {
            var $h = $('#cnt-wrap h1')
            var $headPathWrap = $(document.createElement('span')).html('<table><tbody></tbody></table>').appendTo($h);
            $headPath = $headPathWrap.find('tbody');
            $h.hover(
                function() {
                    $headPathWrap.stop().animate({ width : $headPath.width() }, PATH_SLIDE_DURATION, 'swing')
                },
                function() {
                    $headPathWrap.stop().animate({ width : 0 }, PATH_SLIDE_DURATION, 'swing')
                }
            );

            if (window._TREE_NODE_ID != window._TREE_CAT_ID) {
                var link = $h.find('a').get(0);
                if (link) {
                    window.location = link.href + '#/' + window._TREE_NODE_ID;
                    return;
                }

            }
            $basket = $(document.getElementById('basket-block'));
            $basket.find('ins').click(function() {
                if ($basket.hasClass('basket-full'))
                    window.location = $basket.find('a').get(0).href;
            });
            eshopTable = document.getElementById('eshop-table');
            var treeEl = document.getElementById('eshop-tree');
            if (treeEl) {
                getBasket();
                setupHashChecker();
                setupSearch('global');
                var hashId = getIdFromHash();
                $G.Catalog.Tree.init(treeEl, window._TREE_CAT_ID, hashId);
                $G.Catalog.Tree.attachEventListener('select', selectTreeItemHandler);
                setupHeaderLink();
                if (eshopTable) {
                    $G.Catalog.Table.init(eshopTable);
                    $G.Catalog.Table.attachEventListener('select', selectTableItemHandler);
                    $G.Catalog.Table.attachEventListener('basket', basketHandler);
                }
            } else {
                if (eshopTable) {
                    setupSearch('local');
                    $G.Catalog.Table.initExt(eshopTable);
                    $G.Catalog.Table.attachEventListener('basket', basketHandler);
                    getBasket(true);
                } else {
                    getBasket();
                }

            }
            basketTable = document.getElementById('eshop-basket-table');
            if (basketTable) {
                $G.Catalog.BasketTable.init(basketTable);
                $G.Catalog.BasketTable.attachEventListener('delete', basketHandler);
                $G.Catalog.BasketTable.attachEventListener('change_count', countHandler);
            }
            eshopForm = document.getElementById('eshop-form');
            if (eshopForm) {
                $G.Catalog.Form.init(eshopForm);
            }
        }
    };
}()



/** @type {Number} Разница для подбора высота*/
$G.Catalog.WRAP_HEIGHT_OFFSET = 72;

/**
 * Получить правильное склонение слова "товар"
 * @param {Number} count количество
 * @return {String}
 */
$G.GetCountStr = function(count) {
    if (((count % 100) < 10)  || ((count % 100) > 20)) {
        switch (count % 10) {
            case 1:
                return 'товар'
            case 2:
            case 3:
            case 4:
                return 'товара'
        }
    }
    return 'товаров';
}

/**
 * Составить строку с ценой
 * @param {Number} price цена
 * @param {Boolean} noNDS не учитывать ДНС
 * @return {String}
 */
$G.GetPrice = function(price, noNDS) {
    if (price == 0)
        return '';
    price = Math.floor(price * 100) / 100;
    var nds = Math.floor(price * 18 + 0.5) / 100;
    if (!noNDS)
        price += nds;
    var rub = Math.floor(price).toString();
    var kop = Math.floor((price - parseInt(price) + 0.001) * 100).toString();

    var l = rub.length;
    var i = 0;
    var html = '';

    while (i < l) {
        var k = ((i == 0) && (l % 3 > 0))
            ? l % 3
            : 3;
        html += '<span>' + rub.substr(i, k) + '</span>';
        i += k;
    }
    if (kop.length < 2)
        kop = '0' + kop;
    html += ',' + kop;
    return html;
}



