/*
 * This file is part of the HTML rendering engine for KDE.
 *
 * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
 *           (C) 2002 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2006 Apple Computer, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "FixedTableLayout.h"

#include "RenderTable.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
#include "RenderTableSection.h"

/*
  The text below is from the CSS 2.1 specs.

  Fixed table layout

  With this (fast) algorithm, the horizontal layout of the table does
  not depend on the contents of the cells; it only depends on the
  table's width, the width of the columns, and borders or cell
  spacing.

  The table's width may be specified explicitly with the 'width'
  property. A value of 'auto' (for both 'display: table' and 'display:
  inline-table') means use the automatic table layout algorithm.

  In the fixed table layout algorithm, the width of each column is
  determined as follows:

    1. A column element with a value other than 'auto' for the 'width'
    property sets the width for that column.

    2. Otherwise, a cell in the first row with a value other than
    'auto' for the 'width' property sets the width for that column. If
    the cell spans more than one column, the width is divided over the
    columns.

    3. Any remaining columns equally divide the remaining horizontal
    table space (minus borders or cell spacing).

  The width of the table is then the greater of the value of the
  'width' property for the table element and the sum of the column
  widths (plus cell spacing or borders). If the table is wider than
  the columns, the extra space should be distributed over the columns.


  In this manner, the user agent can begin to lay out the table once
  the entire first row has been received. Cells in subsequent rows do
  not affect column widths. Any cell that has content that overflows
  uses the 'overflow' property to determine whether to clip the
  overflow content.
*/

using namespace std;

namespace WebCore {

FixedTableLayout::FixedTableLayout(RenderTable* table)
    : TableLayout(table)
{
}

int FixedTableLayout::calcWidthArray(int)
{
    int usedWidth = 0;

    // iterate over all <col> elements
    RenderObject* child = m_table->firstChild();
    int nEffCols = m_table->numEffCols();
    m_width.resize(nEffCols);
    m_width.fill(Length(Auto));

    int currentEffectiveColumn = 0;
    Length grpWidth;
    while (child) {
        if (child->isTableCol()) {
            RenderTableCol* col = static_cast<RenderTableCol*>(child);
            if (col->firstChild())
                grpWidth = col->style()->width();
            else {
                Length w = col->style()->width();
                if (w.isAuto())
                    w = grpWidth;
                int effWidth = 0;
                if (w.isFixed() && w.value() > 0)
                    effWidth = w.value();

                int span = col->span();
                while (span) {
                    int spanInCurrentEffectiveColumn;
                    if (currentEffectiveColumn >= nEffCols) {
                        m_table->appendColumn(span);
                        nEffCols++;
                        m_width.append(Length());
                        spanInCurrentEffectiveColumn = span;
                    } else {
                        if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
                            m_table->splitColumn(currentEffectiveColumn, span);
                            nEffCols++;
                            m_width.append(Length());
                        }
                        spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
                    }
                    if ((w.isFixed() || w.isPercent()) && w.isPositive()) {
                        m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn);
                        usedWidth += effWidth * spanInCurrentEffectiveColumn;
                    }
                    span -= spanInCurrentEffectiveColumn;
                    currentEffectiveColumn++;
                }
            }
            static_cast<RenderTableCol*>(child)->calcPrefWidths();
        } else
            break;

        RenderObject* next = child->firstChild();
        if (!next)
            next = child->nextSibling();
        if (!next && child->parent()->isTableCol()) {
            next = child->parent()->nextSibling();
            grpWidth = Length();
        }
        child = next;
    }

    // Iterate over the first row in case some are unspecified.
    RenderTableSection* section = m_table->header();
    if (!section)
        section = m_table->firstBody();
    if (!section)
        section = m_table->footer();
    if (section && !section->numRows())
        section = m_table->sectionBelow(section, true);
    if (section) {
        int cCol = 0;
        RenderObject* firstRow = section->firstChild();
        child = firstRow->firstChild();
        while (child) {
            if (child->isTableCell()) {
                RenderTableCell* cell = static_cast<RenderTableCell*>(child);
                if (cell->prefWidthsDirty())
                    cell->calcPrefWidths();

                Length w = cell->styleOrColWidth();
                int span = cell->colSpan();
                int effWidth = 0;
                if (w.isFixed() && w.isPositive())
                    effWidth = w.value();
                
                int usedSpan = 0;
                int i = 0;
                while (usedSpan < span) {
                    ASSERT(cCol + i < nEffCols);
                    int eSpan = m_table->spanOfEffCol(cCol + i);
                    // Only set if no col element has already set it.
                    if (m_width[cCol + i].isAuto() && w.type() != Auto) {
                        m_width[cCol + i].setRawValue(w.type(), w.rawValue() * eSpan / span);
                        usedWidth += effWidth * eSpan / span;
                    }
                    usedSpan += eSpan;
                    i++;
                }
                cCol += i;
            }
            child = child->nextSibling();
        }
    }

    return usedWidth;
}

// Use a very large value (in effect infinite). But not too large!
// numeric_limits<int>::max() will too easily overflow widths.
// Keep this in synch with BLOCK_MAX_WIDTH in RenderBlock.cpp
#define TABLE_MAX_WIDTH 15000

void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth)
{
    // FIXME: This entire calculation is incorrect for both minwidth and maxwidth.
    
    // we might want to wait until we have all of the first row before
    // layouting for the first time.

    // only need to calculate the minimum width as the sum of the
    // cols/cells with a fixed width.
    //
    // The maximum width is max(minWidth, tableWidth).
    int bs = m_table->bordersPaddingAndSpacing();
    
    int tableWidth = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs : 0;
    int mw = calcWidthArray(tableWidth) + bs;

    minWidth = max(mw, tableWidth);
    maxWidth = minWidth;

    // This quirk is very similar to one that exists in RenderBlock::calcBlockPrefWidths().
    // Here's the example for this one:
    /*
        <table style="width:100%; background-color:red"><tr><td>
            <table style="background-color:blue"><tr><td>
                <table style="width:100%; background-color:green; table-layout:fixed"><tr><td>
                    Content
                </td></tr></table>
            </td></tr></table>
        </td></tr></table>
    */ 
    // In this example, the two inner tables should be as large as the outer table. 
    // We can achieve this effect by making the maxwidth of fixed tables with percentage
    // widths be infinite.
    if (m_table->style()->htmlHacks() && m_table->style()->width().isPercent() 
        && maxWidth < TABLE_MAX_WIDTH)
        maxWidth = TABLE_MAX_WIDTH;
}

void FixedTableLayout::layout()
{
    int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing();
    int nEffCols = m_table->numEffCols();
    Vector<int> calcWidth(nEffCols, 0);

    int numAuto = 0;
    int autoSpan = 0;
    int totalFixedWidth = 0;
    int totalPercentWidth = 0;
    int totalRawPercent = 0;

    // Compute requirements and try to satisfy fixed and percent widths.
    // Percentages are of the table's width, so for example
    // for a table width of 100px with columns (40px, 10%), the 10% compute
    // to 10px here, and will scale up to 20px in the final (80px, 20px).
    for (int i = 0; i < nEffCols; i++) {
        if (m_width[i].isFixed()) {
            calcWidth[i] = m_width[i].value();
            totalFixedWidth += calcWidth[i];
        } else if (m_width[i].isPercent()) {
            calcWidth[i] = m_width[i].calcValue(tableWidth);
            totalPercentWidth += calcWidth[i];
            totalRawPercent += m_width[i].rawValue();
        } else if (m_width[i].isAuto()) {
            numAuto++;
            autoSpan += m_table->spanOfEffCol(i);
        }
    }

    int hspacing = m_table->hBorderSpacing();
    int totalWidth = totalFixedWidth + totalPercentWidth;
    if (!numAuto || totalWidth > tableWidth) {
        // If there are no auto columns, or if the total is too wide, take
        // what we have and scale it to fit as necessary.
        if (totalWidth != tableWidth) {
            // Fixed widths only scale up
            if (totalFixedWidth && totalWidth < tableWidth) {
                totalFixedWidth = 0;
                for (int i = 0; i < nEffCols; i++) {
                    if (m_width[i].isFixed()) {
                        calcWidth[i] = calcWidth[i] * tableWidth / totalWidth;
                        totalFixedWidth += calcWidth[i];
                    }
                }
            }
            if (totalRawPercent) {
                totalPercentWidth = 0;
                for (int i = 0; i < nEffCols; i++) {
                    if (m_width[i].isPercent()) {
                        calcWidth[i] = m_width[i].rawValue() * (tableWidth - totalFixedWidth) / totalRawPercent;
                        totalPercentWidth += calcWidth[i];
                    }
                }
            }
            totalWidth = totalFixedWidth + totalPercentWidth;
        }
    } else {
        // Divide the remaining width among the auto columns.
        int remainingWidth = tableWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto);
        int lastAuto = 0;
        for (int i = 0; i < nEffCols; i++) {
            if (m_width[i].isAuto()) {
                int span = m_table->spanOfEffCol(i);
                int w = remainingWidth * span / autoSpan;
                calcWidth[i] = w + hspacing * (span - 1);
                remainingWidth -= w;
                if (!remainingWidth)
                    break;
                lastAuto = i;
                numAuto--;
                autoSpan -= span;
            }
        }
        // Last one gets the remainder.
        if (remainingWidth)
            calcWidth[lastAuto] += remainingWidth;
        totalWidth = tableWidth;
    }

    if (totalWidth < tableWidth) {
        // Spread extra space over columns.
        int remainingWidth = tableWidth - totalWidth;
        int total = nEffCols;
        while (total) {
            int w = remainingWidth / total;
            remainingWidth -= w;
            calcWidth[--total] += w;
        }
        if (nEffCols > 0)
            calcWidth[nEffCols - 1] += remainingWidth;
    }
    
    int pos = 0;
    for (int i = 0; i < nEffCols; i++) {
        m_table->columnPositions()[i] = pos;
        pos += calcWidth[i] + hspacing;
    }
    int colPositionsSize = m_table->columnPositions().size();
    if (colPositionsSize > 0)
        m_table->columnPositions()[colPositionsSize - 1] = pos;
}

} // namespace WebCore
