/*
 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 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.
 */

#include "config.h"
#include "TextAutoSizing.h"

#if ENABLE(TEXT_AUTOSIZING)

#include "CSSFontSelector.h"
#include "Document.h"
#include "FontCascade.h"
#include "Logging.h"
#include "RenderBlock.h"
#include "RenderListMarker.h"
#include "RenderText.h"
#include "RenderTextFragment.h"
#include "RenderTreeBuilder.h"
#include "Settings.h"
#include "StyleResolver.h"

namespace WebCore {

static RenderStyle cloneRenderStyleWithState(const RenderStyle& currentStyle)
{
    auto newStyle = RenderStyle::clone(currentStyle);
    if (currentStyle.lastChildState())
        newStyle.setLastChildState();
    if (currentStyle.firstChildState())
        newStyle.setFirstChildState();
    return newStyle;
}

TextAutoSizingKey::TextAutoSizingKey(DeletedTag)
{
    HashTraits<std::unique_ptr<RenderStyle>>::constructDeletedValue(m_style);
}

TextAutoSizingKey::TextAutoSizingKey(const RenderStyle& style, unsigned hash)
    : m_style(RenderStyle::clonePtr(style)) // FIXME: This seems very inefficient.
    , m_hash(hash)
{
}

void TextAutoSizingValue::addTextNode(Text& node, float size)
{
    node.renderer()->setCandidateComputedTextSize(size);
    m_autoSizedNodes.add(&node);
}

auto TextAutoSizingValue::adjustTextNodeSizes() -> StillHasNodes
{
    // Remove stale nodes. Nodes may have had their renderers detached. We'll also need to remove the style from the documents m_textAutoSizedNodes
    // collection. Return true indicates we need to do that removal.
    Vector<Text*> nodesForRemoval;
    for (auto& textNode : m_autoSizedNodes) {
        auto* renderer = textNode->renderer();
        if (!renderer || !renderer->style().textSizeAdjust().isAuto() || !renderer->candidateComputedTextSize())
            nodesForRemoval.append(textNode.get());
    }

    for (auto& node : nodesForRemoval)
        m_autoSizedNodes.remove(node);

    StillHasNodes stillHasNodes = m_autoSizedNodes.isEmpty() ? StillHasNodes::No : StillHasNodes::Yes;

    // If we only have one piece of text with the style on the page don't adjust it's size.
    if (m_autoSizedNodes.size() <= 1)
        return stillHasNodes;

    // Compute average size.
    float cumulativeSize = 0;
    for (auto& node : m_autoSizedNodes)
        cumulativeSize += node->renderer()->candidateComputedTextSize();

    float averageSize = std::round(cumulativeSize / m_autoSizedNodes.size());

    // FIXME: Figure out how to make this code use RenderTreeUpdater/Builder properly.
    RenderTreeBuilder builder((*m_autoSizedNodes.begin())->renderer()->view());

    // Adjust sizes.
    bool firstPass = true;
    for (auto& node : m_autoSizedNodes) {
        auto& renderer = *node->renderer();
        if (renderer.style().fontDescription().computedSize() == averageSize)
            continue;

        float specifiedSize = renderer.style().fontDescription().specifiedSize();
        float maxScaleIncrease = renderer.settings().maxTextAutosizingScaleIncrease();
        float scaleChange = averageSize / specifiedSize;
        if (scaleChange > maxScaleIncrease && firstPass) {
            firstPass = false;
            averageSize = std::round(specifiedSize * maxScaleIncrease);
            scaleChange = averageSize / specifiedSize;
        }

        LOG(TextAutosizing, "  adjust node size %p firstPass=%d averageSize=%f scaleChange=%f", node.get(), firstPass, averageSize, scaleChange);

        auto* parentRenderer = renderer.parent();

        auto style = cloneRenderStyleWithState(renderer.style());
        auto fontDescription = style.fontDescription();
        fontDescription.setComputedSize(averageSize);
        style.setFontDescription(FontCascadeDescription { fontDescription });
        style.fontCascade().update(&node->document().fontSelector());
        parentRenderer->setStyle(WTFMove(style));

        if (parentRenderer->isAnonymousBlock())
            parentRenderer = parentRenderer->parent();

        // If we have a list we should resize ListMarkers separately.
        if (is<RenderListMarker>(*parentRenderer->firstChild())) {
            auto& listMarkerRenderer = downcast<RenderListMarker>(*parentRenderer->firstChild());
            auto style = cloneRenderStyleWithState(listMarkerRenderer.style());
            style.setFontDescription(FontCascadeDescription { fontDescription });
            style.fontCascade().update(&node->document().fontSelector());
            listMarkerRenderer.setStyle(WTFMove(style));
        }

        // Resize the line height of the parent.
        auto& parentStyle = parentRenderer->style();
        auto& lineHeightLength = parentStyle.specifiedLineHeight();

        int specifiedLineHeight;
        if (lineHeightLength.isPercent())
            specifiedLineHeight = minimumValueForLength(lineHeightLength, fontDescription.specifiedSize());
        else
            specifiedLineHeight = lineHeightLength.value();

        // This calculation matches the line-height computed size calculation in StyleBuilderCustom::applyValueLineHeight().
        int lineHeight = specifiedLineHeight * scaleChange;
        if (lineHeightLength.isFixed() && lineHeightLength.value() == lineHeight)
            continue;

        auto newParentStyle = cloneRenderStyleWithState(parentStyle);
        newParentStyle.setLineHeight(lineHeightLength.isNegative() ? Length(lineHeightLength) : Length(lineHeight, LengthType::Fixed));
        newParentStyle.setSpecifiedLineHeight(Length { lineHeightLength });
        newParentStyle.setFontDescription(WTFMove(fontDescription));
        newParentStyle.fontCascade().update(&node->document().fontSelector());
        parentRenderer->setStyle(WTFMove(newParentStyle));

        builder.updateAfterDescendants(*parentRenderer);
    }

    for (auto& node : m_autoSizedNodes) {
        auto& textRenderer = *node->renderer();
        if (!is<RenderTextFragment>(textRenderer))
            continue;
        auto* block = downcast<RenderTextFragment>(textRenderer).blockForAccompanyingFirstLetter();
        if (!block)
            continue;
        builder.updateAfterDescendants(*block);
    }

    return stillHasNodes;
}

TextAutoSizingValue::~TextAutoSizingValue()
{
    reset();
}

void TextAutoSizingValue::reset()
{
    for (auto& node : m_autoSizedNodes) {
        auto* renderer = node->renderer();
        if (!renderer)
            continue;

        auto* parentRenderer = renderer->parent();
        if (!parentRenderer)
            continue;

        // Reset the font size back to the original specified size
        auto fontDescription = renderer->style().fontDescription();
        float originalSize = fontDescription.specifiedSize();
        if (fontDescription.computedSize() != originalSize) {
            fontDescription.setComputedSize(originalSize);
            auto style = cloneRenderStyleWithState(renderer->style());
            style.setFontDescription(FontCascadeDescription { fontDescription });
            style.fontCascade().update(&node->document().fontSelector());
            parentRenderer->setStyle(WTFMove(style));
        }

        // Reset the line height of the parent.
        if (parentRenderer->isAnonymousBlock())
            parentRenderer = parentRenderer->parent();

        auto& parentStyle = parentRenderer->style();
        auto& originalLineHeight = parentStyle.specifiedLineHeight();
        if (originalLineHeight == parentStyle.lineHeight())
            continue;

        auto newParentStyle = cloneRenderStyleWithState(parentStyle);
        newParentStyle.setLineHeight(Length { originalLineHeight });
        newParentStyle.setFontDescription(WTFMove(fontDescription));
        newParentStyle.fontCascade().update(&node->document().fontSelector());
        parentRenderer->setStyle(WTFMove(newParentStyle));
    }
}

void TextAutoSizing::addTextNode(Text& node, float candidateSize)
{
    LOG(TextAutosizing, " addAutoSizedNode %p candidateSize=%f", &node, candidateSize);
    auto addResult = m_textNodes.add<TextAutoSizingHashTranslator>(node.renderer()->style(), nullptr);
    if (addResult.isNewEntry)
        addResult.iterator->value = makeUnique<TextAutoSizingValue>();
    addResult.iterator->value->addTextNode(node, candidateSize);
}

void TextAutoSizing::updateRenderTree()
{
    m_textNodes.removeIf([](auto& keyAndValue) {
        return keyAndValue.value->adjustTextNodeSizes() == TextAutoSizingValue::StillHasNodes::No;
    });
}

void TextAutoSizing::reset()
{
    m_textNodes.clear();
}

} // namespace WebCore

#endif // ENABLE(TEXT_AUTOSIZING)
