/*
*  Copyright 2017-2018 Michail Vourlakos <mvourlakos@gmail.com>
*
*  This file is part of Latte-Dock
*
*  Latte-Dock is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License as
*  published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*
*  Latte-Dock is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//!         FILLWIDTH/FILLHEIGHT COMPUTATIONS
//! Computations in order to calculate correctly the sizes for applets
//! that are requesting fillWidth or fillHeight


//! initialize AppletItems flag "inFillCalculations" in orderf
//! to inform them that new calculations are taking place
function initLayoutForFillsCalculations(layout) {
    for(var i=0; i<layout.children.length; ++i) {
        var curApplet = layout.children[i];
        if (curApplet.needsFillSpace) {
            curApplet.inFillCalculations = true;
        }
    }
}

//! during step1/pass1 all the applets with fills
//! that use lower maximumSize than the proposed one from the
//! algorithm are updated
function computeStep1ForLayout(layout, availableSpace, sizePerApplet, noOfApplets) {
    for(var i=0; i<layout.children.length; ++i) {
        var curApplet = layout.children[i];
        var maxSize = 0;

        if (curApplet && curApplet.applet && curApplet.applet.Layout)
            maxSize = root.isVertical ? curApplet.applet.Layout.maximumHeight : curApplet.applet.Layout.maximumWidth;

        if (curApplet.needsFillSpace && (maxSize <= sizePerApplet) && (maxSize>=1) && (maxSize !== Infinity)) {
            curApplet.sizeForFill = maxSize;
            // console.log("s3_1  "+ maxSize);
            curApplet.inFillCalculations = false;
            availableSpace = Math.abs(availableSpace - maxSize);
            noOfApplets = noOfApplets - 1;
            sizePerApplet = noOfApplets > 1 ? Math.floor(availableSpace / noOfApplets) : availableSpace;
            // console.log(noOfApplets + " - " + sizePerApplet + " - " + availableSpace);
        }
    }

    return [availableSpace, sizePerApplet, noOfApplets];
}

//! during step2/pass2 all the applets with fills
//! that remained with no computations from pass1
//! are updated with the algorithm's proposed size
function computeStep2ForLayout(layout, sizePerApplet) {
    for(var i=0; i<layout.children.length; ++i) {
        var curApplet = layout.children[i];

        if (curApplet.needsFillSpace && curApplet.inFillCalculations) {
            curApplet.sizeForFill = sizePerApplet;
            // console.log("s4_1  "+ sizePerApplet);
            curApplet.inFillCalculations = false;
        }
    }
}

//! initialize the three layouts and execute the step1/phase1
//! it is used when the Centered (Main)Layout is only used or when the Main(Layout)
//! is empty in Justify mode
function initializationPhase(availableSpace, sizePerApplet, noOfApplets){
    if (root.panelAlignment === Latte.Dock.Justify) {
        initLayoutForFillsCalculations(startLayout);
        initLayoutForFillsCalculations(endLayout);
    }
    initLayoutForFillsCalculations(mainLayout);


    // console.log("s3...");

    //! first pass in order to update sizes for applet that want to fill space
    //! but their maximum metrics are lower than the sizePerApplet
    var res = computeStep1ForLayout(mainLayout, availableSpace, sizePerApplet, noOfApplets);
    availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];

    if (root.panelAlignment === Latte.Dock.Justify) {
        res = computeStep1ForLayout(startLayout, availableSpace, sizePerApplet, noOfApplets);
        availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];

        res = computeStep1ForLayout(endLayout, availableSpace, sizePerApplet, noOfApplets);
        availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
    }

    return [availableSpace, sizePerApplet, noOfApplets];
}


function updateSizeForAppletsInFill() {
    if ((visibilityManager.normalState && !root.editMode)
            || (behaveAsPlasmaPanel && root.editMode)) {
        // console.log("-------------");
        // console.log("s1...");
        var noA = startLayout.fillApplets + mainLayout.fillApplets + endLayout.fillApplets;

        if (noA === 0)
            return;

        // console.log("s2...");
        if (mainLayout.shownApplets === 0 || root.panelAlignment !== Latte.Dock.Justify) {
            var availableSpace = Math.max(0, root.maxLength - startLayout.sizeWithNoFillApplets - mainLayout.sizeWithNoFillApplets - endLayout.sizeWithNoFillApplets - root.panelEdgeSpacing);
            var sizePerApplet = availableSpace / noA;


            var res = initializationPhase(availableSpace, sizePerApplet, noA);
            availableSpace = res[0];  sizePerApplet = res[1]; noA = res[2];

            // console.log("s4...");

            //! second pass in order to update sizes for applet that want to fill space
            //! this applets get the direct division of the available free space that
            //! remained from step1
            computeStep2ForLayout(startLayout, sizePerApplet);
            computeStep2ForLayout(mainLayout, sizePerApplet);
            computeStep2ForLayout(endLayout, sizePerApplet);

            //console.log("s5...");
        } else {
            //! Justify mode in all remaining cases

            //! compute the two free spaces around the centered layout
            //! they are called start and end accordingly
            var availableSpaceStart = Math.max(0, root.maxLength/2 - startLayout.sizeWithNoFillApplets - root.panelEdgeSpacing/2);
            var availableSpaceEnd = Math.max(0, root.maxLength/2 - endLayout.sizeWithNoFillApplets - root.panelEdgeSpacing/2);
            var availableSpace = availableSpaceStart + availableSpaceEnd - mainLayout.sizeWithNoFillApplets;

            var sizePerAppletMain = mainLayout.fillApplets > 0 ? availableSpace / noA : 0 ;

            var noStart = startLayout.fillApplets;
            var noMain = mainLayout.fillApplets;
            var noEnd = endLayout.fillApplets;

            //! initialize the computations
            initLayoutForFillsCalculations(startLayout);
            initLayoutForFillsCalculations(mainLayout);
            initLayoutForFillsCalculations(endLayout);

            //console.log("s3...");
            var res;

            //! first pass
            if (mainLayout.fillApplets > 0){
                res = computeStep1ForLayout(mainLayout, availableSpace, sizePerAppletMain, noMain);
                sizePerAppletMain = res[1]; noMain = res[2];
                var dif = (availableSpace - res[0]) / 2;
                availableSpaceStart = availableSpaceStart - dif;
                availableSpaceEnd = availableSpaceEnd - dif;
            }

            var sizePerAppletStart = startLayout.fillApplets > 0 ? availableSpaceStart / noStart : 0 ;
            var sizePerAppletEnd = endLayout.fillApplets > 0 ? availableSpaceEnd / noEnd : 0 ;

            if (startLayout.fillApplets > 0) {
                res = computeStep1ForLayout(startLayout, availableSpaceStart, sizePerAppletStart, noStart);
                availableSpaceStart = res[0]; sizePerAppletStart = res[1]; noStart = res[2];
            }
            if (endLayout.fillApplets > 0) {
                res = computeStep1ForLayout(endLayout, availableSpaceEnd, sizePerAppletEnd, noEnd);
                availableSpaceEnd = res[0]; sizePerAppletEnd = res[1]; noEnd = res[2];
            }

            ////
            //! second pass
            if (mainLayout.shownApplets > 0) {
                //var bSize = root.isHorizontal ? mainLayout.width : mainLayout.height;
                sizePerAppletMain = (availableSpaceStart + availableSpaceEnd) / (noStart + noMain + noEnd);
                computeStep2ForLayout(mainLayout, sizePerAppletMain);
                var aSize = root.isHorizontal ? mainLayout.width : mainLayout.height;

                availableSpaceStart = availableSpaceStart - aSize/2;
                availableSpaceEnd = availableSpaceEnd - aSize/2;

                sizePerAppletStart = startLayout.fillApplets > 0 ? availableSpaceStart / noStart : 0 ;
                sizePerAppletEnd = endLayout.fillApplets > 0 ? availableSpaceEnd / noEnd : 0 ;
            }

            if (startLayout.fillApplets > 0)
                computeStep2ForLayout(startLayout, sizePerAppletStart);
            if (endLayout.fillApplets > 0)
                computeStep2ForLayout(endLayout, sizePerAppletEnd);
        }
    }
}