/////////////////////////////////////////////////////////////////////////////
// Name:        webbrowser.cpp
// Purpose:     Web browser window
// Author:      Julian Smart
// Modified by: Francesco Montorsi
// Created:     2003-11-30
// RCS-ID:      $Id: webbrowser.cpp,v 1.1.1.1 2006/12/12 09:39:05 frm Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWidgets license
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#include "wx/webbrowser.h"

#ifdef __WXMSW__

#ifdef __WXMAC__
    #include "wx/html/webkit.h"
#elif defined(__WXMSW__)
    #include "wx/iehtmlwin.h"
#endif

#include "bitmaps/open_small.xpm"
#include "bitmaps/back_small.xpm"
#include "bitmaps/forward_small.xpm"
#include "bitmaps/home_small.xpm"
#include "bitmaps/stop_small.xpm"
#include "bitmaps/refresh_small.xpm"
#include "bitmaps/browser_search.xpm"
#include "bitmaps/browser_newwindow.xpm"
#include "bitmaps/weblink_tool.xpm"

/*
 * wxWebBrowserWindow draws a texture and holds an HTML window.
 */

IMPLEMENT_CLASS(wxWebBrowserWindow, wxWindow)

BEGIN_EVENT_TABLE(wxWebBrowserWindow, wxWindow)
//    EVT_PAINT(wxWebBrowserWindow::OnPaint)
    EVT_ERASE_BACKGROUND(wxWebBrowserWindow::OnEraseBackground)
    EVT_SIZE(wxWebBrowserWindow::OnSize)
#ifdef __WXMSW__
    EVT_IDLE(wxWebBrowserWindow::OnIdle)
#endif
#ifdef __WXMAC__
    EVT_WEBKIT_STATE_CHANGED(wxWebBrowserWindow::OnStateChanged)
#endif
    EVT_TOOL(wxID_BROWSER_OPEN_URL, wxWebBrowserWindow::OnOpenURL)
    EVT_TOOL(wxID_BROWSER_GO_HOME, wxWebBrowserWindow::OnHome)
    EVT_TOOL(wxID_BROWSER_GO_BACK, wxWebBrowserWindow::OnBack)
    EVT_TOOL(wxID_BROWSER_GO_FORWARD, wxWebBrowserWindow::OnForward)
    EVT_TOOL(wxID_BROWSER_STOP, wxWebBrowserWindow::OnStop)
    EVT_TOOL(wxID_BROWSER_REFRESH, wxWebBrowserWindow::OnReload)
    EVT_TOOL(wxID_BROWSER_URL_TEXT, wxWebBrowserWindow::OnURLEnter)
    EVT_TOOL(wxID_BROWSER_SEARCH, wxWebBrowserWindow::OnSearch)
    EVT_TOOL(wxID_BROWSER_NEW_WINDOW, wxWebBrowserWindow::OnNewWindow)
    EVT_TEXT_ENTER(wxID_BROWSER_URL_CTRL, wxWebBrowserWindow::OnURLEnter)

    EVT_TOOL_ENTER(-1, wxWebBrowserWindow::OnToolEnter)

    // Causes crash on init :-(
//    EVT_ACTIVEX(wxID_BROWSER_CTRL, "BeforeNavigate2", wxWebBrowserWindow::OnMSHTMLBeforeNavigate)
END_EVENT_TABLE()

wxWebBrowserWindow::wxWebBrowserWindow(wxWindow* parent, wxWindowID id,
       const wxPoint& pos, const wxSize& size, long style):
    wxWindow(parent, id, pos, size, style)
{
    m_urlTextCtrl = NULL;
    m_toolBar = NULL;
    m_browserWindow = NULL;
}

/// Create windows. Must be called outside of ctor for virtual functions
/// to work.
bool wxWebBrowserWindow::CreateWindows()
{
    CreateToolbar();

#ifdef __WXMAC__
    // Needs a positive size
    m_browserWindow = new wxWebKitCtrl(this, wxID_BROWSER_CTRL, wxEmptyString, wxDefaultPosition, wxSize(20, 20),
        /* wxNO_BORDER */ 0);
#elif defined(__WXMSW__)
    m_browserWindow = new wxIEHtmlWin(this, wxID_BROWSER_CTRL, wxDefaultPosition, wxDefaultSize,
        wxNO_BORDER );
#endif

    return true;
}

// Prepend http:// if necessary
void wxWebBrowserWindow::MakeRealURL(wxString& url)
{
    if (url.Find(wxT("://")) == -1 && url.Find(wxT("file:")) == -1)
        url = wxT("http://") + url;
}

void wxWebBrowserWindow::LoadInitialPage()
{
    wxString initialFile(GetInitialPage());
    initialFile.Replace(wxT("\\"), wxT("/"));
    initialFile = wxT("file:///") + initialFile;

    LoadPage(initialFile);
}

void wxWebBrowserWindow::OnSize(wxSizeEvent& event)
{
    if (m_browserWindow && m_toolBar)
    {
        wxSize clientSize = GetClientSize();
        wxSize toolBarSize = m_toolBar->GetSize();
        m_toolBar->SetSize(0, 0, clientSize.x, toolBarSize.y);

        // On Windows, setting the size can cause adjustment of the returned size, so
        // get the size again
        toolBarSize = m_toolBar->GetSize();

        m_browserWindow->SetSize(0, toolBarSize.y, clientSize.x, clientSize.y-toolBarSize.y);

        //        wxSize toolBarNewSize = m_toolBar->GetSize();
        //        printf("Client width: %d\n", clientSize.x);
        //        printf("Toolbar old and new widths: %d, %d\n", toolBarSize.x, toolBarNewSize.x);

        wxPoint pos = GetURLTextCtrl()->GetPosition();
        wxSize sz = GetURLTextCtrl()->GetSize();

        // int margin = 4;
        int margin = 2;

        GetURLTextCtrl()->SetSize(pos.x, pos.y, clientSize.x - pos.x - margin, sz.y);

    }
}

void wxWebBrowserWindow::OnEraseBackground(wxEraseEvent& event)
{
}

void wxWebBrowserWindow::OnIdle(wxIdleEvent& event)
{
#ifdef __WXMSW__
    if (GetBrowser() && GetURLTextCtrl() && FindFocus() != GetURLTextCtrl())
    {
        wxString currentURL = m_browserWindow->GetPropAsString(wxT("LocationURL"));
        wxString displayedURL = GetURLTextCtrl()->GetValue();
        if (currentURL != m_lastUrl && currentURL != displayedURL)
            GetURLTextCtrl()->SetValue(currentURL);
    }
#endif
    event.Skip();
}

bool wxWebBrowserWindow::LoadPage(const wxString& url)
{
#ifdef __WXMAC__
    wxString url1 = url;
    url1.Replace(wxT("\xE9"), wxT("%E9"));
    MakeRealURL(url1);

    GetURLTextCtrl()->SetValue(url1);
    m_browserWindow->LoadURL(url1);
    return TRUE;
#elif defined(__WXMSW__)
    m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));

    wxString url1 = url;
    url1.Replace(wxT("\xE9"), wxT("%E9"));

    GetURLTextCtrl()->SetValue(url1);
    m_browserWindow->LoadUrl(url1);
    return TRUE;
#endif
}

/// Called to add permanent (document-independent) tools to
/// the main toolbar for the main window or undocked window.
bool wxWebBrowserWindow::CreateToolbar()
{
    m_toolBar = CreateToolBarObject();

    AddToolBarTools(m_toolBar);
    AddURLControl(m_toolBar);

    m_toolBar->Realize();

    return true;
}

wxToolBarBase* wxWebBrowserWindow::CreateToolBarObject()
{
    return new wxToolBar(this, -1, wxDefaultPosition, wxSize(-1, -1), wxNO_BORDER|wxTB_FLAT|wxTB_NODIVIDER|wxTB_NOALIGN);
}

/// Add toolbar tools
void wxWebBrowserWindow::AddToolBarTools(wxToolBarBase* toolBar)
{
    wxBitmap toolBarBitmaps[30];

    toolBarBitmaps[0] = wxBitmap(open_small_xpm);
    toolBarBitmaps[1] = wxBitmap(back_small_xpm);
    toolBarBitmaps[2] = wxBitmap(forward_small_xpm);
    toolBarBitmaps[3] = wxBitmap(home_small_xpm);
    toolBarBitmaps[4] = wxBitmap(browser_search_xpm);
    toolBarBitmaps[5] = wxBitmap(stop_small_xpm);
    toolBarBitmaps[6] = wxBitmap(refresh_small_xpm);
    toolBarBitmaps[7] = wxBitmap(browser_newwindow_xpm);
    toolBarBitmaps[8] = wxBitmap(weblink_tool_xpm);

    m_toolBar->SetToolBitmapSize(wxSize(16, 16));
    m_toolBar->AddTool(wxID_BROWSER_OPEN_URL, toolBarBitmaps[0], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Open URL"), _("Prompts for a web address to open"));
    m_toolBar->AddSeparator();
    m_toolBar->AddTool(wxID_BROWSER_GO_BACK, toolBarBitmaps[1], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go back"), _("Goes back a page"));
    m_toolBar->AddTool(wxID_BROWSER_GO_FORWARD, toolBarBitmaps[2], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go forward"), _("Goes forward a page"));
    m_toolBar->AddTool(wxID_BROWSER_STOP, toolBarBitmaps[5], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Stop"), _("Stops the current operation"));
    m_toolBar->AddTool(wxID_BROWSER_GO_HOME, toolBarBitmaps[3], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go home"), _("Goes to the user's designated home page"));
    m_toolBar->AddTool(wxID_BROWSER_REFRESH, toolBarBitmaps[6], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Reload"), _("Reloads the current page"));
    m_toolBar->AddTool(wxID_BROWSER_NEW_WINDOW, toolBarBitmaps[7], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Show page in browser"), _("Shows the current page in an external browser"));

    m_toolBar->AddSeparator();
    m_toolBar->AddTool(wxID_BROWSER_SEARCH, toolBarBitmaps[4], wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Search"), _("Shows the web search page"));
}

/// Add the URL control (usually the last one)
void wxWebBrowserWindow::AddURLControl(wxToolBarBase* toolBar)
{
    m_toolBar->AddSeparator();
    m_urlTextCtrl = new wxURLTextCtrl(m_toolBar, wxID_BROWSER_URL_CTRL, wxT(""), wxDefaultPosition, wxSize(100, -1));
    m_toolBar->AddControl(m_urlTextCtrl);
}


void wxWebBrowserWindow::OnBack(wxCommandEvent& event)
{
#if defined(__WXMSW__)
    m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));
#endif
    m_browserWindow->GoBack();
}

void wxWebBrowserWindow::OnForward(wxCommandEvent& event)
{
#if defined(__WXMSW__)
    m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));
#endif
    m_browserWindow->GoForward();
}

void wxWebBrowserWindow::OnHome(wxCommandEvent& event)
{
#ifdef __WXMAC__
    // FIXME: no Go Home?
    // For now, go to the app-designated home page.
    LoadInitialPage();
#elif defined(__WXMSW__)
    m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));
    m_browserWindow->GoHome();
#endif
}

void wxWebBrowserWindow::OnReload(wxCommandEvent& event)
{
#ifdef __WXMAC__
    m_browserWindow->Reload();
#elif defined(__WXMSW__)
    m_browserWindow->Refresh(wxIEHTML_REFRESH_NORMAL);
#endif
}

void wxWebBrowserWindow::OnOpenURL(wxCommandEvent& event)
{
//    wxString location = m_browserWindow->GetPropAsString(wxT("LocationURL"));
//    wxMessageBox(location);
    wxString url = wxGetTextFromUser(_("Please enter a URL"), _("Open URL"),
        wxEmptyString, this);
    if (!url.IsEmpty())
    {
#ifdef __WXMAC__
        MakeRealURL(url);
        m_browserWindow->LoadURL(url);
        m_browserWindow->SetFocus();
#elif defined(__WXMSW__)
        m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));
        m_browserWindow->LoadUrl(url);
        m_browserWindow->SetFocus();
#endif
    }
}

void wxWebBrowserWindow::OnStop(wxCommandEvent& event)
{
    m_browserWindow->Stop();
}

void wxWebBrowserWindow::OnSearch(wxCommandEvent& event)
{
    wxString searchEngine = GetSearchEngine();
    if (!searchEngine.IsEmpty() && searchEngine.Find(wxT("http://")) == wxNOT_FOUND)
        searchEngine = wxT("http://") + searchEngine;
#ifdef __WXMAC__
    if (searchEngine.IsEmpty())
        searchEngine = wxT("http://www.google.com");
    m_browserWindow->LoadURL(searchEngine);
    m_browserWindow->SetFocus();
#elif defined(__WXMSW__)
    if (!searchEngine.IsEmpty())
    {
        m_browserWindow->LoadUrl(searchEngine);
        m_browserWindow->SetFocus();
    }
    else
        m_browserWindow->GoSearch();
#endif
}

void wxWebBrowserWindow::OnURLEnter(wxCommandEvent& event)
{
#ifdef __WXMAC__
    wxString url = GetURLTextCtrl()->GetValue();
    if (!url.IsEmpty())
    {
        MakeRealURL(url);
        m_browserWindow->LoadURL(url);
        m_browserWindow->SetFocus();
    }

#elif defined(__WXMSW__)
    wxString url = GetURLTextCtrl()->GetValue();
    if (!url.IsEmpty())
    {
        m_lastUrl = m_browserWindow->GetPropAsString(wxT("LocationURL"));
        m_browserWindow->LoadUrl(url);
        m_browserWindow->SetFocus();
    }
#endif
}

#ifdef __WXMSW__
void wxWebBrowserWindow::OnMSHTMLBeforeNavigate(wxActiveXEvent& event)
{
//    wxString url = event[wxT("Url")];
/*
wxVariant& wxActiveXEvent::operator[] (wxString name)
{
    int i;

    for (i = 0; i < m_params.GetCount(); i++)
    {
        if (name.CmpNoCase(m_params[i].GetName()) == 0)
            return m_params[i];
    };

    wxString err = wxT("wxActiveXEvent::operator[] invalid name <") + name + wxT(">");
    err += wxT("\r\nValid Names = :\r\n");
    for (i = 0; i < m_params.GetCount(); i++)
    {
        err += m_params[i].GetName();
        err += wxT("\r\n");
    };

    wxASSERT_MSG(false, err);

    return nullVar;
};


    if (url == wxT("about:blank"))
        url = wxEmptyString;
    m_urlTextCtrl->SetValue(url);*/
}
#endif

#ifdef __WXMAC__
void wxWebBrowserWindow::OnStateChanged(wxWebKitStateChangedEvent& myEvent)
{
    wxFrame* frame = NULL;
    wxWindow* p = GetParent();
    while (p && !p->IsKindOf(CLASSINFO(wxFrame)))
        p = p->GetParent();
    if (p)
        frame = wxDynamicCast(p, wxFrame);

    if (myEvent.GetState() == wxWEBKIT_STATE_NEGOTIATING)
    {
        if (frame && frame->GetStatusBar())
            frame->GetStatusBar()->SetStatusText(_("Contacting ") + myEvent.GetURL());
        m_urlTextCtrl->SetValue(myEvent.GetURL());
    }
    else if (myEvent.GetState() == wxWEBKIT_STATE_TRANSFERRING)
    {
        if (frame && frame->GetStatusBar())
            frame->GetStatusBar()->SetStatusText(_("Loading ") + myEvent.GetURL());
    }
    else if (myEvent.GetState() == wxWEBKIT_STATE_STOP)
    {
        m_lastUrl = myEvent.GetURL();
        m_urlTextCtrl->SetValue(m_lastUrl);
        if (frame && frame->GetStatusBar())
            frame->GetStatusBar()->SetStatusText(_("Load complete."));
//        SetTitle(mySafari->GetTitle());
    }
    else if (myEvent.GetState() == wxWEBKIT_STATE_FAILED)
    {
        if (frame && frame->GetStatusBar())
            frame->GetStatusBar()->SetStatusText(_("Failed to load ") + myEvent.GetURL());
    }
}
#endif

void wxWebBrowserWindow::OnNewWindow(wxCommandEvent& event)
{
    wxString displayedURL = GetURLTextCtrl()->GetValue();
    if (!displayedURL.IsEmpty())
        ViewInBrowser(displayedURL);
        // stViewHTMLFile(displayedURL);
}

void wxWebBrowserWindow::OnToolEnter(wxCommandEvent& event)
{
    wxWindow* parent = GetParent();
    while (parent && !parent->IsKindOf(CLASSINFO(wxFrame)))
    {
        parent = parent->GetParent();
    }
    wxFrame* frameParent = wxDynamicCast(parent, wxFrame);
    if (frameParent)
    {
        long id = event.GetInt();
        wxToolBarToolBase* tool = id == -1 ? (wxToolBarToolBase*)0 : m_toolBar->FindById(id);
        wxString help = tool ? tool->GetLongHelp() : wxString();
        frameParent->DoGiveHelp(help, id != -1);
    }
}

/*
 * wxURLTextCtrl
 */

IMPLEMENT_CLASS(wxURLTextCtrl, wxTextCtrl)

BEGIN_EVENT_TABLE(wxURLTextCtrl, wxTextCtrl)
    EVT_CHAR(wxURLTextCtrl::OnChar)
    EVT_SET_FOCUS(wxURLTextCtrl::OnSetFocus)
END_EVENT_TABLE()

wxURLTextCtrl::wxURLTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value,
       const wxPoint& pos, const wxSize& size, long style):
    wxTextCtrl(parent, id, value, pos, size, style)
{
    SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}

void wxURLTextCtrl::OnChar(wxKeyEvent& event)
{
    event.Skip();
}

void wxURLTextCtrl::OnSetFocus(wxFocusEvent& event)
{
    SetSelection(-1, -1);
}

void wxURLTextCtrl::OnTextUpdated(wxCommandEvent& event)
{
#if 0
    wxWebBrowserWindow* parent = wxDynamicCast(GetParent()->GetParent(), wxWebBrowserWindow);
    if (parent)
    {
    }
#endif
    event.Skip();
}

#endif      // __WXMSW__
