/*
 * Copyright (C) 2013 Google 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 "core/css/FontLoader.h"

#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/Dictionary.h"
#include "core/css/CSSFontFaceLoadEvent.h"
#include "core/css/CSSFontFaceSource.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSParser.h"
#include "core/css/CSSSegmentedFontFace.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/DOMException.h"
#include "core/dom/Document.h"
#include "core/page/FrameView.h"
#include "core/platform/HistogramSupport.h"

namespace WebCore {

static const int defaultFontSize = 10;
static const char* const defaultFontFamily = "sans-serif";

class LoadFontCallback : public CSSSegmentedFontFace::LoadFontCallback {
public:
    static PassRefPtr<LoadFontCallback> create(int numLoading, PassRefPtr<VoidCallback> loadCallback, PassRefPtr<VoidCallback> errorCallback)
    {
        return adoptRef<LoadFontCallback>(new LoadFontCallback(numLoading, loadCallback, errorCallback));
    }

    static PassRefPtr<LoadFontCallback> createFromParams(const Dictionary& params, const FontFamily& family)
    {
        RefPtr<VoidCallback> onsuccess;
        RefPtr<VoidCallback> onerror;
        params.get("onsuccess", onsuccess);
        params.get("onerror", onerror);
        if (!onsuccess && !onerror)
            return 0;
        int numFamilies = 0;
        for (const FontFamily* f = &family; f; f = f->next())
            numFamilies++;
        return LoadFontCallback::create(numFamilies, onsuccess, onerror);
    }

    virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE;
    virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE;
    void loaded(Document*);
    void error(Document*);
private:
    LoadFontCallback(int numLoading, PassRefPtr<VoidCallback> loadCallback, PassRefPtr<VoidCallback> errorCallback)
        : m_numLoading(numLoading)
        , m_errorOccured(false)
        , m_loadCallback(loadCallback)
        , m_errorCallback(errorCallback)
    { }

    int m_numLoading;
    bool m_errorOccured;
    RefPtr<VoidCallback> m_loadCallback;
    RefPtr<VoidCallback> m_errorCallback;
};

void LoadFontCallback::loaded(Document* document)
{
    m_numLoading--;
    if (m_numLoading || !document)
        return;

    if (m_errorOccured) {
        if (m_errorCallback)
            document->fontloader()->scheduleCallback(m_errorCallback.release());
    } else {
        if (m_loadCallback)
            document->fontloader()->scheduleCallback(m_loadCallback.release());
    }
}

void LoadFontCallback::error(Document* document)
{
    m_errorOccured = true;
    loaded(document);
}

void LoadFontCallback::notifyLoaded(CSSSegmentedFontFace* face)
{
    loaded(face->fontSelector()->document());
}

void LoadFontCallback::notifyError(CSSSegmentedFontFace* face)
{
    error(face->fontSelector()->document());
}

FontLoader::FontLoader(Document* document)
    : ActiveDOMObject(document)
    , m_document(document)
    , m_loadingCount(0)
    , m_timer(this, &FontLoader::timerFired)
{
    suspendIfNeeded();
}

FontLoader::~FontLoader()
{
}

EventTargetData* FontLoader::eventTargetData()
{
    return &m_eventTargetData;
}

EventTargetData* FontLoader::ensureEventTargetData()
{
    return &m_eventTargetData;
}

const AtomicString& FontLoader::interfaceName() const
{
    return eventNames().interfaceForFontLoader;
}

ScriptExecutionContext* FontLoader::scriptExecutionContext() const
{
    return ActiveDOMObject::scriptExecutionContext();
}

void FontLoader::didLayout()
{
    if (m_document->page() && m_document->page()->mainFrame() == m_document->frame())
        m_histogram.record();
    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
        return;
    if (m_loadingCount || (!m_pendingDoneEvent && m_fontsReadyCallbacks.isEmpty()))
        return;
    if (!m_timer.isActive())
        m_timer.startOneShot(0);
}

void FontLoader::timerFired(Timer<FontLoader>*)
{
    firePendingEvents();
    firePendingCallbacks();
    fireDoneEventIfPossible();
}

void FontLoader::scheduleEvent(PassRefPtr<Event> event)
{
    m_pendingEvents.append(event);
    if (!m_timer.isActive())
        m_timer.startOneShot(0);
}

void FontLoader::firePendingEvents()
{
    if (m_pendingEvents.isEmpty())
        return;

    Vector<RefPtr<Event> > pendingEvents;
    m_pendingEvents.swap(pendingEvents);
    for (size_t index = 0; index < pendingEvents.size(); ++index)
        dispatchEvent(pendingEvents[index].release());
}

void FontLoader::scheduleCallback(PassRefPtr<VoidCallback> callback)
{
    m_pendingCallbacks.append(callback);
    if (!m_timer.isActive())
        m_timer.startOneShot(0);
}

void FontLoader::firePendingCallbacks()
{
    if (m_pendingCallbacks.isEmpty())
        return;

    Vector<RefPtr<VoidCallback> > pendingCallbacks;
    m_pendingCallbacks.swap(pendingCallbacks);
    for (size_t index = 0; index < pendingCallbacks.size(); ++index)
        pendingCallbacks[index]->handleEvent();
}

void FontLoader::beginFontLoading(CSSFontFaceRule* rule)
{
    m_histogram.incrementCount();
    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
        return;

    ++m_loadingCount;
    if (m_loadingCount == 1 && !m_pendingDoneEvent)
        scheduleEvent(CSSFontFaceLoadEvent::createForFontFaceRule(eventNames().loadingEvent, rule));
    scheduleEvent(CSSFontFaceLoadEvent::createForFontFaceRule(eventNames().loadstartEvent, rule));
    m_pendingDoneEvent.clear();
}

void FontLoader::fontLoaded(CSSFontFaceRule* rule)
{
    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
        return;
    scheduleEvent(CSSFontFaceLoadEvent::createForFontFaceRule(eventNames().loadEvent, rule));
    queueDoneEvent(rule);
}

void FontLoader::loadError(CSSFontFaceRule* rule, CSSFontFaceSource* source)
{
    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
        return;
    // FIXME: We should report NetworkError in case of timeout, etc.
    String errorName = (source && source->isDecodeError()) ? "InvalidFontDataError" : DOMException::getErrorName(NotFoundError);
    scheduleEvent(CSSFontFaceLoadEvent::createForError(rule, DOMError::create(errorName)));
    queueDoneEvent(rule);
}

void FontLoader::queueDoneEvent(CSSFontFaceRule* rule)
{
    ASSERT(m_loadingCount > 0);
    --m_loadingCount;
    if (!m_loadingCount) {
        ASSERT(!m_pendingDoneEvent);
        m_pendingDoneEvent = CSSFontFaceLoadEvent::createForFontFaceRule(eventNames().loadingdoneEvent, rule);
    }
}

void FontLoader::notifyWhenFontsReady(PassRefPtr<VoidCallback> callback)
{
    m_fontsReadyCallbacks.append(callback);
    if (!m_timer.isActive())
        m_timer.startOneShot(0);
}

void FontLoader::fireDoneEventIfPossible()
{
    if (!m_pendingEvents.isEmpty() || !m_pendingCallbacks.isEmpty())
        return;
    if (m_loadingCount || (!m_pendingDoneEvent && m_fontsReadyCallbacks.isEmpty()))
        return;

    // If the layout was invalidated in between when we thought layout
    // was updated and when we're ready to fire the event, just wait
    // until after the next layout before firing events.
    if (!m_document->view() || m_document->view()->needsLayout())
        return;

    if (m_pendingDoneEvent)
        dispatchEvent(m_pendingDoneEvent.release());

    if (!m_fontsReadyCallbacks.isEmpty()) {
        Vector<RefPtr<VoidCallback> > callbacks;
        m_fontsReadyCallbacks.swap(callbacks);
        for (size_t index = 0; index < callbacks.size(); ++index)
            callbacks[index]->handleEvent();
    }
}

void FontLoader::loadFont(const Dictionary& params)
{
    // FIXME: The text member of params is ignored.
    String fontString;
    if (!params.get("font", fontString))
        return;
    Font font;
    if (!resolveFontStyle(fontString, font))
        return;
    RefPtr<LoadFontCallback> callback = LoadFontCallback::createFromParams(params, font.family());

    for (const FontFamily* f = &font.family(); f; f = f->next()) {
        CSSSegmentedFontFace* face = m_document->styleResolver()->fontSelector()->getFontFace(font.fontDescription(), f->family());
        if (!face) {
            if (callback)
                callback->error(m_document);
            continue;
        }
        face->loadFont(font.fontDescription(), callback);
    }
}

bool FontLoader::checkFont(const String& fontString, const String&)
{
    // FIXME: The second parameter (text) is ignored.
    Font font;
    if (!resolveFontStyle(fontString, font))
        return false;
    for (const FontFamily* f = &font.family(); f; f = f->next()) {
        CSSSegmentedFontFace* face = m_document->styleResolver()->fontSelector()->getFontFace(font.fontDescription(), f->family());
        if (!face || !face->checkFont())
            return false;
    }
    return true;
}

bool FontLoader::resolveFontStyle(const String& fontString, Font& font)
{
    // Interpret fontString in the same way as the 'font' attribute of CanvasRenderingContext2D.
    RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
    CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0);
    if (parsedStyle->isEmpty())
        return false;

    String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
    if (fontValue == "inherit" || fontValue == "initial")
        return false;

    RefPtr<RenderStyle> style = RenderStyle::create();

    FontFamily fontFamily;
    fontFamily.setFamily(defaultFontFamily);

    FontDescription defaultFontDescription;
    defaultFontDescription.setFamily(fontFamily);
    defaultFontDescription.setSpecifiedSize(defaultFontSize);
    defaultFontDescription.setComputedSize(defaultFontSize);

    style->setFontDescription(defaultFontDescription);

    style->font().update(style->font().fontSelector());

    // Now map the font property longhands into the style.
    CSSPropertyValue properties[] = {
        CSSPropertyValue(CSSPropertyFontFamily, *parsedStyle),
        CSSPropertyValue(CSSPropertyFontStyle, *parsedStyle),
        CSSPropertyValue(CSSPropertyFontVariant, *parsedStyle),
        CSSPropertyValue(CSSPropertyFontWeight, *parsedStyle),
        CSSPropertyValue(CSSPropertyFontSize, *parsedStyle),
        CSSPropertyValue(CSSPropertyLineHeight, *parsedStyle),
    };
    StyleResolver* styleResolver = m_document->styleResolver();
    styleResolver->applyPropertiesToStyle(properties, WTF_ARRAY_LENGTH(properties), style.get());

    font = style->font();
    font.update(styleResolver->fontSelector());
    return true;
}

void FontLoader::FontLoadHistogram::record()
{
    if (m_recorded)
        return;
    m_recorded = true;
    HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1, 100, 50);
}

} // namespace WebCore
