/*
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2007 Holger Hans Peter Freyther
 *
 * 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "Icon.h"

#include "GraphicsContext.h"
#include "MIMETypeRegistry.h"
#include "PlatformContextCairo.h"

#include <gtk/gtk.h>

#include <wtf/RefPtr.h>
#include <wtf/text/CString.h>

namespace WebCore {

Icon::Icon()
    : m_icon(0)
{
}

Icon::~Icon()
{
    if (m_icon)
        g_object_unref(m_icon);
}

static String lookupIconName(String MIMEType)
{
    /*
     Lookup an appropriate icon according to either the Icon Naming Spec
     or conventional Gnome icon names respectively.

     See http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html

     The icon theme is probed for the following names:
     1. media-subtype
     2. gnome-mime-media-subtype
     3. media-x-generic
     4. gnome-mime-media

     In the worst case it falls back to the stock file icon.
    */
    int pos = MIMEType.find('/');
    if(pos >= 0) {
        String media = MIMEType.substring(0, pos);
        String subtype = MIMEType.substring(pos + 1);
        GtkIconTheme* iconTheme = gtk_icon_theme_get_default();
        String iconName = media + "-" + subtype;
        if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data()))
            return iconName;
        iconName = "gnome-mime-" + media + "-" + subtype;
        if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data()))
            return iconName;
        iconName = media + "-x-generic";
        if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data()))
            return iconName;
        iconName = media + "gnome-mime-" + media;
        if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data()))
            return iconName;
    }
    return "text-x-generic";
}

// FIXME: Move the code to ChromeClient::iconForFiles().
RefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
{
    if (filenames.isEmpty())
        return nullptr;

    if (filenames.size() == 1) {
        if (!g_path_skip_root(filenames[0].utf8().data()))
            return nullptr;

        String MIMEType = MIMETypeRegistry::getMIMETypeForPath(filenames[0]);
        String iconName = lookupIconName(MIMEType);

        RefPtr<Icon> icon = adoptRef(new Icon);
        icon->m_icon = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), iconName.utf8().data(), 16, GTK_ICON_LOOKUP_USE_BUILTIN, 0);
        if (!icon->m_icon)
            return nullptr;
        return icon;
    }

    //FIXME: Implement this
    return 0;
}

void Icon::paint(GraphicsContext& context, const FloatRect& rect)
{
    if (context.paintingDisabled())
        return;

    // TODO: Scale/clip the image if necessary.
    cairo_t* cr = context.platformContext()->cr();
    cairo_save(cr);
    gdk_cairo_set_source_pixbuf(cr, m_icon, rect.x(), rect.y());
    cairo_paint(cr);
    cairo_restore(cr);
}

}
