/*
 * tCollapse jQuery plugin
 * version 0.3
 *
 * Copyleft  2010 Alexander Moskaliov (irker.net)
 *
 */


(function($) {
    //коллекция div  с классом indicator
    var collapseСollection= $([]);
    // таймер отслеживания изменения размера window
    var resizeTimer = null;
    // отслеживаем изменение окна
    $(window).bind('resize', function() {
        if (resizeTimer) clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function() {
            //обновляем стили коллекции
            updateCollapse(collapseСollection);
        }, 100);
    });

    //функция удаляет класс collapsed тем дивам, которые не влезли в одну строку, и убирает у тех, которые влезли
    function updateCollapse(collapsingElements)
    {
        if (collapsingElements)
        {
            //отсеиваем только те, которым нужно переключить класс
            collapsingElements.filter(
                function ()
                {
                    var element=$(this);
                    //  высотой больше stringsCountTable строк и не класса collapsed или высотой в stringsCountTable строк и класса collapsed
                    return (element.height()>(element.data('height'))) ^ element.hasClass('collapsed');
                }
                ).
            // переключаем класс
            toggleClass('collapsed');
        }
    }

    // подгатавливает указанные талицы
    $.fn.addCollapse = function(stringsCount) {

        //пробегаемся по элементам
        $(this).each (
            function () {
                if ($(this).is('table')) {
                    //число текстовых строк, до которых обрезается строка
                    var stringsCountTable=stringsCount ? 1*stringsCount : 1;

                    // если содержит <tbody> переключаемся на него
                    var tablebody=  $('tbody',this).lenght==0 ? $(this)  : $('tbody',this) ;

                    // следующие 3 строки после комментария вычисляют высоту 1 текстовой строки данной таблицы
                    // можно было бы задаться высотой 1em, но во-первых, 1em нельзя сравнить с height() ,
                    // а во-вторых, браузеры по разному отображают шрифты и высота скачет.
                    // FIXME: нужно найти способ лучше
                    var temp=$('<tr><td><div>A</div></td></td>').appendTo(tablebody);
                    var height=temp.find('div').height();
                    temp.remove();
                    // переменная уникальная для каждой из таблиц - содержит развернутую строку
                    var oldUnCollapse=null;
                    // перебираем строки
                    tablebody.children('tr:not(.trCollapsing)').
                    // добавляем класс
                    addClass('trCollapsing').
                    // по клику на строку разворачиваем ее
                    bind('click.tcollapse',
                        function ()  {
                            // получаем строку
                            var element=$(this).has('.collapsed');
                            // если строка содержит свернутые ячейки
                            if (element.length!=0) {
                                // развернута ли уже строка
                                var isUnCollapsed=element.data('uncollapsed');
                                // сворачиваем строку, которая уже была развернута
                                if (oldUnCollapse) {
                                    oldUnCollapse.addClass('trCollapsing').data('uncollapsed','').find('.collapsing').height(stringsCountTable*height);
                                }
                                // строка еще не развернута
                                if (!isUnCollapsed){
                                    // разворачиваем строку путем удаления класса trCollapsing и снятием height у свернутых дивов
                                    element.data('uncollapsed',true).removeClass('trCollapsing').find('.collapsing').height('');
                                    // сохраняем строку
                                    oldUnCollapse = element;
                                }
                            }
                        }
                        ).
                    // берем все ячейки ( не берем th )
                    children('td').not('.no-collapse').
                    each(
                        function ()
                        {
                            // вставляем два div внутрь каждой ячейки:
                            // первый div с помощью класса collapsing и свойства height обрезается до высоты stringsCountTable текстовыч строк
                            // второй div не обрезается и служит в дальнейшем индикатором высоты - его высоту сравниваем с высотой stringsCountTable текстовых строк в функции updateCollapse
                            $(this).html( "<div class='collapsing' style='height:"+(stringsCountTable*height)+"px;'><div class='indicator'>"+ $(this).html() + "</div></div>");
                        }
                        );
                    // добавляем к коллекции новые элементы
                    collapseСollection = collapseСollection.
                    add($('.indicator',this).
                        // также указываем им данные о высоте, чтобы ускорить работу функции updateCollapse
                        data('height',1*stringsCountTable*height));
                }
            }
            );


        updateCollapse(collapseСollection);


        return this;

    };

    // удаляет таблицу из управляемых плагином
    $.fn.removeCollapse = function() {
        //пробегаемся по элементам
        $(this).each (
            function () {
                if ($(this).is('table')) {
                    // ищем все строки, управляемые плагином
                    $('.trCollapsing',this).
                    removeClass('trCollapsing').
                    unbind('click.tcollapse').
                    children('td').
                    each(
                        function()
                        {
                            //удаляем вспомогательные div
                            $(this).html($('.indicator',this).html());
                        }
                        );
                }
            }
            );
    };

})(jQuery);
