/*
 * Copyright (C) 2010 Apple 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:
 * 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 INC. AND ITS 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 APPLE INC. OR ITS 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 "WebInspectorProxy.h"

#if ENABLE(INSPECTOR)

#include "WebKitBundle.h"
#include "WebPageProxy.h"
#include "WebProcessProxy.h"
#include "WebView.h"
#include <WebCore/InspectorFrontendClientLocal.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/WebCoreInstanceHandle.h>
#include <WebCore/WindowMessageBroadcaster.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RetainPtr.h>
#include <wtf/text/StringConcatenate.h>
#include <wtf/text/WTFString.h>

using namespace WebCore;

namespace WebKit {

static const LPCWSTR kWebKit2InspectorWindowClassName = L"WebKit2InspectorWindowClass";

bool WebInspectorProxy::registerInspectorViewWindowClass()
{
    static bool haveRegisteredWindowClass = false;
    if (haveRegisteredWindowClass)
        return true;
    haveRegisteredWindowClass = true;

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_DBLCLKS;
    wcex.lpfnWndProc    = WebInspectorProxy::InspectorViewWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(WebInspectorProxy*);
    wcex.hInstance      = instanceHandle();
    wcex.hIcon          = 0;
    wcex.hCursor        = ::LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground  = 0;
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = kWebKit2InspectorWindowClassName;
    wcex.hIconSm        = 0;

    return !!::RegisterClassEx(&wcex);
}

LRESULT CALLBACK WebInspectorProxy::InspectorViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LONG_PTR longPtr = ::GetWindowLongPtr(hWnd, 0);
    
    if (WebInspectorProxy* inspectorView = reinterpret_cast<WebInspectorProxy*>(longPtr))
        return inspectorView->wndProc(hWnd, message, wParam, lParam);

    if (message == WM_CREATE) {
        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);

        // Associate the WebInspectorProxy with the window.
        ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
        return 0;
    }

    return ::DefWindowProc(hWnd, message, wParam, lParam);
}

void WebInspectorProxy::windowReceivedMessage(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
{
    ASSERT(m_isAttached);

    switch (msg) {
    case WM_WINDOWPOSCHANGING:
        onWebViewWindowPosChangingEvent(wParam, lParam);
        break;
    default:
        break;
    }
}

LRESULT WebInspectorProxy::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult = 0;
    bool handled = true;

    switch (message) {
    case WM_SIZE:
        lResult = onSizeEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_GETMINMAXINFO:
        lResult = onMinMaxInfoEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SETFOCUS:
        lResult = onSetFocusEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_CLOSE:
        lResult = onCloseEvent(hWnd, message, wParam, lParam, handled);
        break;
    default:
        handled = false;
        break;
    }

    if (!handled)
        lResult = ::DefWindowProc(hWnd, message, wParam, lParam);

    return lResult;
}

LRESULT WebInspectorProxy::onSizeEvent(HWND, UINT, WPARAM, LPARAM, bool&)
{
    RECT rect;
    ::GetClientRect(m_inspectorWindow, &rect);

    ::SetWindowPos(m_inspectorView->window(), 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);

    return 0;
}

LRESULT WebInspectorProxy::onSetFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool&)
{    
    ::SetFocus(m_inspectorView->window());

    return 0;
}

LRESULT WebInspectorProxy::onMinMaxInfoEvent(HWND, UINT, WPARAM, LPARAM lParam, bool&)
{
    MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam);
    POINT size = {minimumWindowWidth, minimumWindowHeight};
    info->ptMinTrackSize = size;

    return 0;
}

LRESULT WebInspectorProxy::onCloseEvent(HWND, UINT, WPARAM, LPARAM, bool&)
{
    ::ShowWindow(m_inspectorWindow, SW_HIDE);
    close();

    return 0;
}

void WebInspectorProxy::onWebViewWindowPosChangingEvent(WPARAM wParam, LPARAM lParam)
{
    WINDOWPOS* windowPos = reinterpret_cast<WINDOWPOS*>(lParam);

    if (windowPos->flags & SWP_NOSIZE)
        return;

    HWND inspectorWindow = m_inspectorView->window();

    RECT inspectorRect;
    ::GetClientRect(inspectorWindow, &inspectorRect);
    unsigned inspectorHeight = inspectorRect.bottom - inspectorRect.top;

    RECT parentRect;
    ::GetClientRect(::GetParent(inspectorWindow), &parentRect);
    inspectorHeight = InspectorFrontendClientLocal::constrainedAttachedWindowHeight(inspectorHeight, parentRect.bottom - parentRect.top);

    windowPos->cy -= inspectorHeight;

    ::SetWindowPos(inspectorWindow, 0, windowPos->x, windowPos->y + windowPos->cy, windowPos->cx, inspectorHeight, SWP_NOZORDER);
}

WebPageProxy* WebInspectorProxy::platformCreateInspectorPage()
{
    ASSERT(!m_inspectorView);
    ASSERT(!m_inspectorWindow);

    RECT initialRect = { 0, 0, initialWindowWidth, initialWindowHeight };
    m_inspectorView = WebView::create(initialRect, m_page->process()->context(), inspectorPageGroup(), 0);

    return m_inspectorView->page();
}

void WebInspectorProxy::platformOpen()
{
    registerInspectorViewWindowClass();

    m_inspectorWindow = ::CreateWindowEx(0, kWebKit2InspectorWindowClassName, 0, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
        0, 0, initialWindowWidth, initialWindowHeight, 0, 0, instanceHandle(), this);
    ASSERT(::IsWindow(m_inspectorWindow));

    m_inspectorView->setParentWindow(m_inspectorWindow);

    if (m_isAttached)
        platformAttach();
    else
        ::ShowWindow(m_inspectorWindow, SW_SHOW);
}

void WebInspectorProxy::platformDidClose()
{
    ASSERT(!m_isAttached);
    ASSERT(!m_isVisible || m_inspectorWindow);
    ASSERT(!m_isVisible || m_inspectorView);

    if (m_inspectorWindow) {
        ASSERT(::IsWindow(m_inspectorWindow));
        ::DestroyWindow(m_inspectorWindow);
    }

    m_inspectorWindow = 0;
    m_inspectorView = 0;
}

void WebInspectorProxy::platformBringToFront()
{
    // FIXME: this will not bring a background tab in Safari to the front, only its window.
    HWND parentWindow = m_isAttached ? ::GetAncestor(m_page->nativeWindow(), GA_ROOT) : m_inspectorWindow;
    if (!parentWindow)
        return;

    ASSERT(::IsWindow(parentWindow));
    ::SetWindowPos(parentWindow, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}

bool WebInspectorProxy::platformIsFront()
{
    notImplemented();
    return false;
}

void WebInspectorProxy::platformInspectedURLChanged(const String& urlString)
{
    // FIXME: this should be made localizable once WebKit2 supports it. <rdar://problem/8728860>
    String title = makeString("Web Inspector ", static_cast<UChar>(0x2014), ' ', urlString);
    ::SetWindowTextW(m_inspectorWindow, title.charactersWithNullTermination());
}

unsigned WebInspectorProxy::platformInspectedWindowHeight()
{
    HWND inspectedWindow = m_page->nativeWindow();

    RECT inspectedWindowRect;
    ::GetWindowRect(inspectedWindow, &inspectedWindowRect);

    return static_cast<unsigned>(inspectedWindowRect.bottom - inspectedWindowRect.top);
}

void WebInspectorProxy::platformAttach()
{
    HWND webViewWindow = m_page->nativeWindow();
    HWND parentWindow = ::GetParent(webViewWindow);

    WindowMessageBroadcaster::addListener(webViewWindow, this);
    m_inspectorView->setParentWindow(parentWindow);
    ::ShowWindow(m_inspectorWindow, SW_HIDE);

    ::PostMessage(parentWindow, WM_SIZE, 0, 0);
}

void WebInspectorProxy::platformDetach()
{
    HWND webViewWindow = m_page->nativeWindow();
    WindowMessageBroadcaster::removeListener(webViewWindow, this);

    m_inspectorView->setParentWindow(m_inspectorWindow);

    if (m_isVisible)
        ::ShowWindow(m_inspectorWindow, SW_SHOW);

    // Send the detached inspector window and the WebView's parent window WM_SIZE messages
    // to have them re-layout correctly.
    ::PostMessage(m_inspectorWindow, WM_SIZE, 0, 0);
    ::PostMessage(::GetParent(webViewWindow), WM_SIZE, 0, 0);
}

void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned height)
{
    if (!m_isAttached)
        return;

    HWND inspectedWindow = m_page->nativeWindow();
    HWND parentWindow = ::GetParent(inspectedWindow);

    RECT parentWindowRect;
    ::GetWindowRect(parentWindow, &parentWindowRect);

    RECT inspectedWindowRect;
    ::GetWindowRect(inspectedWindow, &inspectedWindowRect);

    int totalHeight = parentWindowRect.bottom - parentWindowRect.top;
    int webViewWidth = inspectedWindowRect.right - inspectedWindowRect.left;

    POINT inspectedWindowOrigin = { inspectedWindowRect.left, inspectedWindowRect.top };
    ::ScreenToClient(parentWindow, &inspectedWindowOrigin);

    HWND inspectorWindow = m_inspectorView->window();
    ::SetWindowPos(inspectorWindow, 0, inspectedWindowOrigin.x, totalHeight - height, webViewWidth, height, SWP_NOZORDER);

    // We want to set the inspected web view height to the totalHeight, because the height adjustment
    // of the inspected WebView happens in onWindowPosChanging, not here.
    ::SetWindowPos(inspectedWindow, 0, inspectedWindowOrigin.x, inspectedWindowOrigin.y, webViewWidth, totalHeight, SWP_NOZORDER);

    ::RedrawWindow(inspectorWindow, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW); 
    ::RedrawWindow(inspectedWindow, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
}

String WebInspectorProxy::inspectorPageURL() const
{
    RetainPtr<CFURLRef> htmlURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle(), CFSTR("inspector"), CFSTR("html"), CFSTR("inspector")));
    if (!htmlURLRef)
        return String();

    return String(CFURLGetString(htmlURLRef.get()));
}

String WebInspectorProxy::inspectorBaseURL() const
{
    // Web Inspector uses localized strings, so it's not contained within inspector directory.
    RetainPtr<CFURLRef> htmlURLRef(AdoptCF, CFBundleCopyResourcesDirectoryURL(webKitBundle()));
    if (!htmlURLRef)
        return String();

    return String(CFURLGetString(htmlURLRef.get()));
}

} // namespace WebKit

#endif // ENABLE(INSPECTOR)
