/*
 * Copyright (C) 2003, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
 *
 * 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, or (at your option) any later version.
 *
 * 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.
 *
 */

#pragma once

#include "BidiContext.h"
#include "LegacyInlineFlowBox.h"
#include "RenderBox.h"
#include <wtf/WeakPtr.h>

namespace WebCore {

class HitTestResult;
class LegacyEllipsisBox;
class LogicalSelectionOffsetCaches;
class RenderBlockFlow;
class RenderFragmentContainer;

struct BidiStatus;
struct GapRects;

class LegacyRootInlineBox : public LegacyInlineFlowBox, public CanMakeWeakPtr<LegacyRootInlineBox> {
    WTF_MAKE_ISO_ALLOCATED(LegacyRootInlineBox);
public:
    explicit LegacyRootInlineBox(RenderBlockFlow&);
    virtual ~LegacyRootInlineBox();

    RenderBlockFlow& blockFlow() const;

    void detachEllipsisBox();

    LegacyRootInlineBox* nextRootBox() const;
    LegacyRootInlineBox* prevRootBox() const;

    void adjustPosition(float dx, float dy) final;

    LayoutUnit lineTop() const { return m_lineTop; }
    LayoutUnit lineBottom() const { return m_lineBottom; }

    LayoutUnit lineBoxTop() const { return m_lineBoxTop; }
    LayoutUnit lineBoxBottom() const { return m_lineBoxBottom; }
    LayoutUnit lineBoxHeight() const { return lineBoxBottom() - lineBoxTop(); }
    
    LayoutUnit paginationStrut() const { return m_paginationStrut; }
    void setPaginationStrut(LayoutUnit strut) { m_paginationStrut = strut; }

    bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; }
    void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { m_isFirstAfterPageBreak = isFirstAfterPageBreak; }

    LayoutUnit paginatedLineWidth() const { return m_paginatedLineWidth; }
    void setPaginatedLineWidth(LayoutUnit width) { m_paginatedLineWidth = width; }

    // It should not be assumed the containingFragment() is always valid.
    // It can also be nullptr if the flow has no fragment chain.
    RenderFragmentContainer* containingFragment() const;
    void setContainingFragment(RenderFragmentContainer&);
    void clearContainingFragment();

    LayoutUnit selectionTop() const;
    LayoutUnit selectionBottom() const;
    LayoutUnit selectionHeight() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTop()); }

    LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
    LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }

    LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
    void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit lineBoxTop, LayoutUnit lineBoxBottom)
    { 
        m_lineTop = top; 
        m_lineBottom = bottom;
        m_lineBoxTop = lineBoxTop;
        m_lineBoxBottom = lineBoxBottom;
    }

    RenderObject* lineBreakObj() const { return m_lineBreakObj.get(); }
    BidiStatus lineBreakBidiStatus() const;
    void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);

    unsigned lineBreakPos() const { return m_lineBreakPos; }
    void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }

    bool isForTrailingFloats() const { return m_isForTrailingFloats; }
    void setIsForTrailingFloats() { m_isForTrailingFloats = true; }

    using LegacyInlineBox::endsWithBreak;
    using LegacyInlineBox::setEndsWithBreak;

    void childRemoved(LegacyInlineBox*);

    bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
    // Return the truncatedWidth, the width of the truncated text + ellipsis.
    float placeEllipsis(const AtomString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, LegacyInlineBox* markupBox = nullptr);
    // Return the position of the LegacyEllipsisBox or -1.
    float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) final;

    using LegacyInlineBox::hasEllipsisBox;
    LegacyEllipsisBox* ellipsisBox() const;

    void paintEllipsisBox(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) const;

    void clearTruncation() final;

    bool isHyphenated() const;

    LayoutUnit baselinePosition(FontBaseline baselineType) const final;
    LayoutUnit lineHeight() const final;

    void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
    bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;

    RenderObject::HighlightState selectionState() const final;
    const LegacyInlineBox* firstSelectedBox() const;
    const LegacyInlineBox* lastSelectedBox() const;

    using CleanLineFloatList = Vector<WeakPtr<RenderBox>>;
    void appendFloat(RenderBox& floatingBox)
    {
        ASSERT(!isDirty());
        if (m_floats)
            m_floats->append(floatingBox);
        else
            m_floats = makeUnique<CleanLineFloatList>(1, floatingBox);
    }

    void removeFloat(RenderBox& floatingBox)
    {
        ASSERT(m_floats);
        ASSERT(m_floats->contains(&floatingBox));
        m_floats->remove(m_floats->find(&floatingBox));
    }

    CleanLineFloatList* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }

    void extractLineBoxFromRenderObject() final;
    void attachLineBoxToRenderObject() final;
    void removeLineBoxFromRenderObject() final;
    
    FontBaseline baselineType() const { return static_cast<FontBaseline>(m_baselineType); }

    bool hasAnnotationsBefore() const { return m_hasAnnotationsBefore; }
    bool hasAnnotationsAfter() const { return m_hasAnnotationsAfter; }

    LayoutRect paddedLayoutOverflowRect(LayoutUnit endPadding) const;

    void ascentAndDescentForBox(LegacyInlineBox&, GlyphOverflowAndFallbackFontsMap&, LayoutUnit& ascent, LayoutUnit& descent, bool& affectsAscent, bool& affectsDescent) const;
    LayoutUnit verticalPositionForBox(LegacyInlineBox*, VerticalPositionCache&);
    bool fitsToGlyphs() const;
    bool includesRootLineBoxFontOrLeading() const;
    
    LayoutUnit logicalTopVisualOverflow() const
    {
        return LegacyInlineFlowBox::logicalTopVisualOverflow(lineTop());
    }
    LayoutUnit logicalBottomVisualOverflow() const
    {
        return LegacyInlineFlowBox::logicalBottomVisualOverflow(lineBottom());
    }
    LayoutUnit logicalTopLayoutOverflow() const
    {
        return LegacyInlineFlowBox::logicalTopLayoutOverflow(lineTop());
    }
    LayoutUnit logicalBottomLayoutOverflow() const
    {
        return LegacyInlineFlowBox::logicalBottomLayoutOverflow(lineBottom());
    }

#if ENABLE(TREE_DEBUGGING)
    void outputLineBox(WTF::TextStream&, bool mark, int depth) const final;
    const char* boxName() const final;
#endif
private:
    bool isRootInlineBox() const final { return true; }

    bool includeLeadingForBox(LegacyInlineBox&) const;
    bool includeFontForBox(LegacyInlineBox&) const;
    bool includeGlyphsForBox(LegacyInlineBox&) const;
    bool includeInitialLetterForBox(LegacyInlineBox&) const;
    bool includeMarginForBox(LegacyInlineBox&) const;

    LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0_lu) const;

    LayoutUnit beforeAnnotationsAdjustment() const;

    // Where this line ended. The exact object and the position within that object are stored so that
    // we can create an LegacyInlineIterator beginning just after the end of this line.
    WeakPtr<RenderObject> m_lineBreakObj;
    RefPtr<BidiContext> m_lineBreakContext;

    LayoutUnit m_lineTop;
    LayoutUnit m_lineBottom;

    LayoutUnit m_lineBoxTop;
    LayoutUnit m_lineBoxBottom;

    LayoutUnit m_paginationStrut;
    LayoutUnit m_paginatedLineWidth;

    // Floats hanging off the line are pushed into this vector during layout. It is only
    // good for as long as the line has not been marked dirty.
    std::unique_ptr<CleanLineFloatList> m_floats;

    unsigned m_lineBreakPos { 0 };
};

inline LegacyRootInlineBox* LegacyRootInlineBox::nextRootBox() const
{
    return downcast<LegacyRootInlineBox>(m_nextLineBox);
}

inline LegacyRootInlineBox* LegacyRootInlineBox::prevRootBox() const
{
    return downcast<LegacyRootInlineBox>(m_prevLineBox);
}

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_INLINE_BOX(LegacyRootInlineBox, isRootInlineBox())
