/*
    Copyright (C) 2007 Trolltech ASA

    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.

    This class provides all functionality needed for loading images, style sheets and html
    pages from the web. It has a memory cache for these objects.
*/
#include "config.h"
#include "Font.h"
#include "FontDescription.h"
#include "TextStyle.h"

#include "GraphicsContext.h"
#include <QTextLayout>
#include <QPainter>
#include <QFontMetrics>
#include <QFontInfo>
#include <qalgorithms.h>
#include <qdebug.h>

#include <limits.h>
namespace WebCore {

struct TextRunComponent {
    TextRunComponent() : font(0) {}
    TextRunComponent(const UChar *start, int length, bool rtl, const QFont *font, int offset, bool sc = false);
    TextRunComponent(int spaces, bool rtl, const QFont *font, int offset);

    inline bool isSpace() const { return spaces != 0; }

    QString string;
    const QFont *font;
    int width;
    int offset;
    int spaces;
};

TextRunComponent::TextRunComponent(const UChar *start, int length, bool rtl, const QFont *f, int o, bool sc)
    : string(reinterpret_cast<const QChar*>(start), length)
    , font(f)
    , offset(o)
    , spaces(0)
{
    if (sc)
        string = string.toUpper();
    string.prepend(rtl ? QChar(0x202e) : QChar(0x202d));
    width = QFontMetrics(*font).width(string);
}

TextRunComponent::TextRunComponent(int s, bool rtl, const QFont *f, int o)
    : string(s, QLatin1Char(' '))
    , font(f)
    , offset(o)
    , spaces(s)
{
    string.prepend(rtl ? QChar(0x202e) : QChar(0x202d));
    width = spaces * QFontMetrics(*font).width(QLatin1Char(' '));
}


Font::Font()
    : m_letterSpacing(0)
    , m_wordSpacing(0)
    , m_font()
    , m_scFont()
{
    QFontMetrics metrics(m_font);
    m_spaceWidth = metrics.width(QLatin1Char(' '));
    qreal pointsize = m_font.pointSizeF();
    if (pointsize > 0)
        m_scFont.setPointSizeF(pointsize*0.7);
    else
        m_scFont.setPixelSize(qRound(m_font.pixelSize()*.7));
}

Font::Font(const FontDescription& description, short letterSpacing, short wordSpacing)
    : m_fontDescription(description)
    , m_letterSpacing(letterSpacing)
    , m_wordSpacing(wordSpacing)
{
    const FontFamily* family = &description.family();
    QString familyName;
    while (family) {
        familyName += family->family();
        family = family->next();
        if (family)
            familyName += QLatin1Char(',');
    }

    m_font.setFamily(familyName);
    m_font.setPixelSize(qRound(description.computedSize()));
    m_font.setItalic(description.italic());
    if (description.bold()) {
        // Qt's Bold is 75, Webkit is 63.
        m_font.setWeight(QFont::Bold);
    } else {
        m_font.setWeight(description.weight());
    }
    QFontMetrics metrics = QFontMetrics(m_font);
    m_spaceWidth = metrics.width(QLatin1Char(' '));
    m_scFont = m_font;
    m_scFont.setPixelSize(qRound(description.computedSize()*.7));
}

Font::~Font()
{
}
    
Font::Font(const Font& other)
    : m_fontDescription(other.m_fontDescription)
    , m_letterSpacing(other.m_letterSpacing)
    , m_wordSpacing(other.m_wordSpacing)
    , m_font(other.m_font)
    , m_scFont(other.m_scFont)
    , m_spaceWidth(other.m_spaceWidth)
{
}

Font& Font::operator=(const Font& other)
{
    m_fontDescription = other.m_fontDescription;
    m_letterSpacing = other.m_letterSpacing;
    m_wordSpacing = other.m_wordSpacing;
    m_font = other.m_font;
    m_scFont = other.m_scFont;
    m_spaceWidth = other.m_spaceWidth;
    return *this;
}

void Font::update() const
{
    // don't think we need this
}

static int generateComponents(Vector<TextRunComponent, 1024>* components, const Font &font, const TextRun &run, const TextStyle &style)
{
//     qDebug() << "generateComponents" << QString((const QChar *)run.characters(), run.length());
    int letterSpacing = font.letterSpacing();
    int wordSpacing = font.wordSpacing();
    bool smallCaps = font.fontDescription().smallCaps();
    int padding = style.padding();
    int numSpaces = 0;
    if (padding) {
        for (int i = 0; i < run.length(); i++)
            if (Font::treatAsSpace(run[i]))
                ++numSpaces;      
    }

    int offset = 0;
    const QFont *f = &font.font();
    if (letterSpacing || smallCaps) {
        // need to draw every letter on it's own
        int start = 0;
        if (Font::treatAsSpace(run[0])) {
            int add = 0;
            if (numSpaces) {
                add = padding/numSpaces;
                padding -= add;
                --numSpaces;
            }
            components->append(TextRunComponent(1, style.rtl(), &font.font(), offset));
            offset += add + letterSpacing + components->last().width;
            start = 1;
//         qDebug() << "space at 0" << offset;
        } else if (smallCaps) {
            f = (QChar::category(run[0]) == QChar::Letter_Lowercase ? &font.scFont() : &font.font());
        }
        for (int i = 1; i < run.length(); ++i) {
            uint ch = run[i];
            if (QChar(ch).isHighSurrogate() && QChar(run[i-1]).isLowSurrogate())
                ch = QChar::surrogateToUcs4(ch, run[i-1]);
            if (QChar(ch).isLowSurrogate() || QChar::category(ch) == QChar::Mark_NonSpacing)
                continue;
            if (Font::treatAsSpace(run[i])) {
                int add = 0;
//                 qDebug() << "    treatAsSpace:" << i << start;
                if (i - start > 0) {
                    components->append(TextRunComponent(run.characters() + start, i - start,
                                                        style.rtl(), 
                                                        f, offset, f == &font.scFont()));
                    offset += components->last().width + letterSpacing;
//                     qDebug() << "   appending(1) " << components->last().string << components->last().width;
                }
                if (numSpaces) {
                    add = padding/numSpaces;
                    padding -= add;
                    --numSpaces;
                }
                components->append(TextRunComponent(1, style.rtl(), &font.font(), offset));
                offset += wordSpacing + add + components->last().width + letterSpacing;
                start = i + 1;
                continue;
            } else if (!letterSpacing) {
//                 qDebug() << i << char(run[i]) << (QChar::category(ch) == QChar::Letter_Lowercase) <<
//                     QFontInfo(*f).pointSizeF();
                if (QChar::category(ch) == QChar::Letter_Lowercase) {
                    if (f == &font.scFont())
                        continue;
                } else {
                    if (f == &font.font())
                        continue;
                }
            }
            if (i - start > 0) {
                components->append(TextRunComponent(run.characters() + start, i - start,
                                                    style.rtl(), 
                                                    f, offset, f == &font.scFont()));
                offset += components->last().width + letterSpacing;
//                 qDebug() << "   appending(2) " << components->last().string << components->last().width;
            }
            if (smallCaps)
                f = (QChar::category(ch) == QChar::Letter_Lowercase ? &font.scFont() : &font.font());
            start = i;
        }
        if (run.length() - start > 0) {
            components->append(TextRunComponent(run.characters() + start, run.length() - start,
                                                style.rtl(), 
                                                f, offset, f == &font.scFont()));
            offset += components->last().width;
//             qDebug() << "   appending(3) " << components->last().string << components->last().width;
        }
        offset += letterSpacing;
    } else {
        int start = 0;
        for (int i = 0; i < run.length(); ++i) {
            if (Font::treatAsSpace(run[i])) {
                if (i - start > 0) {
                    components->append(TextRunComponent(run.characters() + start, i - start,
                                                        style.rtl(), 
                                                        f, offset));
                    offset += components->last().width;
                }
                int add = 0;
                if (numSpaces) {
                    add = padding/numSpaces;
                    padding -= add;
                    --numSpaces;
                }
                components->append(TextRunComponent(1, style.rtl(), &font.font(), offset));
                offset += add + components->last().width;
                if (i)
                    offset += wordSpacing;
                start = i + 1;
            }
        }
        if (run.length() - start > 0) {
            components->append(TextRunComponent(run.characters() + start, run.length() - start,
                                                style.rtl(), 
                                                f, offset));
            offset += components->last().width;
        }
    }
    return offset;
}

void Font::drawText(GraphicsContext* ctx, const TextRun& run, const TextStyle& style, const FloatPoint& point, int from, int to) const
{
    if (to < 0)
        to = run.length();
    QPainter *p = ctx->platformContext();
    Color color = ctx->fillColor();
    p->setPen(QColor(color));

    Vector<TextRunComponent, 1024> components;
    int w = generateComponents(&components, *this, run, style);

    if (from > 0 || to < run.length()) {
        FloatRect clip = selectionRectForText(run, style,
                                              IntPoint(qRound(point.x()), qRound(point.y())),
                                              QFontMetrics(m_font).height(), from, to);
        QRectF rect(clip.x(), clip.y() - ascent(), clip.width(), clip.height());
        p->save();
        p->setClipRect(rect.toRect());
    }

    if (style.rtl()) {
        for (int i = 0; i < components.size(); ++i) {
            if (!components.at(i).isSpace()) {
                p->setFont(*components.at(i).font);
                QPointF pt(point.x() + w - components.at(i).offset - components.at(i).width, point.y());
                p->drawText(pt, components.at(i).string);
            }
        }
    } else {
        for (int i = 0; i < components.size(); ++i) {
            if (!components.at(i).isSpace()) {
                p->setFont(*components.at(i).font);
                QPointF pt(point.x() + components.at(i).offset, point.y());
                p->drawText(pt, components.at(i).string);
            }
        }
    }
    if (from > 0 || to < run.length())
        p->restore();
}

int Font::width(const TextRun& run, const TextStyle& style) const
{
    Vector<TextRunComponent, 1024> components;
    int w = generateComponents(&components, *this, run, style);

//     qDebug() << "     width=" << w;
    return w;
}

int Font::width(const TextRun& run) const
{
    return width(run, TextStyle());
}

float Font::floatWidth(const TextRun& run, const TextStyle& style) const
{
    return width(run, style);
}

float Font::floatWidth(const TextRun& run) const
{
    return width(run);
}

int Font::offsetForPosition(const TextRun& run, const TextStyle& style, int position, bool includePartialGlyphs) const
{
    Vector<TextRunComponent, 1024> components;
    int w = generateComponents(&components, *this, run, style);

    int offset = 0;
    if (style.rtl()) {
        for (int i = 0; i < components.size(); ++i) {
            int xe = w - components.at(i).offset;
            int xs = xe - components.at(i).width;
            if (position >= xs) {
                QTextLayout layout(components.at(i).string, *components.at(i).font);
                layout.beginLayout();
                QTextLine l = layout.createLine();
                if (!l.isValid()) 
                    return offset;
                
                l.setLineWidth(INT_MAX/256);
                layout.endLayout();

                if (position - xs >= l.width())
                    return offset;
                int cursor = l.xToCursor(position - xs);
                if (cursor > 1)
                    --cursor;
                return offset + cursor;
            } else {
                offset += components.at(i).string.length() - 1;
            }
        }
    } else {
        for (int i = 0; i < components.size(); ++i) {
            int xs = components.at(i).offset;
            int xe = xs + components.at(i).width;
            if (position <= xe) {
                QTextLayout layout(components.at(i).string, *components.at(i).font);
                layout.beginLayout();
                QTextLine l = layout.createLine();
                if (!l.isValid())
                    return offset;
                
                l.setLineWidth(INT_MAX/256);
                layout.endLayout();

                if (position - xs >= l.width())
                    return offset + components.at(i).string.length() - 1;
                int cursor = l.xToCursor(position - xs);
                if (cursor > 1)
                    --cursor;
                return offset + cursor;
            } else {
                offset += components.at(i).string.length() - 1;
            }
        }
    }
    return run.length();
}

static float cursorToX(const Vector<TextRunComponent, 1024>& components, int width,
                     const TextStyle& style, int cursor)
{
    int start = 0;
    for (int i = 0; i < components.size(); ++i) {
        if (start + components.at(i).string.length() - 1 < cursor) {
            start += components.at(i).string.length() - 1;
            continue;
        }
        int xs = components.at(i).offset;
        if (style.rtl())
            xs = width - xs - components.at(i).width;
        QTextLayout layout(components.at(i).string, *components.at(i).font);
        layout.beginLayout();
        QTextLine l = layout.createLine();
        if (!l.isValid())
            return 0;
        
        l.setLineWidth(INT_MAX/256);
        layout.endLayout();
        
        return xs + l.cursorToX(cursor - start + 1);
    }
    return width;
}

FloatRect Font::selectionRectForText(const TextRun& run, const TextStyle& style, const IntPoint& pt,
                                     int h, int from, int to) const
{
    Vector<TextRunComponent, 1024> components;
    int w = generateComponents(&components, *this, run, style);

    if (from == 0 && to == run.length())
        return FloatRect(pt.x(), pt.y(), w, h);

    float x1 = cursorToX(components, w, style, from);
    float x2 = cursorToX(components, w, style, to);
    if (x2 < x1)
        qSwap(x1, x2);

    return FloatRect(pt.x() + x1, pt.y(), x2 - x1, h);
}

bool Font::isFixedPitch() const
{
    return QFontInfo(m_font).fixedPitch();
}

// Metrics that we query the FontFallbackList for.
int Font::ascent() const
{
    return QFontMetrics(m_font).ascent();
}

int Font::descent() const
{
    return QFontMetrics(m_font).descent();
}

int Font::lineSpacing() const
{
    return QFontMetrics(m_font).lineSpacing();
}

float Font::xHeight() const
{
    return QFontMetrics(m_font).xHeight();
}

int Font::spaceWidth() const
{
    return m_spaceWidth;
}

}
