/*
 * 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER 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 "core/testing/DummyPageHolder.h"

#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/loader/EmptyClients.h"
#include "wtf/Assertions.h"

namespace blink {

PassOwnPtr<DummyPageHolder> DummyPageHolder::create(
    const IntSize& initialViewSize,
    Page::PageClients* pageClients,
    PassOwnPtr<FrameLoaderClient> frameLoaderClient) {
    return adoptPtr(new DummyPageHolder(initialViewSize, pageClients, frameLoaderClient));
}

DummyPageHolder::DummyPageHolder(
    const IntSize& initialViewSize,
    Page::PageClients* pageClients,
    PassOwnPtr<FrameLoaderClient> frameLoaderClient)
{
    if (!pageClients) {
        fillWithEmptyClients(m_pageClients);
    } else {
        m_pageClients.chromeClient = pageClients->chromeClient;
        m_pageClients.editorClient = pageClients->editorClient;
        m_pageClients.spellCheckerClient = pageClients->spellCheckerClient;
    }
    m_page = adoptPtrWillBeNoop(new Page(m_pageClients));

    // FIXME(sky): Delete the tests that use DummyPageHolder since
    // they no longer work and we're not running them.

    // Settings& settings = m_page->settings();
    // FIXME: http://crbug.com/363843. This needs to find a better way to
    // not create graphics layers.
    // settings.setAcceleratedCompositingEnabled(false);

    m_frameLoaderClient = frameLoaderClient;
    if (!m_frameLoaderClient)
        m_frameLoaderClient = adoptPtr(new EmptyFrameLoaderClient);

    m_frame = LocalFrame::create(m_frameLoaderClient.get(), &m_page->frameHost());
    m_frame->setView(FrameView::create(m_frame.get(), initialViewSize));
}

DummyPageHolder::~DummyPageHolder()
{
    m_page->willBeDestroyed();
    m_page.clear();
#if !ENABLE(OILPAN)
    ASSERT(m_frame->hasOneRef());
#endif
    m_frame.clear();
}

Page& DummyPageHolder::page() const
{
    return *m_page;
}

LocalFrame& DummyPageHolder::frame() const
{
    return *m_frame;
}

FrameView& DummyPageHolder::frameView() const
{
    return *m_frame->view();
}

Document& DummyPageHolder::document() const
{
    return *m_frame->domWindow()->document();
}

} // namespace blink
