/*
 * Copyright (C) 2007 Kevin Ollivier  All rights reserved.
 *
 * 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 "WebView.h"

#include "ContextMenu.h"
#include "ContextMenuController.h"
#include "ContextMenuItem.h"
#include "Document.h"
#include "Editor.h"
#include "Element.h"
#include "EmptyClients.h"
#include "EventHandler.h"
#include "FileChooser.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameSelection.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLFormElement.h"
#include "Logging.h"
#include "MemoryCache.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "ResourceHandleManager.h"
#include "Scrollbar.h"
#include "Settings.h"
#include "SubstituteData.h"
#include "Threading.h"
#include "markup.h"
#if __WXMSW__
#include "WebCoreInstanceHandle.h"
#endif

#include "ChromeClientWx.h"
#include "ContextMenuClientWx.h"
#include "DragClientWx.h"
#include "EditorClientWx.h"
#include "FrameLoaderClientWx.h"
#include "InspectorClientWx.h"

#include "ScriptController.h"
#include "JSDOMBinding.h"
#include <runtime/InitializeThreading.h>
#include <runtime/JSValue.h>
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>

#if ENABLE(SQL_DATABASE)
#include "AbstractDatabase.h"
#include "DatabaseTracker.h"
#endif

#include "wx/wxprec.h"
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include "WebDOMElement.h"
#include "WebDOMNode.h"

#include "WebFrame.h"
#include "WebViewPrivate.h"

#include <wx/defs.h>
#include <wx/dcbuffer.h>
#include <wx/dcgraph.h>

#if defined(_MSC_VER)
int rint(double val)
{
    return (int)(val < 0 ? val - 0.5 : val + 0.5);
}
#endif

#if OS(DARWIN)
// prototype - function is in WebSystemInterface.mm
void InitWebCoreSystemInterface(void);
#endif

// ----------------------------------------------------------------------------
// WebView Events
// ----------------------------------------------------------------------------

namespace WebKit {

IMPLEMENT_DYNAMIC_CLASS(WebViewLoadEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)

WebViewLoadEvent::WebViewLoadEvent(wxWindow* win)
{
    SetEventType( wxEVT_WEBVIEW_LOAD);
    SetEventObject( win );
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewBeforeLoadEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)

WebViewBeforeLoadEvent::WebViewBeforeLoadEvent(wxWindow* win)
{
    m_cancelled = false;
    SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewNewWindowEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)

WebViewNewWindowEvent::WebViewNewWindowEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewRightClickEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)

WebViewRightClickEvent::WebViewRightClickEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewConsoleMessageEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)

WebViewConsoleMessageEvent::WebViewConsoleMessageEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewAlertEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)

WebViewAlertEvent::WebViewAlertEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_JS_ALERT);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewConfirmEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)

WebViewConfirmEvent::WebViewConfirmEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewPromptEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)

WebViewPromptEvent::WebViewPromptEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewReceivedTitleEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)

WebViewReceivedTitleEvent::WebViewReceivedTitleEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewWindowObjectClearedEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)

WebViewWindowObjectClearedEvent::WebViewWindowObjectClearedEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewContentsChangedEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONTENTS_CHANGED)

WebViewContentsChangedEvent::WebViewContentsChangedEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_CONTENTS_CHANGED);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewSelectionChangedEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_SELECTION_CHANGED)

WebViewSelectionChangedEvent::WebViewSelectionChangedEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_SELECTION_CHANGED);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

IMPLEMENT_DYNAMIC_CLASS(WebViewPrintFrameEvent, wxCommandEvent)

DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_PRINT_FRAME)

WebViewPrintFrameEvent::WebViewPrintFrameEvent(wxWindow* win)
{
    SetEventType(wxEVT_WEBVIEW_PRINT_FRAME);
    SetEventObject(win);
    if (win)
        SetId(win->GetId());
}

//---------------------------------------------------------
// DOM Element info data type
//---------------------------------------------------------

WebViewDOMElementInfo::WebViewDOMElementInfo() :
    m_isSelected(false),
    m_text(wxEmptyString),
    m_imageSrc(wxEmptyString),
    m_link(wxEmptyString),
    m_urlElement(0),
    m_innerNode(0)
{
}

static WebViewCachePolicy gs_cachePolicy;

/* static */
void WebView::SetCachePolicy(const WebViewCachePolicy& cachePolicy)
{
    WebCore::MemoryCache* globalCache = WebCore::memoryCache();
    globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(),
                               cachePolicy.GetMaxDeadCapacity(),
                               cachePolicy.GetCapacity());

    // store a copy since there is no getter for MemoryCache values
    gs_cachePolicy = cachePolicy;
}

/* static */
WebViewCachePolicy WebView::GetCachePolicy()
{
    return gs_cachePolicy;
}

WebViewDOMElementInfo::WebViewDOMElementInfo(const WebViewDOMElementInfo& other)
{
    m_isSelected = other.m_isSelected;
    m_text = other.m_text;
    m_imageSrc = other.m_imageSrc;
    m_link = other.m_link;
    m_innerNode = other.m_innerNode;
    m_urlElement = other.m_urlElement;
}

WebViewDOMElementInfo::~WebViewDOMElementInfo() 
{
    if (m_innerNode)
        delete m_innerNode;
        
    if (m_urlElement)
        delete m_urlElement;
}

BEGIN_EVENT_TABLE(WebView, wxWindow)
    EVT_PAINT(WebView::OnPaint)
    EVT_SIZE(WebView::OnSize)
    EVT_MOUSE_EVENTS(WebView::OnMouseEvents)
    EVT_CONTEXT_MENU(WebView::OnContextMenuEvents)
    EVT_KEY_DOWN(WebView::OnKeyEvents)
    EVT_KEY_UP(WebView::OnKeyEvents)
    EVT_CHAR(WebView::OnKeyEvents)
    EVT_SET_FOCUS(WebView::OnSetFocus)
    EVT_KILL_FOCUS(WebView::OnKillFocus)
    EVT_MOUSE_CAPTURE_LOST(WebView::OnMouseCaptureLost)
END_EVENT_TABLE()

IMPLEMENT_DYNAMIC_CLASS(WebView, wxWindow)

const wxChar* WebViewNameStr = wxT("webView");

WebView::WebView() :
    m_textMagnifier(1.0),
    m_isInitialized(false),
    m_beingDestroyed(false),
    m_mouseWheelZooms(false),
    m_title(wxEmptyString)
{
}

WebView::WebView(wxWindow* parent, const wxString& url, int id, const wxPoint& position, 
                     const wxSize& size, long style, const wxString& name) :
    m_textMagnifier(1.0),
    m_isInitialized(false),
    m_beingDestroyed(false),
    m_mouseWheelZooms(false),
    m_title(wxEmptyString)
{
    Create(parent, url, id, position, size, style, name);
}

bool WebView::Create(wxWindow* parent, const wxString& url, int id, const wxPoint& position, 
                       const wxSize& size, long style, const wxString& name)
{
#if OS(DARWIN)
    InitWebCoreSystemInterface();
#endif

    if ( (style & wxBORDER_MASK) == 0)
        style |= wxBORDER_NONE;
    
    if (!wxWindow::Create(parent, id, position, size, style, name))
        return false;

    JSC::initializeThreading();
    WTF::initializeMainThread();

// This is necessary because we are using SharedTimerWin.cpp on Windows,
// due to a problem with exceptions getting eaten when using the callback
// approach to timers (which wx itself uses).
#if __WXMSW__
    WebCore::setInstanceHandle(wxGetInstance());
#endif

    // this helps reduce flicker on platforms like MSW
    SetBackgroundStyle(wxBG_STYLE_CUSTOM);

    m_impl = new WebViewPrivate();

#if !LOG_DISABLED
    WebCore::initializeLoggingChannelsIfNecessary();
#endif // !LOG_DISABLED
    WebCore::HTMLFrameOwnerElement* parentFrame = 0;

    WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();

    WebCore::Page::PageClients pageClients;
    pageClients.chromeClient = new WebCore::ChromeClientWx(this);
    pageClients.contextMenuClient = new WebCore::ContextMenuClientWx();
    pageClients.editorClient = editorClient;
    pageClients.dragClient = new WebCore::DragClientWx();
    pageClients.inspectorClient = new WebCore::InspectorClientWx();
    m_impl->page = new WebCore::Page(pageClients);
    editorClient->setPage(m_impl->page);
    
    m_mainFrame = new WebFrame(this);

    // Default settings - we should have WebViewSettings class for this
    // eventually
    WebCore::Settings* settings = m_impl->page->settings();
    settings->setLoadsImagesAutomatically(true);
    settings->setDefaultFixedFontSize(13);
    settings->setDefaultFontSize(16);
    settings->setSerifFontFamily("Times New Roman");
    settings->setFixedFontFamily("Courier New");
    settings->setSansSerifFontFamily("Arial");
    settings->setStandardFontFamily("Times New Roman");
    settings->setScriptEnabled(true);

#if ENABLE(SQL_DATABASE)
    SetDatabasesEnabled(true);
#endif

    // we need to do this so that objects like the focusController are properly
    // initialized so that the activate handler is run properly.
    LoadURL(url);
    
    m_isInitialized = true;

    return true;
}

WebView::~WebView()
{
    m_beingDestroyed = true;
    
    while (HasCapture())
        ReleaseMouse();
    
    if (m_mainFrame && m_mainFrame->GetFrame())
        m_mainFrame->GetFrame()->loader()->detachFromParent();
    
    delete m_impl->page;
    m_impl->page = 0;   
}

// NOTE: binding to this event in the WebView constructor is too early in 
// some cases, but leave the event handler here so that users can bind to it
// at a later time if they have activation state problems.
void WebView::OnTLWActivated(wxActivateEvent& event)
{        
    if (m_impl && m_impl->page && m_impl->page->focusController())
        m_impl->page->focusController()->setActive(event.GetActive());
    
    event.Skip();
    
}

void WebView::Stop()
{
    if (m_mainFrame)
        m_mainFrame->Stop();
}

void WebView::Reload()
{
    if (m_mainFrame)
        m_mainFrame->Reload();
}

wxString WebView::GetPageSource()
{
    if (m_mainFrame)
        return m_mainFrame->GetPageSource();

    return wxEmptyString;
}

void WebView::SetPageSource(const wxString& source, const wxString& baseUrl, const wxString& mimetype)
{
    if (m_mainFrame)
        m_mainFrame->SetPageSource(source, baseUrl, mimetype);
}

wxString WebView::GetInnerText()
{
    if (m_mainFrame)
        return m_mainFrame->GetInnerText();
        
    return wxEmptyString;
}

wxString WebView::GetAsMarkup()
{
    if (m_mainFrame)
        return m_mainFrame->GetAsMarkup();
        
    return wxEmptyString;
}

wxString WebView::GetExternalRepresentation()
{
    if (m_mainFrame)
        return m_mainFrame->GetExternalRepresentation();
        
    return wxEmptyString;
}

WebKitSelection WebView::GetSelection()
{
    if (m_mainFrame)
        return m_mainFrame->GetSelection();
        
    return 0;
}

wxString WebView::GetSelectionAsHTML()
{
    if (m_mainFrame)
        return m_mainFrame->GetSelectionAsHTML();
        
    return wxEmptyString;
}

wxString WebView::GetSelectionAsText()
{
    if (m_mainFrame)
        return m_mainFrame->GetSelectionAsText();
        
    return wxEmptyString;
}

void WebView::SetTransparent(bool transparent)
{
    WebCore::Frame* frame = 0;
    if (m_mainFrame)
        frame = m_mainFrame->GetFrame();
    
    if (!frame || !frame->view())
        return;

    frame->view()->setTransparent(transparent);
}

bool WebView::IsTransparent() const
{
    WebCore::Frame* frame = 0;
    if (m_mainFrame)
        frame = m_mainFrame->GetFrame();

   if (!frame || !frame->view())
        return false;

    return frame->view()->isTransparent();
}

wxString WebView::RunScript(const wxString& javascript)
{
    if (m_mainFrame)
        return m_mainFrame->RunScript(javascript);
    
    return wxEmptyString;
}

bool WebView::ExecuteEditCommand(const wxString& command, const wxString& parameter)
{
    if (m_mainFrame)
        return m_mainFrame->ExecuteEditCommand(command, parameter);
}

EditState WebView::GetEditCommandState(const wxString& command) const
{
    if (m_mainFrame)
        return m_mainFrame->GetEditCommandState(command);
}

wxString WebView::GetEditCommandValue(const wxString& command) const
{
    if (m_mainFrame)
        return m_mainFrame->GetEditCommandValue(command);
 
    return wxEmptyString;
}

void WebView::LoadURL(const wxString& url)
{
    if (m_mainFrame)
        m_mainFrame->LoadURL(url);
}

wxString WebView::GetMainFrameURL() const
{
    if (m_mainFrame)
        return m_mainFrame->GetURL();
    
    return wxEmptyString;
}

bool WebView::GoBack()
{
    if (m_mainFrame)
        return m_mainFrame->GoBack();

    return false;
}

bool WebView::GoForward()
{
    if (m_mainFrame)
        return m_mainFrame->GoForward();

    return false;
}

bool WebView::CanGoBack()
{
    if (m_mainFrame)
        return m_mainFrame->CanGoBack();

    return false;
}

bool WebView::CanGoForward()
{
    if (m_mainFrame)
        return m_mainFrame->CanGoForward();

    return false;
}

bool WebView::CanIncreaseTextSize() const
{
    if (m_mainFrame)
        return m_mainFrame->CanIncreaseTextSize();

    return false;
}

void WebView::IncreaseTextSize()
{
    if (m_mainFrame)
        m_mainFrame->IncreaseTextSize();
}

bool WebView::CanDecreaseTextSize() const
{
    if (m_mainFrame)
        return m_mainFrame->CanDecreaseTextSize();

    return false;
}

void WebView::DecreaseTextSize()
{        
    if (m_mainFrame)
        m_mainFrame->DecreaseTextSize();
}

void WebView::ResetTextSize()
{
    if (m_mainFrame)
        m_mainFrame->ResetTextSize();    
}

void WebView::MakeEditable(bool enable)
{
    if (m_mainFrame)
        m_mainFrame->MakeEditable(enable);
}

bool WebView::IsEditable() const
{
    if (m_mainFrame)
        return m_mainFrame->IsEditable();
    
    return false;
}



/* 
 * Event forwarding functions to send events down to WebCore.
 */

void WebView::OnPaint(wxPaintEvent& event)
{
    if (m_beingDestroyed || !m_mainFrame)
        return;

    WebCore::Frame* frame = m_mainFrame->GetFrame();
    if (!frame || !frame->view())
        return;

    // we can't use wxAutoBufferedPaintDC here because it will not create 
    // a 32-bit bitmap for its buffer.
#if __WXMSW__
    wxPaintDC paintdc(this);
    int width, height;
    paintdc.GetSize(&width, &height);
    wxBitmap bitmap(width, height, 32);
    wxMemoryDC dc(bitmap);
#else
    wxPaintDC dc(this);
#endif

    if (IsShown() && frame->document()) {
#if USE(WXGC)
#if wxCHECK_VERSION(2, 9, 2) && defined(wxUSE_CAIRO) && wxUSE_CAIRO
        wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetCairoRenderer();
        if (!renderer)
            renderer = wxGraphicsRenderer::GetDefaultRenderer();
        wxGraphicsContext* context = renderer->CreateContext(dc);
        wxGCDC gcdc(context);
#else
        wxGCDC gcdc(dc);
#endif
#endif

        if (dc.IsOk()) {
            wxRect paintRect = GetUpdateRegion().GetBox();

#if USE(WXGC)
            WebCore::GraphicsContext gc(&gcdc);
#else
            WebCore::GraphicsContext gc(&dc);
#endif
            if (frame->contentRenderer()) {
                frame->view()->updateLayoutAndStyleIfNeededRecursive();
                frame->view()->paint(&gc, paintRect);
#if __WXMSW__
                dc.SelectObject(wxNullBitmap);
                paintdc.DrawBitmap(bitmap, 0, 0);
#endif
            }
        }
    }
}

bool WebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
{
    if (m_mainFrame)
        return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);

    return false;
}

void WebView::OnSize(wxSizeEvent& event)
{ 
    if (m_isInitialized && m_mainFrame) {
        WebCore::Frame* frame = m_mainFrame->GetFrame();
        frame->view()->resize(event.GetSize());
        frame->view()->adjustViewSize();
    }
      
    event.Skip();
}

static int getDoubleClickTime()
{
#if __WXMSW__
    return ::GetDoubleClickTime();
#else
    return 500;
#endif
}

void WebView::OnMouseEvents(wxMouseEvent& event)
{
    event.Skip();
    
    if (!m_impl->page)
        return; 
        
    WebCore::Frame* frame = m_mainFrame->GetFrame();  
    if (!frame || !frame->view())
        return;
    
    wxPoint globalPoint = ClientToScreen(event.GetPosition());

    wxEventType type = event.GetEventType();
    
    if (type == wxEVT_MOUSEWHEEL) {
        if (m_mouseWheelZooms && event.ControlDown() && !event.AltDown() && !event.ShiftDown()) {
            if (event.GetWheelRotation() < 0)
                DecreaseTextSize();
            else if (event.GetWheelRotation() > 0)
                IncreaseTextSize();
        } else {
            WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
            frame->eventHandler()->handleWheelEvent(wkEvent);
        }

        return;
    }
    
    // If an event, such as a right-click event, leads to a focus change (e.g. it 
    // raises a dialog), WebKit never gets the mouse up event and never relinquishes 
    // mouse capture. This leads to WebKit handling mouse events, such as modifying
    // the selection, while other controls or top level windows have the focus.
    // I'm not sure if this is the right place to handle this, but I can't seem to
    // find a precedent on how to handle this in other ports.
    if (wxWindow::FindFocus() != this) {
        while (HasCapture())
            ReleaseMouse();

        frame->eventHandler()->setMousePressed(false);

        return;
    }
        
    int clickCount = event.ButtonDClick() ? 2 : 1;

    if (clickCount == 1 && m_impl->tripleClickTimer.IsRunning()) {
        wxPoint diff(event.GetPosition() - m_impl->tripleClickPos);
        if (abs(diff.x) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_X) &&
            abs(diff.y) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_Y)) {
            clickCount = 3;
        }
    } else if (clickCount == 2) {
        m_impl->tripleClickTimer.Start(getDoubleClickTime(), false);
        m_impl->tripleClickPos = event.GetPosition();
    }
    
    WebCore::PlatformMouseEvent wkEvent(event, globalPoint, clickCount);

    if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN || 
                type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) {
        frame->eventHandler()->handleMousePressEvent(wkEvent);
        if (!HasCapture())
            CaptureMouse();
    } else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP) {
        frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
        while (HasCapture())
            ReleaseMouse();
    } else if (type == wxEVT_MOTION || type == wxEVT_ENTER_WINDOW || type == wxEVT_LEAVE_WINDOW)
        frame->eventHandler()->mouseMoved(wkEvent);
}

void WebView::OnContextMenuEvents(wxContextMenuEvent& event)
{
    Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WebView::OnMenuSelectEvents), 0, this);
    m_impl->page->contextMenuController()->clearContextMenu();
    wxPoint localEventPoint = ScreenToClient(event.GetPosition());

    if (!m_impl->page)
        return;
        
    WebCore::Frame* focusedFrame = m_impl->page->focusController()->focusedOrMainFrame();
    if (!focusedFrame->view())
        return;

    //Create WebCore mouse event from the wxContextMenuEvent
    wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN);
    mouseEvent.m_x = localEventPoint.x;
    mouseEvent.m_y = localEventPoint.y;
    WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition(), 1);

    bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
    if (!handledEvent)
        return;

    WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
    if (!coreMenu)
        return;

    WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
    if (!menuWx)
        return;

    PopupMenu(menuWx, localEventPoint);
    
    Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WebView::OnMenuSelectEvents), 0, this);
}

void WebView::OnMenuSelectEvents(wxCommandEvent& event)
{
    // we shouldn't hit this unless there's a context menu showing
    WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
    ASSERT(coreMenu);
    if (!coreMenu)
        return;

    WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
    if (!item)
        return;

    m_impl->page->contextMenuController()->contextMenuItemSelected(item);
    delete item;
}

void WebView::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
{
    // do nothing - unfortunately, we MUST handle this event due to wxWidgets rules,
    // otherwise we will assert, even though there is nothing for us to do here.
}

bool WebView::CanCopy()
{
    if (m_mainFrame)
        return m_mainFrame->CanCopy();

    return false;
}

void WebView::Copy()
{
    if (m_mainFrame)
        m_mainFrame->Copy();
}

bool WebView::CanCut()
{
    if (m_mainFrame)
        return m_mainFrame->CanCut();

    return false;
}

void WebView::Cut()
{
    if (m_mainFrame)
        m_mainFrame->Cut();
}

bool WebView::CanPaste()
{
    if (m_mainFrame)
        return m_mainFrame->CanPaste();

    return false;
}

void WebView::Paste()
{
    if (m_mainFrame)
        m_mainFrame->Paste();
}

void WebView::OnKeyEvents(wxKeyEvent& event)
{
    WebCore::Frame* frame = 0;
    if (m_impl->page)
        frame = m_impl->page->focusController()->focusedOrMainFrame();

    if (!(frame && frame->view()))
        return;

    WebCore::PlatformKeyboardEvent wkEvent(event);

    if (frame->eventHandler()->keyEvent(wkEvent))
        return;

    //Some things WebKit won't do for us... Copy/Cut/Paste and KB scrolling
    if (event.GetEventType() == wxEVT_KEY_DOWN) {
        switch (event.GetKeyCode()) {
        case 67: //"C"
            if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
                Copy();
                return;
            }
            break;
        case 86: //"V"
            if (CanPaste() && event.GetModifiers() == wxMOD_CMD) {
                Paste();
                return;
            }
            break;
        case 88: //"X"
            if (CanCut() && event.GetModifiers() == wxMOD_CMD) {
                Cut();
                return;
            }
            break;
        case WXK_INSERT:
            if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
                Copy();
                return;
            }
            if (CanPaste() && event.GetModifiers() == wxMOD_SHIFT) {
                Paste();
                return;
            }
            return; //Insert shall not become a char
        case WXK_DELETE:
            if (CanCut() && event.GetModifiers() == wxMOD_SHIFT) {
                Cut();
                return;
            }
            break;
        case WXK_LEFT:
        case WXK_NUMPAD_LEFT:
            frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0));
            return;
        case WXK_UP:
        case WXK_NUMPAD_UP:
            frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep()));
            return;
        case WXK_RIGHT:
        case WXK_NUMPAD_RIGHT:
            frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0));
            return;
        case WXK_DOWN:
        case WXK_NUMPAD_DOWN:
            frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep()));
            return;
        case WXK_END:
        case WXK_NUMPAD_END:
            frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), frame->view()->maximumScrollPosition().y()));
            return;
        case WXK_HOME:
        case WXK_NUMPAD_HOME:
            frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), 0));
            return;
        case WXK_PAGEUP:
        case WXK_NUMPAD_PAGEUP:
            frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
            return;
        case WXK_PAGEDOWN:
        case WXK_NUMPAD_PAGEDOWN:
            frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
            return;
        //These we don't want turning into char events, stuff 'em
        case WXK_ESCAPE:
        case WXK_LBUTTON:
        case WXK_RBUTTON:
        case WXK_CANCEL:
        case WXK_MENU:
        case WXK_MBUTTON:
        case WXK_CLEAR:
        case WXK_PAUSE:
        case WXK_SELECT:
        case WXK_PRINT:
        case WXK_EXECUTE:
        case WXK_SNAPSHOT:
        case WXK_HELP:
        case WXK_F1:
        case WXK_F2:
        case WXK_F3:
        case WXK_F4:
        case WXK_F5:
        case WXK_F6:
        case WXK_F7:
        case WXK_F8:
        case WXK_F9:
        case WXK_F10:
        case WXK_F11:
        case WXK_F12:
        case WXK_F13:
        case WXK_F14:
        case WXK_F15:
        case WXK_F16:
        case WXK_F17:
        case WXK_F18:
        case WXK_F19:
        case WXK_F20:
        case WXK_F21:
        case WXK_F22:
        case WXK_F23:
        case WXK_F24:
        case WXK_NUMPAD_F1:
        case WXK_NUMPAD_F2:
        case WXK_NUMPAD_F3:
        case WXK_NUMPAD_F4:
        //When numlock is off Numpad 5 becomes BEGIN, or HOME on Char
        case WXK_NUMPAD_BEGIN:
        case WXK_NUMPAD_INSERT:
            return;
        }
    }

    event.Skip();
}

void WebView::OnSetFocus(wxFocusEvent& event)
{
    if (m_impl && m_impl->page && m_impl->page->focusController()) {
        m_impl->page->focusController()->setFocused(true);
        m_impl->page->focusController()->setActive(true);

        if (!m_impl->page->focusController()->focusedFrame() && m_mainFrame)
            m_impl->page->focusController()->setFocusedFrame(m_mainFrame->GetFrame());
    }
    
    event.Skip();
}

void WebView::OnKillFocus(wxFocusEvent& event)
{
    if (m_impl && m_impl->page && m_impl->page->focusController()) {
        m_impl->page->focusController()->setFocused(false);

        // We also handle active state in OnTLWActivated, but if a user does not
        // call event.Skip() in their own EVT_ACTIVATE handler, we won't get those
        // callbacks. So we handle active state here as well as a fallback.
        wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent(this));
        if (tlw && tlw->IsActive())
            m_impl->page->focusController()->setActive(true);
        else
            m_impl->page->focusController()->setActive(false);
    }
    
    while (HasCapture())
        ReleaseMouse();
    
    event.Skip();
}

WebViewDOMElementInfo WebView::HitTest(const wxPoint& pos) const
{
    if (m_mainFrame)
        return m_mainFrame->HitTest(pos);

    return WebViewDOMElementInfo();
}

bool WebView::ShouldClose() const
{
    if (m_mainFrame)
        return m_mainFrame->ShouldClose();

    return true;
}

/* static */
void WebView::SetDatabaseDirectory(const wxString& databaseDirectory)
{
#if ENABLE(SQL_DATABASE)
    WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
#endif
}

/* static */
wxString WebView::GetDatabaseDirectory()
{
#if ENABLE(SQL_DATABASE)
    return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
#else
    return wxEmptyString;
#endif
}

/* static */
void WebView::SetDatabasesEnabled(bool enabled)
{
#if ENABLE(SQL_DATABASE)
    WebCore::AbstractDatabase::setIsAvailable(enabled);
#endif
}

/* static */
bool WebView::AreDatabasesEnabled()
{
#if ENABLE(SQL_DATABASE)
    return WebCore::AbstractDatabase::isAvailable();
#endif
    return false;
}

static WebCore::ResourceHandleManager::ProxyType curlProxyType(wxProxyType type)
{
    switch (type) {
        case HTTP: return WebCore::ResourceHandleManager::HTTP;
        case Socks4: return WebCore::ResourceHandleManager::Socks4;
        case Socks4A: return WebCore::ResourceHandleManager::Socks4A;
        case Socks5: return WebCore::ResourceHandleManager::Socks5;
        case Socks5Hostname: return WebCore::ResourceHandleManager::Socks5Hostname;
        default:
            ASSERT_NOT_REACHED();
            return WebCore::ResourceHandleManager::HTTP;
    }
}

/* static */
void WebView::SetProxyInfo(const wxString& host,
                             unsigned long port,
                             wxProxyType type,
                             const wxString& username,
                             const wxString& password)
{
    using WebCore::ResourceHandleManager;
    if (ResourceHandleManager* mgr = ResourceHandleManager::sharedInstance())
        mgr->setProxyInfo(host, port, curlProxyType(type), username, password);
}

WebSettings WebView::GetWebSettings()
{
    ASSERT(m_impl->page);
    if (m_impl->page)
        return WebSettings(m_impl->page->settings());
    
    return WebSettings();
}

WebKitCompatibilityMode WebView::GetCompatibilityMode() const
{
    if (m_mainFrame)
        return m_mainFrame->GetCompatibilityMode();

    return QuirksMode;
}

void WebView::GrantUniversalAccess()
{
    if (m_mainFrame)
        m_mainFrame->GrantUniversalAccess();
}

}
