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

define(['hp/core/Localizer', 'jquery'], function(localizer) {
    (function($) {
        // jQuery plugin definition
        $.fn.hpGridPanels = function(options) {
          
            var instance;

            function hpGridPanels(elem) {
              
                var container;
                var layoutTimer;
                var development = false;
                
                function removeScrolling() {
                    $('.hp-panel-contents-container', container).each(
                        function (index, contentContainer) {
                            $(contentContainer).css({width: '', height: ''});
                    });
                }
                
                function addScrolling() {
                    $('.hp-grid-panel', container).each(function (index, panel) {
                        var contents = $('.hp-panel-contents', panel);
                        var contentContainer = $('.hp-panel-contents-container', panel); 
                        var header;
                        var heightOffset = 0; 
                        if (contents.length > 0) {
                            header = $('> header', panel);
                            if (header.length > 0) {
                                heightOffset = contentContainer.position().top - header.position().top;
                            }
                            $('.hp-panel-contents-container', panel).
                                css({width: $(panel).width(),
                                    height: $(panel).height() - heightOffset});
                        }
                    });
                }
                
                function setHeaderMaxWidth() { 
                    $('.hp-grid-panel', container).each(function (index, panel) {
                        var header = $('> header', panel);
                        var edit = $('.hp-panel-edit', header);
                        if (header.length > 0 && edit.length > 0) {
                            $('> h2', header).css ({'max-width': $(panel).width() - $(edit).outerWidth(true)});
                        }
                    });
                }
                
                function addPanelContainers() {
                    var contentContainer;
                    $('.hp-grid-panel', container).each(function (index, panel) {
                        var contents = $('.hp-panel-contents', panel);
                        if (contents.length > 0 &&
                            ! contents.parent().hasClass('hp-panel-contents-container')) {
                            contentContainer = $('<div></div>').
                                addClass('hp-panel-contents-container');
                            contents.wrap(contentContainer);
                        }
                    });
                }
                
                function layoutNarrow () {
                    $(container).addClass('hp-grid-narrow');
                    $('.hp-grid-panel, .hp-grid-row, .hp-grid-column',
                          container).css({'width': '', 'height': ''});
                }
                
                function layoutNormal (unitWidth, unitHeight) {
                    $(container).removeClass('hp-grid-narrow');

                    $('.hp-grid-panel, .hp-grid-row, .hp-grid-column',
                          container).css({'width': '', 'height': ''});

                    // update the css width property
                    for (var index = 1; index <= 12; index += 1) {
                        $(".hp-grid-span-" + index, container).
                            css('width', Math.floor(unitWidth * index));
                    }

                    // update the css height property 
                    for (index = 1; index <= 12; index += 1) {
                        $(".hp-grid-height-" + index, container).
                            css('height', Math.floor(unitHeight * index));
                    }
                    
                    // adjust panels inside panels to align with outer panel grid
                    var firstPanel = $('.hp-grid-panel').first();
                    if (firstPanel.length > 0) {
                        var header = $('> header', firstPanel);
                        var headerHeight = header.length > 0 ? header.outerHeight() : 0;
                        var panelPadding = $('> *', firstPanel).first().offset().top - firstPanel.offset().top;
                        // rows inside columns
                        $('.hp-panel-contents.hp-grid-column > .hp-grid-panel', container).each(function (index, panel) {
                            $(panel).css('width', '');
                        });
                        $('.hp-panel-contents.hp-grid-column > .hp-grid-panel:first-child', container).each(function (index, panel) {
                            $(panel).css('height', $(panel).outerHeight() - headerHeight - (panelPadding * 2) - 1);
                        });
                        $('.hp-panel-contents.hp-grid-column > .hp-grid-panel:last-child', container).each(function (index, panel) {
                            $(panel).css('height', $(panel).outerHeight() - panelPadding - 1);
                        });
                        // columns inside rows
                        $('.hp-panel-contents.hp-grid-row > .hp-grid-panel', container).each(function (index, panel) {
                            $(panel).css('height', '');
                        });
                        $('.hp-panel-contents.hp-grid-row > .hp-grid-panel:first-child', container).each(function (index, panel) {
                            $(panel).css('width', $(panel).outerWidth() - panelPadding);
                        });
                        $('.hp-panel-contents.hp-grid-row > .hp-grid-panel:last-child', container).each(function (index, panel) {
                            $(panel).css('width', $(panel).outerWidth() - panelPadding);
                        });
                    }

                    addScrolling();
                }
                
                function haveEnoughSpace (unitWidth, unitHeight) {
                    // any panels too short or narrow to really see?
                    var result = true;
                    for (var index = 1; index <= 12; index += 1) {
                        if ((index * unitWidth < 180) &&
                            $(".hp-grid-span-" + index, container).length > 0) {
                            result = false;
                            break;
                        }
                        if ((index * unitHeight < 100) &&
                            $(".hp-grid-height-" + index, container).length > 0) {
                            result = false;
                            break;
                        }
                    }
                    return result;
                }
                
                // for development
                function overlayGrid(width, height, unitWidth, unitHeight) {
                    var canvas = $('canvas', container).attr('width', width).attr('height', height)[0];
                    var context = canvas.getContext('2d');
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    context.beginPath();
                    context.lineWidth = 1;
                    context.strokeStyle = '#f00';
                    for (var index = 1; index < 12; index += 1) {
                        context.moveTo(unitWidth * index, 0);
                        context.lineTo(unitWidth * index, height);
                        context.moveTo(0, unitHeight * index);
                        context.lineTo(width, unitHeight * index);
                    }
                    context.stroke();
                }
                
                function layout () {
                  
                    $(container).css('visibility', 'hidden').removeClass('hp-grid-narrow');

                    addPanelContainers();
                    
                    removeScrolling();
                    
                    var width = $(container).innerWidth();
                    var height = $(container).innerHeight();
                    var unitWidth = width / 12;
                    var unitHeight = height / 12;
                    
                    // any panels too short or narrow to really see?
                    var bigEnough = haveEnoughSpace(unitWidth, unitHeight);

                    if (bigEnough) {
                        layoutNormal(unitWidth, unitHeight);
                    } else {
                        layoutNarrow();
                    }
                    
                    if (development) {
                        overlayGrid(width, height, unitWidth, unitHeight);
                    }
                    
                    //set header max width after all the width calculation is done
                    setHeaderMaxWidth();
                    
	                  // hp-form-content.hp-ellipsis needs width for nowrap styling
  	                $('.hp-grid-panel .hp-panel-contents', container).
  	                    each(function (index, contents) {
  	                        $('.hp-ellipsis', contents).closest('li.hp-form-item').
  	                            css({width: $(contents).width() - 10});
  	                });
  	                
  	                $(container).css('visibility', '');
                }
                
                function onResize(event) {
                    if (event.target == window || event.currentTarget == window) {
                        clearTimeout(layoutTimer);
                        layoutTimer = setTimeout(layout, 50);
                    }
                }
              
                this.initialize = function(elem) {
                    container = $(elem);
                    if (development) {
                        container.append($('<canvas></canvas>'));
                    }
                    $('.hp-panel-edit', container).
                        text(localizer.getString('core.details.edit'));
                    // rely on this event to trigger layout
                    container.parents('.hp-page').on('relayout', layout);
                    $(window).on('resize', onResize);
                    layout();
                };
                
                this.reset = function() {
                    container = $(elem);
                    layout();
                };
            }
            
            if ( typeof options === 'string' ) { 
                // call method
                var args = Array.prototype.slice.call( arguments, 1 );

                this.each(function() {
                    instance = $.data( this, 'hpGridPanels' );
                    if ( !instance ) {
                        if (window.console) {
                            window.console.error(
                                "cannot call methods on hpGridPanels 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 hpGridPanels instance" );
                        }
                        return;
                    }
                    // apply method
                    instance[ options ].apply( instance, args );
                });  
            } else {
                // pluginify
                var ret;
                this.each(function() {
                    var $elem = $(this);
                    instance = new hpGridPanels($elem[0]);
                    $.data(this, 'hpGridPanels', instance);
                    instance.initialize($elem[0]);
                    ret = ret ? ret.add($elem) : $elem;
                });
                return ret;
            }
        };
    }(jQuery));
});
