/*
 * Copyright (C) 2011 Apple Inc.  All rights reserved.
 * Copyright (C) 2013 Adobe Systems Incorporated. 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. ``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
 * 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 "CSSCrossfadeValue.h"

#include "AnimationUtilities.h"
#include "CSSImageValue.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
#include "CrossfadeGeneratedImage.h"
#include "RenderElement.h"
#include "StyleCachedImage.h"
#include <wtf/text/StringBuilder.h>

namespace WebCore {

static inline double blendFunc(double from, double to, double progress)
{
    return blend(from, to, progress);
}

static bool subimageKnownToBeOpaque(const CSSValue& value, const RenderElement& renderer)
{
    if (is<CSSImageValue>(value))
        return downcast<CSSImageValue>(value).knownToBeOpaque(renderer);

    if (is<CSSImageGeneratorValue>(value))
        return downcast<CSSImageGeneratorValue>(value).knownToBeOpaque(renderer);

    ASSERT_NOT_REACHED();

    return false;
}

inline CSSCrossfadeValue::SubimageObserver::SubimageObserver(CSSCrossfadeValue& owner)
    : m_owner(owner)
{
}

void CSSCrossfadeValue::SubimageObserver::imageChanged(CachedImage*, const IntRect*)
{
    m_owner.crossfadeChanged();
}

inline CSSCrossfadeValue::CSSCrossfadeValue(Ref<CSSValue>&& fromValue, Ref<CSSValue>&& toValue, Ref<CSSPrimitiveValue>&& percentageValue, bool prefixed)
    : CSSImageGeneratorValue(CrossfadeClass)
    , m_fromValue(WTFMove(fromValue))
    , m_toValue(WTFMove(toValue))
    , m_percentageValue(WTFMove(percentageValue))
    , m_subimageObserver(*this)
    , m_isPrefixed(prefixed)
{
}

Ref<CSSCrossfadeValue> CSSCrossfadeValue::create(Ref<CSSValue>&& fromValue, Ref<CSSValue>&& toValue, Ref<CSSPrimitiveValue>&& percentageValue, bool prefixed)
{
    return adoptRef(*new CSSCrossfadeValue(WTFMove(fromValue), WTFMove(toValue), WTFMove(percentageValue), prefixed));
}

CSSCrossfadeValue::~CSSCrossfadeValue()
{
    if (m_cachedFromImage)
        m_cachedFromImage->removeClient(m_subimageObserver);
    if (m_cachedToImage)
        m_cachedToImage->removeClient(m_subimageObserver);
}

String CSSCrossfadeValue::customCSSText() const
{
    StringBuilder result;
    if (m_isPrefixed)
        result.appendLiteral("-webkit-cross-fade(");
    else
        result.appendLiteral("cross-fade(");
    result.append(m_fromValue->cssText());
    result.appendLiteral(", ");
    result.append(m_toValue->cssText());
    result.appendLiteral(", ");
    result.append(m_percentageValue->cssText());
    result.append(')');
    return result.toString();
}

FloatSize CSSCrossfadeValue::fixedSize(const RenderElement& renderer)
{
    float percentage = m_percentageValue->floatValue();
    float inversePercentage = 1 - percentage;

    // FIXME: Skip Content Security Policy check when cross fade is applied to an element in a user agent shadow tree.
    // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
    auto options = CachedResourceLoader::defaultCachedResourceOptions();

    auto& cachedResourceLoader = renderer.document().cachedResourceLoader();
    auto* cachedFromImage = cachedImageForCSSValue(m_fromValue, cachedResourceLoader, options);
    auto* cachedToImage = cachedImageForCSSValue(m_toValue, cachedResourceLoader, options);

    if (!cachedFromImage || !cachedToImage)
        return FloatSize();

    FloatSize fromImageSize = cachedFromImage->imageForRenderer(&renderer)->size();
    FloatSize toImageSize = cachedToImage->imageForRenderer(&renderer)->size();

    // Rounding issues can cause transitions between images of equal size to return
    // a different fixed size; avoid performing the interpolation if the images are the same size.
    if (fromImageSize == toImageSize)
        return fromImageSize;

    return fromImageSize * inversePercentage + toImageSize * percentage;
}

bool CSSCrossfadeValue::isPending() const
{
    return CSSImageGeneratorValue::subimageIsPending(m_fromValue)
        || CSSImageGeneratorValue::subimageIsPending(m_toValue);
}

bool CSSCrossfadeValue::knownToBeOpaque(const RenderElement& renderer) const
{
    return subimageKnownToBeOpaque(m_fromValue, renderer)
        && subimageKnownToBeOpaque(m_toValue, renderer);
}

void CSSCrossfadeValue::loadSubimages(CachedResourceLoader& cachedResourceLoader, const ResourceLoaderOptions& options)
{
    auto oldCachedFromImage = m_cachedFromImage;
    auto oldCachedToImage = m_cachedToImage;

    m_cachedFromImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_fromValue, cachedResourceLoader, options);
    m_cachedToImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_toValue, cachedResourceLoader, options);

    if (m_cachedFromImage != oldCachedFromImage) {
        if (oldCachedFromImage)
            oldCachedFromImage->removeClient(m_subimageObserver);
        if (m_cachedFromImage)
            m_cachedFromImage->addClient(m_subimageObserver);
    }

    if (m_cachedToImage != oldCachedToImage) {
        if (oldCachedToImage)
            oldCachedToImage->removeClient(m_subimageObserver);
        if (m_cachedToImage)
            m_cachedToImage->addClient(m_subimageObserver);
    }

    // FIXME: Unclear why this boolean adds any value; for now keeping it around to avoid changing semantics.
    m_subimagesAreReady = true;
}

Image* CSSCrossfadeValue::image(RenderElement& renderer, const FloatSize& size)
{
    if (size.isEmpty())
        return nullptr;

    // FIXME: Skip Content Security Policy check when cross fade is applied to an element in a user agent shadow tree.
    // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
    auto options = CachedResourceLoader::defaultCachedResourceOptions();

    auto& cachedResourceLoader = renderer.document().cachedResourceLoader();
    auto* cachedFromImage = cachedImageForCSSValue(m_fromValue, cachedResourceLoader, options);
    auto* cachedToImage = cachedImageForCSSValue(m_toValue, cachedResourceLoader, options);

    if (!cachedFromImage || !cachedToImage)
        return &Image::nullImage();

    auto* fromImage = cachedFromImage->imageForRenderer(&renderer);
    auto* toImage = cachedToImage->imageForRenderer(&renderer);

    if (!fromImage || !toImage)
        return &Image::nullImage();

    m_generatedImage = CrossfadeGeneratedImage::create(*fromImage, *toImage, m_percentageValue->floatValue(), fixedSize(renderer), size);
    return m_generatedImage.get();
}

inline void CSSCrossfadeValue::crossfadeChanged()
{
    if (!m_subimagesAreReady)
        return;
    for (auto& client : clients())
        client.key->imageChanged(this);
}

bool CSSCrossfadeValue::traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const
{
    if (m_cachedFromImage && handler(*m_cachedFromImage))
        return true;
    if (m_cachedToImage && handler(*m_cachedToImage))
        return true;
    return false;
}

RefPtr<CSSCrossfadeValue> CSSCrossfadeValue::blend(const CSSCrossfadeValue& from, double progress) const
{
    ASSERT(equalInputImages(from));

    if (!m_cachedToImage || !m_cachedFromImage)
        return nullptr;

    auto fromImageValue = CSSImageValue::create(*m_cachedFromImage);
    auto toImageValue = CSSImageValue::create(*m_cachedToImage);

    double fromPercentage = from.m_percentageValue->doubleValue();
    if (from.m_percentageValue->isPercentage())
        fromPercentage /= 100.0;
    double toPercentage = m_percentageValue->doubleValue();
    if (m_percentageValue->isPercentage())
        toPercentage /= 100.0;
    auto percentageValue = CSSPrimitiveValue::create(blendFunc(fromPercentage, toPercentage, progress), CSSPrimitiveValue::CSS_NUMBER);

    return CSSCrossfadeValue::create(WTFMove(fromImageValue), WTFMove(toImageValue), WTFMove(percentageValue), from.isPrefixed() && isPrefixed());
}

bool CSSCrossfadeValue::equals(const CSSCrossfadeValue& other) const
{
    return equalInputImages(other) && compareCSSValue(m_percentageValue, other.m_percentageValue);
}


bool CSSCrossfadeValue::equalInputImages(const CSSCrossfadeValue& other) const
{
    return compareCSSValue(m_fromValue, other.m_fromValue) && compareCSSValue(m_toValue, other.m_toValue);
}

} // namespace WebCore
