/*
 * Copyright 2016 The Fuchsia Authors. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT HOLDERS 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.
 */

#pragma once

#include <functional>
#include <memory>

namespace WebCore {
class GraphicsContext;
class MainFrame;
class Page;
class URL;
class DocumentLoader;
class ResourceRequest;
class ResourceResponse;
}

class WebFrameLoaderClient;
class WebChromeClient;

typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
typedef std::function<std::string(const std::string&)> WebRequestDelegate;

class WebView {
public:
    enum MouseEventKind { kMouseDown,
        kMouseMoved,
        kMouseUp };
    enum TouchEventKind { kTouchDown,
        kTouchMoved,
        kTouchUp };
    ~WebView();

    bool setup(unsigned char* pixelBuffer, int pixelFormat, size_t targetWidth, size_t targetHeight, size_t rowbytes);
    void setFileURL(const std::string& fileUrlString);
    void setURL(const std::string& urlString);

    void reload();

    void goBack();
    void goForward();

    void scrollDownOneLine();
    void scrollUpOneLine();
    void scrollLeftOneLine();
    void scrollRightOneLine();

    void layoutAndPaint();

    void setFocused(bool);
    void setVisible(bool);
    void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);

    void handleMouseEvent(int x, int y, MouseEventKind eventType);
    void handleTouchEvent(uint32_t touchId, int x, int y, TouchEventKind eventType);
    bool handleKeyEvent(uint8_t keycode, uint8_t charValue, bool pressed, bool repeat);

    void setWebRequestDelegate(WebRequestDelegate delegate);
    void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse);

    void iterateEventLoop();

    std::string getTitle();
    bool isMainFrameLoaded();
    std::string getMainDocumentError() const;

    void deleteAllCookies();

    cairo_t* cairoContext() const { return m_cairoContext; }
    cairo_surface_t* cairoSurface() const { return m_cairoSurface; }

private:
    WebRequestDelegate m_webRequestDelegate;

    void setURLInternal(const WebCore::URL& url);
    void scrollInternal(uint8_t direction, uint8_t granularity);

    WebCore::Page* m_page = { nullptr };
    cairo_t* m_cairoContext = { nullptr };
    cairo_surface_t* m_cairoSurface = { nullptr };
    size_t m_pageWidth;
    size_t m_pageHeight;
    WebFrameLoaderClient* m_frameLoaderClient = { nullptr };
    WebChromeClient* m_chromeClient = { nullptr };
    bool fControl = false;
    bool fShift = false;
};
