/*
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "config.h"
#include "ClipboardGtk.h"

#include "CachedImage.h"
#include "DragData.h"
#include "Editor.h"
#include "Element.h"
#include "FileList.h"
#include "Frame.h"
#include "HTMLNames.h"
#include "Image.h"
#include "NotImplemented.h"
#include "Pasteboard.h"
#include "PasteboardHelper.h"
#include "RenderImage.h"
#include "ScriptExecutionContext.h"
#include "markup.h"
#include <wtf/text/CString.h>
#include <wtf/text/StringHash.h>

namespace WebCore {

enum ClipboardDataType {
    ClipboardDataTypeText,
    ClipboardDataTypeMarkup,
    ClipboardDataTypeURIList,
    ClipboardDataTypeURL,
    ClipboardDataTypeImage,
    ClipboardDataTypeUnknown
};

PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame* frame)
{
    return ClipboardGtk::create(policy, Clipboard::DragAndDrop, frame);
}

PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
{
    return ClipboardGtk::create(policy, DragAndDrop, frame);
}

ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, ClipboardType clipboardType, Frame* frame)
    : Clipboard(policy, CopyAndPaste)
    , m_frame(frame)
{
}

ClipboardGtk::~ClipboardGtk()
{
    if (m_dragImage)
        m_dragImage->removeClient(this);
}

static ClipboardDataType dataObjectTypeFromHTMLClipboardType(const String& rawType)
{
    String type(rawType.stripWhiteSpace());

    // Two special cases for IE compatibility
    if (type == "Text" || type == "text")
        return ClipboardDataTypeText;
    if (type == "URL")
        return ClipboardDataTypeURL;

    // From the Mac port: Ignore any trailing charset - JS strings are
    // Unicode, which encapsulates the charset issue.
    if (type == "text/plain" || type.startsWith("text/plain;"))
        return ClipboardDataTypeText;
    if (type == "text/html" || type.startsWith("text/html;"))
        return ClipboardDataTypeMarkup;
    if (type == "Files" || type == "text/uri-list" || type.startsWith("text/uri-list;"))
        return ClipboardDataTypeURIList;

    // Not a known type, so just default to using the text portion.
    return ClipboardDataTypeUnknown;
}

void ClipboardGtk::clearData(const String& typeString)
{
    if (policy() != ClipboardWritable)
        return;

    notImplemented();
}


void ClipboardGtk::clearAllData()
{
    if (policy() != ClipboardWritable)
        return;

    notImplemented();
}

String ClipboardGtk::getData(const String& typeString) const
{
    notImplemented();

    return String();
}

bool ClipboardGtk::setData(const String& typeString, const String& data)
{
    if (policy() != ClipboardWritable)
        return false;

    bool success = false;

    notImplemented();

    return success;
}

HashSet<String> ClipboardGtk::types() const
{
    if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
        return HashSet<String>();

    notImplemented();

    return HashSet<String>();
}

PassRefPtr<FileList> ClipboardGtk::files() const
{
    if (policy() != ClipboardReadable)
        return FileList::create();

    notImplemented();
    
    return FileList::create();
}

void ClipboardGtk::setDragImage(CachedImage* image, const IntPoint& location)
{
    setDragImage(image, 0, location);
}

void ClipboardGtk::setDragImageElement(Node* element, const IntPoint& location)
{
    setDragImage(0, element, location);
}

void ClipboardGtk::setDragImage(CachedImage* image, Node* element, const IntPoint& location)
{
    if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
        return;

    if (m_dragImage)
        m_dragImage->removeClient(this);
    m_dragImage = image;
    if (m_dragImage)
        m_dragImage->addClient(this);

    m_dragLoc = location;
    m_dragImageElement = element;
}

DragImageRef ClipboardGtk::createDragImage(IntPoint& location) const
{
    location = m_dragLoc;

    if (m_dragImage)
        return createDragImageFromImage(m_dragImage->image());
    if (m_dragImageElement && m_frame)
        return m_frame->nodeImage(m_dragImageElement.get());

    return 0; // We do not have enough information to create a drag image, use the default icon.
}

void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, const String& label, Frame* frame)
{
    notImplemented();
}

void ClipboardGtk::writeURL(const KURL& url, const String& label, Frame*)
{
    notImplemented();
}

void ClipboardGtk::writeRange(Range* range, Frame* frame)
{
    notImplemented();
}

void ClipboardGtk::writePlainText(const String& text)
{
    notImplemented();
}

bool ClipboardGtk::hasData()
{
    notImplemented();
    return false;
}

}
