/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/

#include "precompiled_sfx2.hxx"
#include "sfx2/sidebar/GridLayouter.hxx"

#include <vcl/window.hxx>

namespace sfx2 { namespace sidebar {

typedef std::vector<CellDescriptor> CellData;
typedef std::vector<CellData> ColumnData;

class GridLayouter::Implementation
{
public:
    Implementation (Window& rParent);
    ~Implementation (void);

    CellDescriptor& GetCell (
        const sal_Int32 nRow,
        const sal_Int32 nColumn,
        const sal_Int32 nVariant);

    void Layout (void);
    void LayoutColumn(
        ColumnData& rColumn,
        const sal_Int32 nX,
        const sal_Int32 nColumnIndex);

    void DistributeWidth (const sal_Int32 nTotalWidth);
    sal_Int32 GetMinimumColumnWidth (
        ColumnData& rColumn,
        const ColumnDescriptor& rDescriptor) const;

    void Paint (void);

    Window& mrParent;
    ::std::vector<ColumnData> maColumns;
    ::std::vector<ColumnDescriptor> maColumnDescriptors;
};

#define ForAllColumnDescriptors(I)                              \
    for (::std::vector<ColumnDescriptor>::iterator              \
             I(maColumnDescriptors.begin()),                    \
             iEnd(maColumnDescriptors.end());                   \
         I!=iEnd;                                               \
         ++I)

#define ForAllColumns(I,N)                                      \
    sal_Int32 N (0);                                            \
    for (::std::vector<ColumnData>::iterator                    \
             I(maColumns.begin()),                              \
             iEnd(maColumns.end());                             \
         I!=iEnd;                                               \
         ++I,++N)

#define ForAllRows(ColumnData,I)                                \
    for (std::vector<CellData>::iterator                        \
             I((ColumnData).begin()),                           \
             iRowEnd((ColumnData).end());                       \
         I!=iRowEnd;                                            \
         ++I)

#define ForAllCells(CellData,I)                                 \
    for (::std::vector<CellDescriptor>::iterator                \
             I((CellData).begin()),                             \
             iCellEnd((CellData).end());                        \
         I!=iCellEnd;                                           \
         ++I)
    

//===== GridLayouter ==========================================================

GridLayouter::GridLayouter (Window& rParent)
    : mpImplementation(new Implementation(rParent))
{
}




GridLayouter::~GridLayouter (void)
{
}




CellDescriptor& GridLayouter::GetCell (
    const sal_Int32 nRow,
    const sal_Int32 nColumn,
    const sal_Int32 nVariant)
{
    return mpImplementation->GetCell(nRow, nColumn, nVariant);
}




ColumnDescriptor& GridLayouter::GetColumn (
    const sal_Int32 nColumn)
{
    // Make sure that the specified column exists.
    mpImplementation->GetCell(0, nColumn, 0);
    return mpImplementation->maColumnDescriptors[nColumn];
}




void GridLayouter::Layout (void)
{
    mpImplementation->Layout();
}




void GridLayouter::Paint (const Rectangle& rBox)
{
    (void)rBox;
    
    mpImplementation->Paint();
}




//===== CellDescriptor ========================================================

CellDescriptor::CellDescriptor (void)
    : mpControl(NULL),
      mnGridWidth(1),
      mnMinimumWidth(-1),
      mnMaximumWidth(-1),
      mnOffset(0)
{
}




CellDescriptor::~CellDescriptor (void)
{
}




CellDescriptor& CellDescriptor::SetGridWidth (const sal_Int32 nColumnCount)
{
    mnGridWidth = nColumnCount;
    return *this;
}




CellDescriptor& CellDescriptor::SetControl (Window& rControl)
{
    mpControl = &rControl;
    return *this;
}




CellDescriptor& CellDescriptor::SetFixedWidth (const sal_Int32 nWidth)
{
    mnMinimumWidth = nWidth;
    mnMaximumWidth = nWidth;
    return *this;
}



CellDescriptor& CellDescriptor::SetOffset (const sal_Int32 nOffset)
{
    mnOffset = nOffset;
    return *this;
}




CellDescriptor& CellDescriptor::SetFixedWidth (void)
{
    sal_Int32 nMaxControlWidth (0);
    if (mpControl != NULL)
    {
        const sal_Int32 nControlWidth (mpControl->GetSizePixel().Width());
        if (nControlWidth > nMaxControlWidth)
            nMaxControlWidth = nControlWidth;
    }
    mnMinimumWidth = nMaxControlWidth;
    mnMaximumWidth = nMaxControlWidth;
    
    return *this;
}




CellDescriptor& CellDescriptor::SetMinimumWidth (const sal_Int32 nWidth)
{
    mnMinimumWidth = nWidth;
    return *this;
}



sal_Int32 CellDescriptor::GetGridWidth (void) const
{
    return mnGridWidth;
}




Window* CellDescriptor::GetControl (void) const
{
    return mpControl;
}




sal_Int32 CellDescriptor::GetMinimumWidth (void) const
{
    return mnMinimumWidth + mnOffset;
}




sal_Int32 CellDescriptor::GetMaximumWidth (void) const
{
    return mnMaximumWidth;
}



sal_Int32 CellDescriptor::GetOffset (void) const
{
    return mnOffset;
}




//===== GridLayouter::Implementation ==========================================

GridLayouter::Implementation::Implementation (Window& rParent)
    : mrParent(rParent),
      maColumns(),
      maColumnDescriptors()
{
}




GridLayouter::Implementation::~Implementation (void)
{
}




CellDescriptor& GridLayouter::Implementation::GetCell (
    const sal_Int32 nRow,
    const sal_Int32 nColumn,
    const sal_Int32 nVariant)
{
    if (nColumn<0 || nRow<0 || nVariant<0)
    {
        OSL_ASSERT(nColumn>=0);
        OSL_ASSERT(nRow>=0);
        OSL_ASSERT(nVariant>=0);
        return GetCell(0,0,0);
    }

    // Provide missing columns.
    if (maColumns.size() <= static_cast<size_t>(nColumn))
    {
        maColumns.resize(nColumn+1);
        maColumnDescriptors.resize(nColumn+1);
    }

    // Provide missing rows.
    ColumnData& rColumn (maColumns[nColumn]);
    if (rColumn.size() <= static_cast<size_t>(nRow))
        rColumn.resize(nRow+1);

    // Provide missing variants.
    CellData& rCellData (rColumn[nRow]);
    if (rCellData.size() <= static_cast<size_t>(nVariant))
        rCellData.resize(nVariant+1);
    
    return rCellData[nVariant];
}




void GridLayouter::Implementation::Layout (void)
{
    if (maColumns.empty())
    {
        // There are no columns and therefore no controls => nothing
        // to do.
        return;
    }

    const Size aParentSize (mrParent.GetSizePixel());
    
    // Determine the total column weight.
    sal_Int32 nTotalColumnWeight (0);
    ForAllColumnDescriptors(iDescriptor)
        nTotalColumnWeight += iDescriptor->GetWeight();
    if (nTotalColumnWeight <= 0)
    {
        OSL_ASSERT(nTotalColumnWeight>0);
        return;
    }

    // Distribute the width of the parent window to the columns.
    DistributeWidth(aParentSize.Width());

    // Set the new positions and widths.
    sal_Int32 nX (0);
    ForAllColumns(iColumn,nColumnIndex)
    {
        LayoutColumn(
            *iColumn,
            nX,
            nColumnIndex);
            
        nX += maColumnDescriptors[nColumnIndex].GetWidth();
    }
}




void GridLayouter::Implementation::LayoutColumn(
    ColumnData& rColumn,
    const sal_Int32 nX,
    const sal_Int32 nColumnIndex)
{
    ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumnIndex]);
    const sal_Int32 nLeft (nX + rDescriptor.GetLeftPadding());
    const sal_Int32 nWidth (rDescriptor.GetWidth() - rDescriptor.GetLeftPadding() - rDescriptor.GetRightPadding());

    sal_Int32 nRow (-1);
    ForAllRows(rColumn, iCell)
    {
        ++nRow;

        ForAllCells(*iCell, iCellDescriptor)
        {
            Window* pControl = iCellDescriptor->GetControl();
            if (pControl==NULL || ! pControl->IsVisible())
                continue;

            sal_Int32 nCellWidth (nWidth);
            const sal_Int32 nGridWidth (iCellDescriptor->GetGridWidth());
            if (nGridWidth < 0)
                continue;
            else if (nGridWidth > 1)
            {
                // Cell spans more than one column.  Sum all their
                // widths.
                for (sal_Int32 nOffset=1;
                     nOffset<nGridWidth && static_cast<size_t>(nColumnIndex+nOffset)<maColumnDescriptors.size();
                     ++nOffset)
                {
                    nCellWidth += maColumnDescriptors[nColumnIndex+nOffset].GetWidth();
                }
                nCellWidth -= maColumnDescriptors[nColumnIndex+nGridWidth-1].GetRightPadding();
            }

            // Check width against valid range of cell.
            if (iCellDescriptor->GetMinimumWidth() > 0)
                if (nCellWidth < iCellDescriptor->GetMinimumWidth())
                    nCellWidth = iCellDescriptor->GetMinimumWidth();
            if (iCellDescriptor->GetMaximumWidth() > 0)
                if (nCellWidth > iCellDescriptor->GetMaximumWidth())
                    nCellWidth = iCellDescriptor->GetMaximumWidth();
            
            pControl->SetPosSizePixel(
                nLeft + iCellDescriptor->GetOffset(),
                0,
                nCellWidth,
                0,
                WINDOW_POSSIZE_X | WINDOW_POSSIZE_WIDTH);
        }
    }
}




void GridLayouter::Implementation::DistributeWidth (const sal_Int32 nTotalWidth)
{
    // Prepare width distribution:
    // a) Setup minimum widths for all columns.
    // b) Sum up the width of columns that have zero weight.
    // c) Sum up the non-zero weights.
    sal_Int32 nZeroWeightWidth (0);
    sal_Int32 nTotalColumnWeight (0);
    for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
    {
        ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);
        ColumnData& rColumn (maColumns[nColumn]);

        const sal_Int32 nWidth (GetMinimumColumnWidth(rColumn, rDescriptor));

        rDescriptor.SetWidth(nWidth);

        if (rDescriptor.GetWeight() <= 0)
            nZeroWeightWidth += nWidth;
        else
            nTotalColumnWeight += rDescriptor.GetWeight();
    }
        
    sal_Int32 nRemainingWidth (nTotalWidth - nZeroWeightWidth);
    if (nRemainingWidth < 0)
        nRemainingWidth = 0;


    // Distribute the remaining width between columns that have
    // non-zero width.
    const sal_Int32 nDistributableWidth (nRemainingWidth);
    for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
    {
        ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);

        if (rDescriptor.GetWeight() > 0)
        {
            sal_Int32 nWidth (nDistributableWidth * rDescriptor.GetWeight() / nTotalColumnWeight);
            // Make sure the width lies inside the valid range of
            // column widths.
            if (nWidth < rDescriptor.GetWidth())
                nWidth = rDescriptor.GetWidth();
            if (rDescriptor.GetMaximumWidth()>0)
                if (nWidth > rDescriptor.GetTotalMaximumWidth())
                    nWidth = rDescriptor.GetTotalMaximumWidth();

            rDescriptor.SetWidth(nWidth);
            nRemainingWidth -= nWidth;
        }
    }
    
    // If there are some pixels left (due to rounding errors), then
    // give them to the first column that has non-zero weight.
    if (nRemainingWidth > 0)
        for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
        {
            ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);
            if (rDescriptor.GetWeight() > 0)
            {
                rDescriptor.SetWidth(rDescriptor.GetWidth() + nRemainingWidth);
                break;
            }
        }
}




sal_Int32 GridLayouter::Implementation::GetMinimumColumnWidth (
    ColumnData& rColumn,
    const ColumnDescriptor& rDescriptor) const
{
    // Start with the minimum width of the whole column.
    sal_Int32 nMinimumWidth (rDescriptor.GetMinimumWidth());

    // Take also into account the minimum widths of all cells in the column.
    ForAllRows(rColumn, iCell)
        ForAllCells(*iCell, iCellDescriptor)
        {
            if (iCellDescriptor->GetGridWidth() != 1)
                continue;
            const sal_Int32 nMinimumCellWidth (iCellDescriptor->GetMinimumWidth());
            if (nMinimumCellWidth > nMinimumWidth)
                nMinimumWidth = nMinimumCellWidth;
        }

    // Make sure that the minimum width does not become larger than
    // the maximum width of the column.
    if (nMinimumWidth > rDescriptor.GetMaximumWidth() && rDescriptor.GetMaximumWidth()>0)
        nMinimumWidth = rDescriptor.GetMaximumWidth();

    // Add the horizontal padding.
    return  nMinimumWidth 
        + rDescriptor.GetLeftPadding()
        + rDescriptor.GetRightPadding();
}




void GridLayouter::Implementation::Paint (void)
{
    const Size aParentSize (mrParent.GetSizePixel());

    static const Color aSeparatorColor (0x66cdaa);
    static const Color aLeftPaddingColor (0x98fb98);
    static const Color aRightPaddingColor (0xff69b4);
    static const Color aControlOverlayColor (0xffff00);
    
    sal_Int32 nX (0);
    mrParent.SetLineColor();
    mrParent.SetFillColor(aLeftPaddingColor);
    ForAllColumnDescriptors(iColumn)
    {
        if (iColumn->GetLeftPadding() > 0)
        {
            mrParent.DrawRect(Rectangle(
                    nX,0,
                    nX+iColumn->GetLeftPadding(),aParentSize.Height()));
        }

        nX += iColumn->GetWidth();
    }

    nX = 0;
    mrParent.SetFillColor(aRightPaddingColor);
    ForAllColumnDescriptors(iColumn)
    {
        if (iColumn->GetRightPadding() > 0)
        {
            const sal_Int32 nRight (nX + iColumn->GetWidth());
            const sal_Int32 nLeft (nRight - iColumn->GetRightPadding());
            mrParent.DrawRect(Rectangle(
                    nLeft,0,
                    nRight,aParentSize.Height()));
        }

        nX += iColumn->GetWidth();
    }

    nX = 0;
    mrParent.SetFillColor();
    mrParent.SetLineColor(aSeparatorColor);
    ForAllColumnDescriptors(iColumn)
    {
        mrParent.DrawLine(Point(nX,0), Point(nX,aParentSize.Height()));
        nX += iColumn->GetWidth();
    }

    mrParent.SetFillColor();
    mrParent.SetLineColor(aControlOverlayColor);
    ForAllColumns(iColumn,nColumnIndex)
        ForAllRows(*iColumn, iCell)
            ForAllCells(*iCell, iCellDescriptor)
            {
                Window* pControl (iCellDescriptor->GetControl());
                if (pControl!=NULL && pControl->IsVisible())
                {
                    Rectangle aBox (
                        pControl->GetPosPixel(),
                        pControl->GetSizePixel());
                    --aBox.Left();
                    --aBox.Top();
                    ++aBox.Right();
                    ++aBox.Bottom();
                    mrParent.DrawRect(aBox);
                }
            }
}




//===== ColumnDescriptor ======================================================

ColumnDescriptor::ColumnDescriptor (void)
    : mnWeight(1),
      mnMinimumWidth(0),
      mnMaximumWidth(-1),
      mnLeftPadding(0),
      mnRightPadding(0),
      mnWidth(0)
{
}




ColumnDescriptor::~ColumnDescriptor (void)
{
}




ColumnDescriptor& ColumnDescriptor::SetWeight (const sal_Int32 nWeight)
{
    mnWeight = nWeight;

    return *this;
}




ColumnDescriptor& ColumnDescriptor::SetMinimumWidth (const sal_Int32 nWidth)
{
    mnMinimumWidth = nWidth;

    return *this;
}



ColumnDescriptor& ColumnDescriptor::SetFixedWidth (const sal_Int32 nWidth)
{
    mnMinimumWidth = nWidth;
    mnMaximumWidth = nWidth;

    return *this;
}



ColumnDescriptor& ColumnDescriptor::SetLeftPadding (const sal_Int32 nPadding)
{
    mnLeftPadding = nPadding;

    return *this;
}




ColumnDescriptor& ColumnDescriptor::SetRightPadding (const sal_Int32 nPadding)
{
    mnRightPadding = nPadding;

    return *this;
}




sal_Int32 ColumnDescriptor::GetWeight (void) const
{
    return mnWeight;
}




sal_Int32 ColumnDescriptor::GetMinimumWidth (void) const
{
    return mnMinimumWidth;
}




sal_Int32 ColumnDescriptor::GetMaximumWidth (void) const
{
    return mnMaximumWidth;
}




sal_Int32 ColumnDescriptor::GetTotalMaximumWidth (void) const
{
    return mnMaximumWidth + mnLeftPadding + mnRightPadding;
}




sal_Int32 ColumnDescriptor::GetLeftPadding (void) const
{
    return mnLeftPadding;
}




sal_Int32 ColumnDescriptor::GetRightPadding (void) const
{
    return mnRightPadding;
}




void ColumnDescriptor::SetWidth (const sal_Int32 nWidth)
{
    mnWidth = nWidth;
}




sal_Int32 ColumnDescriptor::GetWidth (void) const
{
    return mnWidth;
}

} } // end of namespace sfx2::sidebar
