/*
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "LayoutRect.h"
#include "RenderBlockFlow.h"
#include "SimpleLineLayout.h"
#include "SimpleLineLayoutFlowContents.h"
#include <wtf/IteratorRange.h>
#include <wtf/text/WTFString.h>

namespace WebCore {
namespace SimpleLineLayout {

class RunResolver {
    WTF_MAKE_FAST_ALLOCATED;
public:
    class Iterator;

    class Run {
    public:
        explicit Run(const Iterator&);

        // Position relative to the enclosing flow block.
        unsigned start() const;
        unsigned end() const;
        // Position relative to the actual renderer.
        unsigned localStart() const;
        unsigned localEnd() const;

        float logicalLeft() const;
        float logicalRight() const;

        FloatRect rect() const;
        float expansion() const;
        ExpansionBehavior expansionBehavior() const;
        int baselinePosition() const;
        StringView text() const;
        String textWithHyphen() const;
        const RenderObject& renderer() const;
        bool isEndOfLine() const;
        bool hasHyphen() const { return m_iterator.simpleRun().hasHyphen; }
        bool isLineBreak() const { return m_iterator.simpleRun().isLineBreak; }
        const SimpleLineLayout::Run& simpleRun() const { return m_iterator.simpleRun(); }

        unsigned lineIndex() const;

    private:
        float computeBaselinePosition() const;
        void constructStringForHyphenIfNeeded();

        const Iterator& m_iterator;
    };

    class Iterator {
    friend class Run;
    friend class RunResolver;
    friend class LineResolver;
    public:
        Iterator(const RunResolver&, unsigned runIndex, unsigned lineIndex);

        Iterator& operator++();
        Iterator& operator--();

        bool operator==(const Iterator&) const;
        bool operator!=(const Iterator&) const;

        Run operator*() const;

    private:
        const SimpleLineLayout::Run& simpleRun() const;
        unsigned lineIndex() const { return m_lineIndex; }
        Iterator& advance();
        Iterator& advanceLines(unsigned);
        const RunResolver& resolver() const { return *m_resolver; }
        const Layout& layout() const { return *m_layout; }

        RefPtr<const Layout> m_layout;
        const RunResolver* m_resolver;
        unsigned m_runIndex;
        unsigned m_lineIndex;
    };

    RunResolver(const RenderBlockFlow&, const Layout&);

    const RenderBlockFlow& flow() const { return m_flowRenderer; }
    const FlowContents& flowContents() const { return m_flowContents; }
    Iterator begin() const;
    Iterator end() const;

    WTF::IteratorRange<Iterator> rangeForRect(const LayoutRect&) const;
    WTF::IteratorRange<Iterator> rangeForRenderer(const RenderObject&) const;
    WTF::IteratorRange<Iterator> rangeForLine(unsigned lineIndex) const;
    Iterator runForPoint(const LayoutPoint&) const;
    WTF::IteratorRange<Iterator> rangeForRendererWithOffsets(const RenderObject&, unsigned start, unsigned end) const;

private:
    enum class IndexType { First, Last };
    unsigned lineIndexForHeight(LayoutUnit, IndexType) const;
    unsigned adjustLineIndexForStruts(LayoutUnit, IndexType, unsigned lineIndexCandidate) const;

    const RenderBlockFlow& m_flowRenderer;
    const Layout& m_layout;
    const FlowContents m_flowContents;
    const LayoutUnit m_lineHeight;
    const LayoutUnit m_baseline;
    const LayoutUnit m_borderAndPaddingBefore;
    const float m_ascent;
    const float m_descent;
    const float m_visualOverflowOffset;
    const bool m_inQuirksMode;
};

class LineResolver {
public:
    class Iterator {
    public:
        explicit Iterator(RunResolver::Iterator);

        Iterator& operator++();
        bool operator==(const Iterator&) const;
        bool operator!=(const Iterator&) const;

        FloatRect operator*() const;
        // FIXME: Use a list to support multiple renderers per line.
        const RenderObject& renderer() const;

    private:
        RunResolver::Iterator m_runIterator;
    };

    LineResolver(const RunResolver&);

    Iterator begin() const;
    Iterator end() const;

    WTF::IteratorRange<Iterator> rangeForRect(const LayoutRect&) const;

private:
    const RunResolver& m_runResolver;
};

RunResolver runResolver(const RenderBlockFlow&, const Layout&);
LineResolver lineResolver(const RunResolver&);

inline unsigned RunResolver::Run::start() const
{
    return m_iterator.simpleRun().start;
}

inline unsigned RunResolver::Run::end() const
{
    return m_iterator.simpleRun().end;
}

inline float RunResolver::Run::logicalLeft() const
{
    return m_iterator.simpleRun().logicalLeft;
}

inline float RunResolver::Run::logicalRight() const
{
    return m_iterator.simpleRun().logicalRight;
}

inline float RunResolver::Run::expansion() const
{
    return m_iterator.simpleRun().expansion;
}

inline ExpansionBehavior RunResolver::Run::expansionBehavior() const
{
    return m_iterator.simpleRun().expansionBehavior;
}

inline int RunResolver::Run::baselinePosition() const
{
    return roundToInt(computeBaselinePosition());
}

inline bool RunResolver::Run::isEndOfLine() const
{
    return m_iterator.simpleRun().isEndOfLine;
}

inline unsigned RunResolver::Run::lineIndex() const
{
    return m_iterator.lineIndex();
}

inline RunResolver::Iterator& RunResolver::Iterator::operator++()
{
    return advance();
}

inline float RunResolver::Run::computeBaselinePosition() const
{
    auto& resolver = m_iterator.resolver();
    auto offset = resolver.m_borderAndPaddingBefore + resolver.m_lineHeight * lineIndex();
    if (!m_iterator.layout().hasLineStruts())
        return offset + resolver.m_baseline;
    for (auto& strutEntry : resolver.m_layout.struts()) {
        if (strutEntry.lineBreak > lineIndex())
            break;
        offset += strutEntry.offset;
    }
    return offset + resolver.m_baseline;
}

inline RunResolver::Iterator& RunResolver::Iterator::operator--()
{
    --m_runIndex;
    if (simpleRun().isEndOfLine)
        --m_lineIndex;
    return *this;
}

inline bool RunResolver::Iterator::operator==(const Iterator& other) const
{
    ASSERT(m_resolver == other.m_resolver);
    return m_runIndex == other.m_runIndex;
}

inline bool RunResolver::Iterator::operator!=(const Iterator& other) const
{
    return !(*this == other);
}

inline RunResolver::Run RunResolver::Iterator::operator*() const
{
    return Run(*this);
}

inline const SimpleLineLayout::Run& RunResolver::Iterator::simpleRun() const
{
    return layout().runAt(m_runIndex);
}

inline RunResolver::Iterator RunResolver::begin() const
{
    return Iterator(*this, 0, 0);
}

inline RunResolver::Iterator RunResolver::end() const
{
    return Iterator(*this, m_layout.runCount(), m_layout.lineCount());
}

inline LineResolver::Iterator& LineResolver::Iterator::operator++()
{
    m_runIterator.advanceLines(1);
    return *this;
}

inline bool LineResolver::Iterator::operator==(const Iterator& other) const
{
    return m_runIterator == other.m_runIterator;
}

inline bool LineResolver::Iterator::operator!=(const Iterator& other) const
{
    return m_runIterator != other.m_runIterator;
}

inline LineResolver::Iterator LineResolver::begin() const
{
    return Iterator(m_runResolver.begin());
}

inline LineResolver::Iterator LineResolver::end() const
{
    return Iterator(m_runResolver.end());
}

inline WTF::IteratorRange<LineResolver::Iterator> LineResolver::rangeForRect(const LayoutRect& rect) const
{
    auto runRange = m_runResolver.rangeForRect(rect);
    return { Iterator(runRange.begin()), Iterator(runRange.end()) };
}

inline LineResolver lineResolver(const RunResolver& runResolver)
{
    return LineResolver(runResolver);
}

}
}
