/*
    Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
                  2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>

    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.
*/

#include "config.h"

#if ENABLE(SVG)
#include "SVGTextContentElement.h"

#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "ExceptionCode.h"
#include "FloatPoint.h"
#include "FloatRect.h"
#include "Frame.h"
#include "MappedAttribute.h"
#include "Position.h"
#include "RenderSVGText.h"
#include "SVGCharacterLayoutInfo.h"
#include "SVGInlineTextBox.h"
#include "SVGLength.h"
#include "SVGNames.h"
#include "SVGRootInlineBox.h"
#include "SelectionController.h"
#include "XMLNames.h"
#include <wtf/StdLibExtras.h>

namespace WebCore {

char SVGTextContentElementIdentifier[] = "SVGTextContentElement";

SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document* doc)
    : SVGStyledElement(tagName, doc)
    , SVGTests()
    , SVGLangSpace()
    , SVGExternalResourcesRequired()
    , m_textLength(this, SVGNames::textLengthAttr, LengthModeOther)
    , m_lengthAdjust(this, SVGNames::lengthAdjustAttr, LENGTHADJUST_SPACING)
{
}

SVGTextContentElement::~SVGTextContentElement()
{
}

static inline float cumulativeCharacterRangeLength(const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end, SVGInlineTextBox* textBox,
                                                   int startOffset, long startPosition, long length, bool isVerticalText, long& atCharacter)
{
    if (!length)
        return 0.0f;

    float textLength = 0.0f;
    RenderStyle* style = textBox->textRenderer()->style();

    bool usesFullRange = (startPosition == -1 && length == -1);

    for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
        if (usesFullRange || (atCharacter >= startPosition && atCharacter <= startPosition + length)) {
            unsigned int newOffset = textBox->start() + (it - start) + startOffset;

            // Take RTL text into account and pick right glyph width/height.
            if (textBox->direction() == RTL)
                newOffset = textBox->start() + textBox->end() - newOffset;

            // FIXME: does this handle multichar glyphs ok? not sure
            int charsConsumed = 0;
            String glyphName;
            if (isVerticalText)
                textLength += textBox->calculateGlyphHeight(style, newOffset, 0);
            else
                textLength += textBox->calculateGlyphWidth(style, newOffset, 0, charsConsumed, glyphName);
        }

        if (!usesFullRange) {
            if (atCharacter == startPosition + length - 1)
                break;

            atCharacter++;
        }
    }

    return textLength;
}

// Helper class for querying certain glyph information
struct SVGInlineTextBoxQueryWalker {
    typedef enum {
        NumberOfCharacters,
        TextLength,
        SubStringLength,
        StartPosition,
        EndPosition,
        Extent,
        Rotation,
        CharacterNumberAtPosition
    } QueryMode;

    SVGInlineTextBoxQueryWalker(const SVGTextContentElement* reference, QueryMode mode)
        : m_reference(reference)
        , m_mode(mode)
        , m_queryStartPosition(0)
        , m_queryLength(0)
        , m_queryPointInput()
        , m_queryLongResult(0)
        , m_queryFloatResult(0.0f)
        , m_queryPointResult()
        , m_queryRectResult()
        , m_stopProcessing(true)    
        , m_atCharacter(0)
    {
    }

    void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix&,
                              const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
    {
        RenderStyle* style = textBox->textRenderer()->style();
        bool isVerticalText = style->svgStyle()->writingMode() == WM_TBRL || style->svgStyle()->writingMode() == WM_TB;

        switch (m_mode) {
        case NumberOfCharacters:
        {    
            m_queryLongResult += (end - start);
            m_stopProcessing = false;
            return;
        }
        case TextLength:
        {
            float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, -1, -1, isVerticalText, m_atCharacter);

            if (isVerticalText)
                m_queryFloatResult += textLength;
            else
                m_queryFloatResult += textLength;

            m_stopProcessing = false;
            return;
        }
        case SubStringLength:
        {
            long startPosition = m_queryStartPosition;
            long length = m_queryLength;

            float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, startPosition, length, isVerticalText, m_atCharacter);

            if (isVerticalText)
                m_queryFloatResult += textLength;
            else
                m_queryFloatResult += textLength;

            if (m_atCharacter == startPosition + length)
                m_stopProcessing = true;
            else
                m_stopProcessing = false;

            return;
        }
        case StartPosition:
        {
            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
                if (m_atCharacter == m_queryStartPosition) {
                    m_queryPointResult = FloatPoint(it->x, it->y);
                    m_stopProcessing = true;
                    return;
                }

                m_atCharacter++;
            }

            m_stopProcessing = false;
            return;
        }
        case EndPosition:
        {
            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
                if (m_atCharacter == m_queryStartPosition) {
                    unsigned int newOffset = textBox->start() + (it - start) + startOffset;

                    // Take RTL text into account and pick right glyph width/height.
                    if (textBox->direction() == RTL)
                        newOffset = textBox->start() + textBox->end() - newOffset;

                    int charsConsumed;
                    String glyphName;
                    // calculateGlyph{Height,Width} will consume at least one character. This is the number of characters available
                    // to them beyond that first one.
                    int extraCharactersAvailable = end - it - 1;
                    if (isVerticalText)
                        m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset, extraCharactersAvailable));
                    else
                        m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset, extraCharactersAvailable, charsConsumed, glyphName), it->y);

                    m_stopProcessing = true;
                    return;
                }

                m_atCharacter++;
            }

            m_stopProcessing = false;
            return;
        }
        case Extent:
        {
            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
                if (m_atCharacter == m_queryStartPosition) {
                    unsigned int newOffset = textBox->start() + (it - start) + startOffset;
                    m_queryRectResult = textBox->calculateGlyphBoundaries(style, newOffset, *it);
                    m_stopProcessing = true;
                    return;
                }

                m_atCharacter++;
            }

            m_stopProcessing = false;
            return;
        }
        case Rotation:
        {
            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
                if (m_atCharacter == m_queryStartPosition) {
                    m_queryFloatResult = it->angle;
                    m_stopProcessing = true;
                    return;
                }

                m_atCharacter++;
            }

            m_stopProcessing = false;
            return;
        }
        case CharacterNumberAtPosition:
        {
            int offset = 0;
            SVGChar* charAtPos = textBox->closestCharacterToPosition(m_queryPointInput.x(), m_queryPointInput.y(), offset);

            offset += m_atCharacter;
            if (charAtPos && offset > m_queryLongResult)
                m_queryLongResult = offset;

            m_atCharacter += end - start;
            m_stopProcessing = false;
            return;
        }
        default:
            ASSERT_NOT_REACHED();
            m_stopProcessing = true;
            return;
        }
    }

    void setQueryInputParameters(long startPosition, long length, FloatPoint referencePoint)
    {
        m_queryStartPosition = startPosition;
        m_queryLength = length;
        m_queryPointInput = referencePoint;
    }

    long longResult() const { return m_queryLongResult; }
    float floatResult() const { return m_queryFloatResult; }
    FloatPoint pointResult() const { return m_queryPointResult; }
    FloatRect rectResult() const { return m_queryRectResult; }
    bool stopProcessing() const { return m_stopProcessing; }

private:
    const SVGTextContentElement* m_reference;
    QueryMode m_mode;

    long m_queryStartPosition;
    long m_queryLength;
    FloatPoint m_queryPointInput;

    long m_queryLongResult;
    float m_queryFloatResult;
    FloatPoint m_queryPointResult;
    FloatRect m_queryRectResult;

    bool m_stopProcessing;
    long m_atCharacter;
};

static Vector<SVGInlineTextBox*> findInlineTextBoxInTextChunks(const SVGTextContentElement* element, const Vector<SVGTextChunk>& chunks)
{   
    Vector<SVGTextChunk>::const_iterator it = chunks.begin();
    const Vector<SVGTextChunk>::const_iterator end = chunks.end();

    Vector<SVGInlineTextBox*> boxes;

    for (; it != end; ++it) {
        Vector<SVGInlineBoxCharacterRange>::const_iterator boxIt = it->boxes.begin();
        const Vector<SVGInlineBoxCharacterRange>::const_iterator boxEnd = it->boxes.end();

        for (; boxIt != boxEnd; ++boxIt) {
            SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(boxIt->box);

            Node* textElement = textBox->textRenderer()->parent()->node();
            ASSERT(textElement);

            if (textElement == element || textElement->parent() == element)
                boxes.append(textBox);
        }
    }

    return boxes;
}

static inline SVGRootInlineBox* rootInlineBoxForTextContentElement(const SVGTextContentElement* element)
{
    RenderObject* object = element->renderer();
    
    if (!object || !object->isSVGText() || object->isText())
        return 0;

    RenderSVGText* svgText = static_cast<RenderSVGText*>(object);

    // Find root inline box
    SVGRootInlineBox* rootBox = static_cast<SVGRootInlineBox*>(svgText->firstRootBox());
    if (!rootBox) {
        // Layout is not sync yet!
        element->document()->updateLayoutIgnorePendingStylesheets();
        rootBox = static_cast<SVGRootInlineBox*>(svgText->firstRootBox());
    }

    ASSERT(rootBox);
    return rootBox;
}

static inline SVGInlineTextBoxQueryWalker executeTextQuery(const SVGTextContentElement* element, SVGInlineTextBoxQueryWalker::QueryMode mode,
                                                           long startPosition = 0, long length = 0, FloatPoint referencePoint = FloatPoint())
{
    SVGRootInlineBox* rootBox = rootInlineBoxForTextContentElement(element);
    if (!rootBox)
        return SVGInlineTextBoxQueryWalker(0, mode);

    // Find all inline text box associated with our renderer
    Vector<SVGInlineTextBox*> textBoxes = findInlineTextBoxInTextChunks(element, rootBox->svgTextChunks());

    // Walk text chunks to find chunks associated with our inline text box
    SVGInlineTextBoxQueryWalker walkerCallback(element, mode);
    walkerCallback.setQueryInputParameters(startPosition, length, referencePoint);

    SVGTextChunkWalker<SVGInlineTextBoxQueryWalker> walker(&walkerCallback, &SVGInlineTextBoxQueryWalker::chunkPortionCallback);

    Vector<SVGInlineTextBox*>::iterator it = textBoxes.begin();
    Vector<SVGInlineTextBox*>::iterator end = textBoxes.end();

    for (; it != end; ++it) {
        rootBox->walkTextChunks(&walker, *it);

        if (walkerCallback.stopProcessing())
            break;
    }

    return walkerCallback;
}

unsigned SVGTextContentElement::getNumberOfChars() const
{
    document()->updateLayoutIgnorePendingStylesheets();

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::NumberOfCharacters).longResult();
}

float SVGTextContentElement::getComputedTextLength() const
{
    document()->updateLayoutIgnorePendingStylesheets();

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::TextLength).floatResult();
}

float SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchars, ExceptionCode& ec) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    unsigned numberOfChars = getNumberOfChars();
    if (charnum >= numberOfChars) {
        ec = INDEX_SIZE_ERR;
        return 0.0f;
    }

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::SubStringLength, charnum, nchars).floatResult();
}

FloatPoint SVGTextContentElement::getStartPositionOfChar(unsigned charnum, ExceptionCode& ec) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    if (charnum > getNumberOfChars()) {
        ec = INDEX_SIZE_ERR;
        return FloatPoint();
    }

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::StartPosition, charnum).pointResult();
}

FloatPoint SVGTextContentElement::getEndPositionOfChar(unsigned charnum, ExceptionCode& ec) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    if (charnum > getNumberOfChars()) {
        ec = INDEX_SIZE_ERR;
        return FloatPoint();
    }

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::EndPosition, charnum).pointResult();
}

FloatRect SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionCode& ec) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    if (charnum > getNumberOfChars()) {
        ec = INDEX_SIZE_ERR;
        return FloatRect();
    }

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::Extent, charnum).rectResult();
}

float SVGTextContentElement::getRotationOfChar(unsigned charnum, ExceptionCode& ec) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    if (charnum > getNumberOfChars()) {
        ec = INDEX_SIZE_ERR;
        return 0.0f;
    }

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::Rotation, charnum).floatResult();
}

int SVGTextContentElement::getCharNumAtPosition(const FloatPoint& point) const
{
    document()->updateLayoutIgnorePendingStylesheets();

    return executeTextQuery(this, SVGInlineTextBoxQueryWalker::CharacterNumberAtPosition, 0.0f, 0.0f, point).longResult();
}

void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, ExceptionCode& ec) const
{
    unsigned numberOfChars = getNumberOfChars();
    if (charnum >= numberOfChars) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (nchars > numberOfChars - charnum)
        nchars = numberOfChars - charnum;

    ASSERT(document());
    ASSERT(document()->frame());

    SelectionController* controller = document()->frame()->selection();
    if (!controller)
        return;

    // Find selection start
    VisiblePosition start(const_cast<SVGTextContentElement*>(this), 0, SEL_DEFAULT_AFFINITY);
    for (unsigned i = 0; i < charnum; ++i)
        start = start.next();

    // Find selection end
    VisiblePosition end(start);
    for (unsigned i = 0; i < nchars; ++i)
        end = end.next();

    controller->setSelection(VisibleSelection(start, end));
}

void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr)
{
    if (attr->name() == SVGNames::lengthAdjustAttr) {
        if (attr->value() == "spacing")
            setLengthAdjustBaseValue(LENGTHADJUST_SPACING);
        else if (attr->value() == "spacingAndGlyphs")
            setLengthAdjustBaseValue(LENGTHADJUST_SPACINGANDGLYPHS);
    } else if (attr->name() == SVGNames::textLengthAttr) {
        setTextLengthBaseValue(SVGLength(LengthModeOther, attr->value()));
        if (textLengthBaseValue().value(this) < 0.0)
            document()->accessSVGExtensions()->reportError("A negative value for text attribute <textLength> is not allowed");
    } else {
        if (SVGTests::parseMappedAttribute(attr))
            return;
        if (SVGLangSpace::parseMappedAttribute(attr)) {
            if (attr->name().matches(XMLNames::spaceAttr)) {
                DEFINE_STATIC_LOCAL(const AtomicString, preserveString, ("preserve"));

                if (attr->value() == preserveString)
                    addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePre);
                else
                    addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueNowrap);
            }
            return;
        }
        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
            return;

        SVGStyledElement::parseMappedAttribute(attr);
    }
}

bool SVGTextContentElement::isKnownAttribute(const QualifiedName& attrName)
{
    return (attrName.matches(SVGNames::lengthAdjustAttr) ||
            attrName.matches(SVGNames::textLengthAttr) ||
            SVGTests::isKnownAttribute(attrName) ||
            SVGLangSpace::isKnownAttribute(attrName) ||
            SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
            SVGStyledElement::isKnownAttribute(attrName));
}

}

#endif // ENABLE(SVG)
