/*
 * Copyright (C) 2006, 2007, 2014, 2015 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.
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE 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 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.
 */

#ifndef WebInspectorClient_h
#define WebInspectorClient_h

#include <JavaScriptCore/InspectorFrontendChannel.h>
#include <WebCore/COMPtr.h>
#include <WebCore/InspectorClient.h>
#include <WebCore/InspectorFrontendClientLocal.h>
#include <WebCore/WindowMessageListener.h>
#include <windows.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>

namespace WebCore {
class CertificateInfo;
class Page;
}

class WebInspectorFrontendClient;
class WebNodeHighlight;
class WebView;

class WebInspectorClient final : public WebCore::InspectorClient, public Inspector::FrontendChannel {
    WTF_MAKE_FAST_ALLOCATED;
public:
    explicit WebInspectorClient(WebView*);

    // InspectorClient API.
    void inspectedPageDestroyed() override;

    Inspector::FrontendChannel* openLocalFrontend(WebCore::InspectorController*) override;
    void bringFrontendToFront() override;

    void highlight() override;
    void hideHighlight() override;

    // FrontendChannel API.
    ConnectionType connectionType() const override { return ConnectionType::Local; }
    void sendMessageToFrontend(const WTF::String&) override;

    bool inspectorStartsAttached();
    void setInspectorStartsAttached(bool);
    void deleteInspectorStartsAttached();

    bool inspectorAttachDisabled();
    void setInspectorAttachDisabled(bool);
    void deleteInspectorAttachDisabled();

    void releaseFrontend();

    WebInspectorFrontendClient* frontendClient() { return m_frontendClient.get(); }

    void updateHighlight();

private:
    virtual ~WebInspectorClient();
    std::unique_ptr<WebCore::InspectorFrontendClientLocal::Settings> createFrontendSettings();

    WebView* m_inspectedWebView;
    WebCore::Page* m_frontendPage;
    std::unique_ptr<WebInspectorFrontendClient> m_frontendClient;
    HWND m_inspectedWebViewHandle;
    HWND m_frontendHandle;

    std::unique_ptr<WebNodeHighlight> m_highlight;
};

class WebInspectorFrontendClient final : public WebCore::InspectorFrontendClientLocal, WebCore::WindowMessageListener {
    WTF_MAKE_FAST_ALLOCATED;
public:
    WebInspectorFrontendClient(WebView* inspectedWebView, HWND inspectedWebViewHwnd, HWND frontendHwnd, const COMPtr<WebView>& frotnendWebView, HWND frontendWebViewHwnd, WebInspectorClient*, std::unique_ptr<Settings>);
    virtual ~WebInspectorFrontendClient();

    // InspectorFrontendClient API.
    void frontendLoaded() override;

    WTF::String localizedStringsURL() override;

    void bringToFront() override;
    void closeWindow() override;
    void reopen() override;
    void resetState() override;

    void setAttachedWindowHeight(unsigned) override;
    void setAttachedWindowWidth(unsigned) override;

    void setSheetRect(const WebCore::FloatRect&) override;

    void inspectedURLChanged(const WTF::String& newURL) override;
    void showCertificate(const WebCore::CertificateInfo&) override;

    // InspectorFrontendClientLocal API.
    void attachWindow(DockSide) override;
    void detachWindow() override;

    void destroyInspectorView();

private:
    void closeWindowWithoutNotifications();
    void showWindowWithoutNotifications();

    void updateWindowTitle();

    LRESULT onGetMinMaxInfo(WPARAM, LPARAM);
    LRESULT onSize(WPARAM, LPARAM);
    LRESULT onClose(WPARAM, LPARAM);
    LRESULT onSetFocus();

    void windowReceivedMessage(HWND, UINT message, WPARAM, LPARAM) override;

    void onWebViewWindowPosChanging(WPARAM, LPARAM);

    WebView* m_inspectedWebView;
    HWND m_inspectedWebViewHwnd;
    HWND m_frontendHwnd;
    WebInspectorClient* m_inspectorClient;
    COMPtr<WebView> m_frontendWebView;
    HWND m_frontendWebViewHwnd;

    bool m_attached;

    WTF::String m_inspectedURL;
    bool m_destroyingInspectorView;

    friend LRESULT CALLBACK WebInspectorWndProc(HWND, UINT, WPARAM, LPARAM);
};

#endif // !defined(WebInspectorClient_h)
