/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Google Inc.
 *
 * 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 "Document.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "RenderView.h"
#include "Settings.h"

namespace WebCore {

namespace {

struct ScopedState {
    ScopedState(Frame* theFrame, RenderObject* theRenderer)
        : frame(theFrame)
        , renderer(theRenderer)
        , paintBehavior(frame->view()->paintBehavior())
        , backgroundColor(frame->view()->baseBackgroundColor())
    {
    }

    ~ScopedState()
    {
        if (renderer)
            renderer->updateDragState(false);
        frame->view()->setPaintBehavior(paintBehavior);
        frame->view()->setBaseBackgroundColor(backgroundColor);
        frame->view()->setNodeToDraw(0);
    }

    Frame* frame;
    RenderObject* renderer;
    PaintBehavior paintBehavior;
    Color backgroundColor;
};

} // namespace

DragImageRef Frame::nodeImage(Node* node)
{
    RenderObject* renderer = node->renderer();
    if (!renderer)
        return 0;

    const ScopedState state(this, renderer);

    renderer->updateDragState(true);
    m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
    // When generating the drag image for an element, ignore the document background.
    m_view->setBaseBackgroundColor(colorWithOverrideAlpha(Color::white, 1.0));
    m_doc->updateLayout();
    m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.

    IntRect topLevelRect;
    IntRect paintingRect = renderer->paintingRootRect(topLevelRect);

    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
    if (!buffer)
        return 0;
    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));

    m_view->paintContents(buffer->context(), paintingRect);

    RefPtr<Image> image = buffer->copyImage();
    return createDragImageFromImage(image.get());
}

DragImageRef Frame::dragImageForSelection()
{
    if (!selection()->isRange())
        return 0;

    const ScopedState state(this, 0);
    m_view->setPaintBehavior(PaintBehaviorSelectionOnly);
    m_doc->updateLayout();

    IntRect paintingRect = enclosingIntRect(selection()->bounds());

    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
    if (!buffer)
        return 0;
    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));

    m_view->paintContents(buffer->context(), paintingRect);

    RefPtr<Image> image = buffer->copyImage();
    return createDragImageFromImage(image.get());
}

} // namespace WebCore
