/*
 * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
 * Copyright (C) 2007-2008 Torch Mobile Inc.
 *
 * 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "FloatPoint.h"
#include "FloatSize.h"
#include "Glyph.h"
#include "GlyphBufferMembers.h"
#include <climits>
#include <limits>
#include <wtf/Vector.h>

namespace WebCore {

class Font;

class GlyphBuffer {
public:
    bool isEmpty() const { return m_fonts.isEmpty(); }
    unsigned size() const { return m_fonts.size(); }
    
    void clear()
    {
        m_fonts.clear();
        m_glyphs.clear();
        m_advances.clear();
        m_origins.clear();
        m_offsetsInString.clear();
    }

    const Font** fonts(unsigned from) { return m_fonts.data() + from; }
    GlyphBufferGlyph* glyphs(unsigned from) { return m_glyphs.data() + from; }
    GlyphBufferAdvance* advances(unsigned from) { return m_advances.data() + from; }
    GlyphBufferOrigin* origins(unsigned from) { return m_origins.data() + from; }
    GlyphBufferStringOffset* offsetsInString(unsigned from) { return m_offsetsInString.data() + from; }
    const Font* const * fonts(unsigned from) const { return m_fonts.data() + from; }
    const GlyphBufferGlyph* glyphs(unsigned from) const { return m_glyphs.data() + from; }
    const GlyphBufferAdvance* advances(unsigned from) const { return m_advances.data() + from; }
    const GlyphBufferOrigin* origins(unsigned from) const { return m_origins.data() + from; }
    const GlyphBufferStringOffset* offsetsInString(unsigned from) const { return m_offsetsInString.data() + from; }

    const Font& fontAt(unsigned index) const
    {
        ASSERT(m_fonts[index]);
        return *m_fonts[index];
    }
    GlyphBufferGlyph glyphAt(unsigned index) const { return m_glyphs[index]; }
    GlyphBufferAdvance advanceAt(unsigned index) const { return m_advances[index]; }
    GlyphBufferOrigin originAt(unsigned index) const { return m_origins[index]; }
    GlyphBufferStringOffset uncheckedStringOffsetAt(unsigned index) const { return m_offsetsInString[index]; }
    std::optional<GlyphBufferStringOffset> checkedStringOffsetAt(unsigned index, unsigned stringLength) const
    {
        auto result = uncheckedStringOffsetAt(index);
        if (static_cast<std::make_unsigned_t<GlyphBufferStringOffset>>(result) >= stringLength)
            return std::nullopt;
        return result;
    }

    void setInitialAdvance(GlyphBufferAdvance initialAdvance) { m_initialAdvance = initialAdvance; }
    const GlyphBufferAdvance& initialAdvance() const { return m_initialAdvance; }
    void expandInitialAdvance(float width) { setWidth(m_initialAdvance, WebCore::width(m_initialAdvance) + width); }
    void expandInitialAdvance(GlyphBufferAdvance additionalAdvance)
    {
        setWidth(m_initialAdvance, width(m_initialAdvance) + width(additionalAdvance));
        setHeight(m_initialAdvance, height(m_initialAdvance) + height(additionalAdvance));
    }
    
    static constexpr GlyphBufferStringOffset noOffset = std::numeric_limits<GlyphBufferStringOffset>::max();
    void add(Glyph glyph, const Font& font, float width, GlyphBufferStringOffset offsetInString = noOffset)
    {
        GlyphBufferAdvance advance = makeGlyphBufferAdvance(width, 0);
        add(glyph, font, advance, offsetInString);
    }

    void add(Glyph glyph, const Font& font, GlyphBufferAdvance advance, GlyphBufferStringOffset offsetInString)
    {
        m_fonts.append(&font);
        m_glyphs.append(glyph);
        m_advances.append(advance);
        m_origins.append(makeGlyphBufferOrigin());
        m_offsetsInString.append(offsetInString);
    }

    void remove(unsigned location, unsigned length)
    {
        m_fonts.remove(location, length);
        m_glyphs.remove(location, length);
        m_advances.remove(location, length);
        m_origins.remove(location, length);
        m_offsetsInString.remove(location, length);
    }

    void deleteGlyphWithoutAffectingSize(unsigned index)
    {
        makeGlyphInvisible(index);
        m_advances[index] = makeGlyphBufferAdvance();
    }

    void makeGlyphInvisible(unsigned index)
    {
        // GlyphID 0xFFFF is the "deleted glyph" and is supposed to be invisible when rendered.
        static const constexpr GlyphBufferGlyph deletedGlyph = 0xFFFF;
        m_glyphs[index] = deletedGlyph;
    }

    void makeHole(unsigned location, unsigned length, const Font* font)
    {
        ASSERT(location <= size());

        m_fonts.insertVector(location, Vector<const Font*>(length, font));
        m_glyphs.insertVector(location, Vector<GlyphBufferGlyph>(length, std::numeric_limits<GlyphBufferGlyph>::max()));
        m_advances.insertVector(location, Vector<GlyphBufferAdvance>(length, makeGlyphBufferAdvance()));
        m_origins.insertVector(location, Vector<GlyphBufferOrigin>(length, makeGlyphBufferOrigin()));
        m_offsetsInString.insertVector(location, Vector<GlyphBufferStringOffset>(length, 0));
    }

    void reverse(unsigned from, unsigned length)
    {
        for (unsigned i = from, end = from + length - 1; i < end; ++i, --end)
            swap(i, end);
    }

    void expandLastAdvance(float width)
    {
        ASSERT(!isEmpty());
        GlyphBufferAdvance& lastAdvance = m_advances.last();
        setWidth(lastAdvance, WebCore::width(lastAdvance) + width);
    }

    void expandAdvance(unsigned index, float width)
    {
        ASSERT(index < size());
        auto& lastAdvance = m_advances[index];
        setWidth(lastAdvance, WebCore::width(lastAdvance) + width);
    }

    void expandLastAdvance(GlyphBufferAdvance expansion)
    {
        ASSERT(!isEmpty());
        GlyphBufferAdvance& lastAdvance = m_advances.last();
        setWidth(lastAdvance, width(lastAdvance) + width(expansion));
        setHeight(lastAdvance, height(lastAdvance) + height(expansion));
    }

    void shrink(unsigned truncationPoint)
    {
        m_fonts.shrink(truncationPoint);
        m_glyphs.shrink(truncationPoint);
        m_advances.shrink(truncationPoint);
        m_origins.shrink(truncationPoint);
        m_offsetsInString.shrink(truncationPoint);
    }

    /*
     * This is the unflattened format:
     *
     *                                              X (Paint glyph position)   X (Paint glyph position)   X (Paint glyph position)
     *                                             7                          7                          7
     *                                            /                          /                          /
     *                                           / (Origin)                 / (Origin)                 / (Origin)
     *                                          /                          /                          /
     *                                         /                          /                          /
     *                X---------------------->X------------------------->X------------------------->X------------------------->X
     * (text position ^)  (Initial advance)            (Advance)                  (Advance)                   (Advance)
     *
     *
     *
     *
     *
     * And this is what we transform it into:
     *
     *                                        ----->X------------------------->X------------------------->X
     *                                       /               (Advance)                   (Advance)         \
     *                                      /                                                               \
     *                   (Initial advance) /                                                                 \   (Advance)
     *                  -------------------                                                                   ----------------
     *                 /                                                                                                      \
     *                X                                                                                                        X
     * (text position ^)
     *
     * This is an operation that discards all layout information, and preserves only paint information.
     */
    void flatten()
    {
        ASSERT(size() || (!width(m_initialAdvance) && !height(m_initialAdvance)));
        if (size()) {
            m_initialAdvance = makeGlyphBufferAdvance(
                width(m_initialAdvance) + x(m_origins[0]),
                height(m_initialAdvance) + y(m_origins[0]));
        }
        for (unsigned i = 0; i < size(); ++i) {
            m_advances[i] = makeGlyphBufferAdvance(
                -x(m_origins[i]) + width(m_advances[i]) + (i + 1 < size() ? x(m_origins[i + 1]) : 0),
                -y(m_origins[i]) + height(m_advances[i]) + (i + 1 < size() ? y(m_origins[i + 1]) : 0));
            m_origins[i] = makeGlyphBufferOrigin();
        }
    }

#if ASSERT_ENABLED
    bool isFlattened() const
    {
        for (unsigned i = 0; i < size(); ++i) {
            if (x(m_origins[i]) || y(m_origins[i]))
                return false;
        }
        return true;
    }
#endif

private:
    void swap(unsigned index1, unsigned index2)
    {
        auto font = m_fonts[index1];
        m_fonts[index1] = m_fonts[index2];
        m_fonts[index2] = font;

        auto glyph = m_glyphs[index1];
        m_glyphs[index1] = m_glyphs[index2];
        m_glyphs[index2] = glyph;

        auto advance = m_advances[index1];
        m_advances[index1] = m_advances[index2];
        m_advances[index2] = advance;

        auto origin = m_origins[index1];
        m_origins[index1] = m_origins[index2];
        m_origins[index2] = origin;

        auto offset = m_offsetsInString[index1];
        m_offsetsInString[index1] = m_offsetsInString[index2];
        m_offsetsInString[index2] = offset;
    }

    Vector<const Font*, 1024> m_fonts;
    Vector<GlyphBufferGlyph, 1024> m_glyphs;
    Vector<GlyphBufferAdvance, 1024> m_advances;
    Vector<GlyphBufferOrigin, 1024> m_origins;
    Vector<GlyphBufferStringOffset, 1024> m_offsetsInString;
    GlyphBufferAdvance m_initialAdvance { makeGlyphBufferAdvance() };
};

}
