#include "WebFrameLoaderClient.h"

#include <WebCore/DocumentLoader.h>

#include <iostream>

using namespace WebCore;

using namespace std;

WebFrameLoaderClient::WebFrameLoaderClient(const WebCore::IntSize& targetSize, WebView* webView)
    : m_coreFrame(nullptr), m_webView(webView), m_targetSize(targetSize) {
    ASSERT(m_webView != nullptr);
}

void WebFrameLoaderClient::transitionToCommittedForNewPage()
{
    bool isMainFrame = m_coreFrame->isMainFrame();
    if (isMainFrame && m_coreFrame->view())
        m_coreFrame->view()->setParentVisible(false);
    RefPtr<FrameView> coreView = FrameView::create(*m_coreFrame);
    m_coreFrame->setView(nullptr);
    m_coreFrame->setView(coreView.copyRef());
    coreView->setFrameRect(IntRect(0,0,m_targetSize.width(),m_targetSize.height()));
    if (isMainFrame)
        coreView->setParentVisible(true);
}

void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
{
    m_responseData = std::string(data, length);
    loader->commitData(m_responseData.data(), length);
}

void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    m_webView->dispatchWillSendRequest(loader, identifier, request, redirectResponse);
}

void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
{
    WTFLogAlways("dispatchDidFailLoading: [%ld] %s", identifier, error.localizedDescription().ascii().data());
    WTFLogAlways("dispatchDidFailLoading: domain: %s", error.domain().ascii().data());
    WTFLogAlways("dispatchDidFailLoading: failingURL: %s", error.failingURL().string().ascii().data());
    WTFLogAlways("dispatchDidFailLoading: type: %d", (int)error.type());
}

void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
{
    WTFLogAlways("dispatchDidFailLoad: %s", error.localizedDescription().ascii().data());
}

void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, PassRefPtr<FormState>, FramePolicyFunction function)
{
    function(PolicyUse);
}

void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, FramePolicyFunction function)
{
    function(PolicyUse);
}

void WebFrameLoaderClient::dispatchWillSubmitForm(PassRefPtr<FormState> formState, FramePolicyFunction function)
{
    function(PolicyUse);
}

void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
{
    m_title = title.string().ascii().data();
}

void WebFrameLoaderClient::dispatchDidFinishLoad()
{
    m_webView->dispatchDidFinishLoad();
}

ObjectContentType WebFrameLoaderClient::objectContentType(const URL&, const String&)
{
    return ObjectContentType();
}

WTF::String WebFrameLoaderClient::userAgent(const WebCore::URL&)
{
    return "Mozilla/5.0 (Fuchsia; Intel Fuchsia)";
}

void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
{
    WTFLogAlways("setMainDocumentError: %s", error.localizedDescription().ascii().data());
    m_mainDocumentError = error.localizedDescription().ascii().data();
}

