/*
 * Copyright (C) 2006, 2007, 2008, 2009 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 COMPUTER, 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 COMPUTER, 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 "WebKitDLL.h"
#include "WebIconDatabase.h"

#include "CFDictionaryPropertyBag.h"
#include "COMPtr.h"
#include "WebPreferences.h"
#include "WebNotificationCenter.h"
#pragma warning(push, 0)
#include <WebCore/BitmapInfo.h>
#include <WebCore/BString.h>
#include <WebCore/FileSystem.h>
#include <WebCore/IconDatabase.h>
#include <WebCore/Image.h>
#include <WebCore/PlatformString.h>
#pragma warning(pop)
#include <wtf/MainThread.h>
#include "shlobj.h"

using namespace WebCore;
using namespace WTF;

// WebIconDatabase ----------------------------------------------------------------

WebIconDatabase* WebIconDatabase::m_sharedWebIconDatabase = 0;

WebIconDatabase::WebIconDatabase()
: m_refCount(0)
, m_deliveryRequested(false)
{
    gClassCount++;
    gClassNameCount.add("WebIconDatabase");
}

WebIconDatabase::~WebIconDatabase()
{
    gClassCount--;
    gClassNameCount.remove("WebIconDatabase");
}

void WebIconDatabase::init()
{
    WebPreferences* standardPrefs = WebPreferences::sharedStandardPreferences();
    BOOL enabled = FALSE;
    if (FAILED(standardPrefs->iconDatabaseEnabled(&enabled))) {
        enabled = FALSE;
        LOG_ERROR("Unable to get icon database enabled preference");
    }
    iconDatabase()->setEnabled(!!enabled);
    if (!(!!enabled))
        return;

    startUpIconDatabase();
}

void WebIconDatabase::startUpIconDatabase()
{
    WebPreferences* standardPrefs = WebPreferences::sharedStandardPreferences();

    iconDatabase()->setClient(this);

    BSTR prefDatabasePath = 0;
    if (FAILED(standardPrefs->iconDatabaseLocation(&prefDatabasePath)))
        LOG_ERROR("Unable to get icon database location preference");

    String databasePath(prefDatabasePath, SysStringLen(prefDatabasePath));
    SysFreeString(prefDatabasePath);

    if (databasePath.isEmpty()) {
        databasePath = localUserSpecificStorageDirectory();
        if (databasePath.isEmpty())
            LOG_ERROR("Failed to construct default icon database path");
    }

    if (!iconDatabase()->open(databasePath))
            LOG_ERROR("Failed to open icon database path");
}

void WebIconDatabase::shutDownIconDatabase()
{
}

WebIconDatabase* WebIconDatabase::createInstance()
{
    WebIconDatabase* instance = new WebIconDatabase();
    instance->AddRef();
    return instance;
}

WebIconDatabase* WebIconDatabase::sharedWebIconDatabase()
{
    if (m_sharedWebIconDatabase) {
        m_sharedWebIconDatabase->AddRef();
        return m_sharedWebIconDatabase;
    }
    m_sharedWebIconDatabase = createInstance();
    m_sharedWebIconDatabase->init();
    return m_sharedWebIconDatabase;
}

// IUnknown -------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebIconDatabase::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebIconDatabase*>(this);
    else if (IsEqualGUID(riid, IID_IWebIconDatabase))
        *ppvObject = static_cast<IWebIconDatabase*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE WebIconDatabase::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE WebIconDatabase::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete(this);

    return newRef;
}

// IWebIconDatabase --------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebIconDatabase::sharedIconDatabase(
        /* [retval][out] */ IWebIconDatabase** result)
{
    *result = sharedWebIconDatabase();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::iconForURL(
        /* [in] */ BSTR url,
        /* [optional][in] */ LPSIZE size,
        /* [optional][in] */ BOOL /*cache*/,
        /* [retval][out] */ OLE_HANDLE* bitmap)
{
    IntSize intSize(*size);

    Image* icon = 0;
    if (url)
        icon = iconDatabase()->iconForPageURL(String(url, SysStringLen(url)), intSize);

    // Make sure we check for the case of an "empty image"
    if (icon && icon->width()) {
        *bitmap = (OLE_HANDLE)(ULONG64)getOrCreateSharedBitmap(size);
        if (!icon->getHBITMAPOfSize((HBITMAP)(ULONG64)*bitmap, size)) {
            LOG_ERROR("Failed to draw Image to HBITMAP");
            *bitmap = 0;
            return E_FAIL;
        }
        return S_OK;
    }

    return defaultIconWithSize(size, bitmap);
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::defaultIconWithSize(
        /* [in] */ LPSIZE size,
        /* [retval][out] */ OLE_HANDLE* result)
{
    *result = (OLE_HANDLE)(ULONG64)getOrCreateDefaultIconBitmap(size);
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::retainIconForURL(
        /* [in] */ BSTR url)
{
    iconDatabase()->retainIconForPageURL(String(url, SysStringLen(url)));
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::releaseIconForURL(
        /* [in] */ BSTR url)
{
    iconDatabase()->releaseIconForPageURL(String(url, SysStringLen(url)));
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::removeAllIcons(void)
{
    iconDatabase()->removeAllIcons();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::delayDatabaseCleanup(void)
{
    IconDatabase::delayDatabaseCleanup();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::allowDatabaseCleanup(void)
{
    IconDatabase::allowDatabaseCleanup();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::iconURLForURL( 
        /* [in] */ BSTR url,
        /* [retval][out] */ BSTR* iconURL)
{
    if (!url || !iconURL)
        return E_POINTER;
    BString iconURLBSTR(iconDatabase()->iconURLForPageURL(String(url, SysStringLen(url))));
    *iconURL = iconURLBSTR.release();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::isEnabled( 
        /* [retval][out] */ BOOL *result)
{
    *result = iconDatabase()->isEnabled();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebIconDatabase::setEnabled( 
        /* [in] */ BOOL flag)
{
    BOOL currentlyEnabled;
    isEnabled(&currentlyEnabled);
    if (currentlyEnabled && !flag) {
        iconDatabase()->setEnabled(false);
        shutDownIconDatabase();
    } else if (!currentlyEnabled && flag) {
        iconDatabase()->setEnabled(true);
        startUpIconDatabase();
    }
    return S_OK;
}

HBITMAP createDIB(LPSIZE size)
{
    BitmapInfo bmInfo = BitmapInfo::create(IntSize(*size));

    HDC dc = GetDC(0);
    HBITMAP result = CreateDIBSection(dc, &bmInfo, DIB_RGB_COLORS, 0, 0, 0);
    ReleaseDC(0, dc);

    return result;
}

HBITMAP WebIconDatabase::getOrCreateSharedBitmap(LPSIZE size)
{
    HBITMAP result = m_sharedIconMap.get(*size);
    if (result)
        return result;
    result = createDIB(size);
    m_sharedIconMap.set(*size, result);
    return result;
}

HBITMAP WebIconDatabase::getOrCreateDefaultIconBitmap(LPSIZE size)
{
    HBITMAP result = m_defaultIconMap.get(*size);
    if (result)
        return result;

    result = createDIB(size);

    m_defaultIconMap.set(*size, result);
    if (!iconDatabase()->defaultIcon(*size)->getHBITMAPOfSize(result, size)) {
        LOG_ERROR("Failed to draw Image to HBITMAP");
        return 0;
    }
    return result;
}

// IconDatabaseClient

void WebIconDatabase::dispatchDidRemoveAllIcons()
{
    // Queueing the empty string is a special way of saying "this queued notification is the didRemoveAllIcons notification"
    MutexLocker locker(m_notificationMutex);
    m_notificationQueue.append(String());
    scheduleNotificationDelivery();
}

void WebIconDatabase::dispatchDidAddIconForPageURL(const String& pageURL)
{   
    MutexLocker locker(m_notificationMutex);
    m_notificationQueue.append(pageURL.copy());
    scheduleNotificationDelivery();
}

void WebIconDatabase::scheduleNotificationDelivery()
{
    // Caller of this method must hold the m_notificationQueue lock
    ASSERT(!m_notificationMutex.tryLock());

    if (!m_deliveryRequested) {
        m_deliveryRequested = true;
        callOnMainThread(deliverNotifications, 0);
    }
}

BSTR WebIconDatabase::iconDatabaseDidAddIconNotification()
{
    static BSTR didAddIconName = SysAllocString(WebIconDatabaseDidAddIconNotification);
    return didAddIconName;
}

CFStringRef WebIconDatabase::iconDatabaseNotificationUserInfoURLKey()
{
    static CFStringRef iconUserInfoURLKey = String(WebIconNotificationUserInfoURLKey).createCFString();
    return iconUserInfoURLKey;
}

BSTR WebIconDatabase::iconDatabaseDidRemoveAllIconsNotification()
{
    static BSTR didRemoveAllIconsName = SysAllocString(WebIconDatabaseDidRemoveAllIconsNotification);
    return didRemoveAllIconsName;
}

static void postDidRemoveAllIconsNotification(WebIconDatabase* iconDB)
{
    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    notifyCenter->postNotificationName(WebIconDatabase::iconDatabaseDidRemoveAllIconsNotification(), static_cast<IWebIconDatabase*>(iconDB), 0);
}

static void postDidAddIconNotification(const String& pageURL, WebIconDatabase* iconDB)
{
    RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF, 
    CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));

    RetainPtr<CFStringRef> url(AdoptCF, pageURL.createCFString());
    CFDictionaryAddValue(dictionary.get(), WebIconDatabase::iconDatabaseNotificationUserInfoURLKey(), url.get());

    COMPtr<CFDictionaryPropertyBag> userInfo(AdoptCOM, CFDictionaryPropertyBag::createInstance());
    userInfo->setDictionary(dictionary.get());

    IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    notifyCenter->postNotificationName(WebIconDatabase::iconDatabaseDidAddIconNotification(), static_cast<IWebIconDatabase*>(iconDB), userInfo.get());
}

void WebIconDatabase::deliverNotifications(void*)
{
    ASSERT(m_sharedWebIconDatabase);
    if (!m_sharedWebIconDatabase)
        return;

    ASSERT(m_sharedWebIconDatabase->m_deliveryRequested);

    Vector<String> queue;
    {
        MutexLocker locker(m_sharedWebIconDatabase->m_notificationMutex);
        queue.swap(m_sharedWebIconDatabase->m_notificationQueue);
        m_sharedWebIconDatabase->m_deliveryRequested = false;
    }

    for (unsigned i = 0; i < queue.size(); ++i) {
        if (queue[i].isNull())
            postDidRemoveAllIconsNotification(m_sharedWebIconDatabase);
        else
            postDidAddIconNotification(queue[i], m_sharedWebIconDatabase);
    }
}
