// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.

define(['jquery'], function() {
    (function($) {
        // jQuery plugin definition
        $.fn.hpColumns = function(options) {
            
            var instance;
          
            function hpColumns(elem) {
              
                var container;
                var page;
                var wrapper;
                var layoutTimer;
                var fixedNumColumns;
              
                function layout() {
                    var numColumns, column, maxWidth = 0;
                    var columns = $('.hp-column', wrapper);
                    var items = $('.hp-column-item', wrapper);
                    var i;
                    
                    items.each(function (index, item) {
                        maxWidth = Math.max($(item).outerWidth(), maxWidth);
                    });

                    if (fixedNumColumns) {
                        numColumns = options.numColumns;
                    } else {
                        // Need at least one column
                        numColumns = (maxWidth === 0) ? 1 : 
                            Math.max(1, Math.floor(wrapper.innerWidth() / maxWidth));
                    }
                    itemsPerColumn = Math.ceil(items.length / numColumns);
                    
                    if (columns.length < numColumns) {
                        // add more columns
                        for (i=0; i<(numColumns - columns.length); i++) {
                            column = columns.first().clone();
                            $('.hp-column-item', column).remove();
                            wrapper.append(column);
                        }
                    }
                    
                    // distribute items across columns
                    items.each(function (index, item) {
                        var columnIndex = Math.floor(index / itemsPerColumn);
                        column = $('.hp-column:eq(' + columnIndex + ')', wrapper);
                        //todo make it more generic to handle list items as well
                        $('tbody', column).append(item);
                    });
                    
                    if (columns.length > numColumns) {
                        // remove extraneous columns
                        for (i=0; i<(columns.length - numColumns); i++) {
                            columns.last().remove();
                        }
                    }
                }
                
                function onResize(event) {
                    if (event.target == window) {
                        clearTimeout(layoutTimer);
                        layoutTimer = setTimeout(layout, 50);
                    }
                }
                
                function registerHandlers() {
                    page.on('relayout.hpcolumns', layout);
                    $(window).on('resize.hpcolumns', onResize);
                }

                function unregisterHandlers() {
                    page.off('relayout.hpcolumns', layout);
                    $(window).off('resize.hpcolumns', onResize);
                }

                this.resume = function() {
                    if (!fixedNumColumns) {
                        registerHandlers();
                    }
                };
                
                this.pause = function() {
                    unregisterHandlers();
                };

                this.initialize = function(elem) {
                    
                    container = $(elem);  
                    container.addClass('hp-column');
                    if (! container.parent().hasClass('hp-columns')) {
                        container.wrap('<div class="hp-columns"></div>');
                    }
                    wrapper = container.parent();
                    page = container.parents('.hp-page');
                    //todo make it more generic to handle list items as well
                    $('tr', container).addClass('hp-column-item');
                    fixedNumColumns = options && options.numColumns;
                    if (!fixedNumColumns) {
                        registerHandlers();
                    }
                    layout();
                };
            }
            
            if ( typeof options === 'string' ) { 
                // call method
                var args = Array.prototype.slice.call( arguments, 1 );

                this.each(function() {
                    instance = $.data( this, 'hpColumns' );
                    if ( !instance ) {
                        if (window.console) {
                            window.console.error(
                                "cannot call methods on hpColumns prior to initialization; " +
                                "attempted to call method '" + options + "'" );
                        }
                        return;
                    }
                    if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
                        if (window.console) {
                            window.console.error(
                                "no such method '" + options + "' for hpColumns instance" );
                        }
                        return;
                    }
                    // apply method
                    instance[ options ].apply( instance, args );
                });  
            } else {
                // pluginify
                var ret;
                this.each(function() {
                    var $elem = $(this);
                    instance = new hpColumns($elem[0]);
                    $.data(this, 'hpColumns', instance);
                    instance.initialize($elem[0]);
                    ret = ret ? ret.add($elem) : $elem;
                });
                return ret;
            }
        };
    }(jQuery));
});
