/*
 * 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.
 */

#include "cmakeconfig.h"

#include <algorithm>
#include <chrono>
#include <iostream>
#include <map>

#include <cairo/cairo.h>

#include <fontconfig/fontconfig.h>

#include <fcntl.h>
#include <math.h>

#include <assert.h>
#include <dirent.h>
#include <hid/hid.h>
#include <hid/usages.h>
#include <magenta/device/console.h>
#include <magenta/device/display.h>
#include <magenta/pixelformat.h>
#include <magenta/syscalls.h>
#include <magenta/types.h>
#include <mxio/io.h>
#include <stdlib.h>

#include <WebKit/fuchsia/WebView.h>

#include "FuchsiaCursor.h"
#include "FuchsiaInputHandler.h"

using namespace WebCore;

using std::endl;
using std::cout;
using std::cerr;

using Fuchsia::Event;
using Fuchsia::MouseEvent;
using Fuchsia::KeyEvent;

#define USE_INPUT 1

constexpr float kMinimumZoomMultiplier = 0.5f;
constexpr float kMaximumZoomMultiplier = 3.0f;
constexpr float kZoomMultiplierRatio = 1.2f;

constexpr char kVirtualConsole[] = "/dev/class/console/vc";

int main(int argc, char** argv)
{
    std::string urlToOpen = "file:///system/docs/input.html";

    if (argc > 1) {
        urlToOpen = argv[1];
        if (urlToOpen[0] == '/') {
            urlToOpen = "file://" + urlToOpen;
        }
    }

    cout << "Welcome to MiniBrowser" << endl;

    int fd = open(kVirtualConsole, O_RDWR);
    if (fd < 0) {
        cout << "Failed to open frame buffer:" << errno << endl;
        return -1;
    }

    ssize_t result = mxio_ioctl(fd, IOCTL_CONSOLE_SET_ACTIVE_VC, NULL, 0, NULL, 0);
    if (result < 0) {
        cout << "could not set active console: " << result << endl;
        cout << "press f1/f2 to switch consoles" << endl;
    }

    ioctl_display_get_fb_t frameBuffer;
    result = mxio_ioctl(fd, IOCTL_DISPLAY_GET_FB, nullptr, 0, &frameBuffer,
        sizeof(frameBuffer));

    if (result < 0) {
        cout << "DISPLAY_OP_GET_FB failed.";
        close(fd);
        return -1;
    }

#if 1
    uint32_t beFull = 1;
    ssize_t resultFs = mxio_ioctl(fd, IOCTL_DISPLAY_SET_FULLSCREEN, &beFull, sizeof(beFull), NULL, 0);
    if (resultFs < 0) {
        cout << "could not set full screen: " << resultFs << endl;
    }
#endif

    size_t rowbytes = frameBuffer.info.stride * frameBuffer.info.pixelsize;
    size_t size = rowbytes * frameBuffer.info.height;

    uintptr_t buffer = 0;

    mx_status_t status = mx_vmar_map(mx_vmar_root_self(), 0, frameBuffer.vmo, 0, size,
        MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE, &buffer);

    if (status < 0) {
        cout << "Cannot map frame buffer " << status << endl;
        return -1;
    }

    auto cursorSurface = cairo_image_surface_create_from_png("/system/docs/cursor32.png");
    int w = cairo_image_surface_get_width(cursorSurface);
    int h = cairo_image_surface_get_height(cursorSurface);
    cout << "cursor size is " << w << ", " << h << endl;

    cairo_format_t format = CAIRO_FORMAT_INVALID;
    switch (frameBuffer.info.format) {
    case MX_PIXEL_FORMAT_RGB_565:
        format = CAIRO_FORMAT_RGB16_565;
        break;
    case MX_PIXEL_FORMAT_RGB_x888:
        format = CAIRO_FORMAT_RGB24;
        break;
    case MX_PIXEL_FORMAT_ARGB_8888:
        format = CAIRO_FORMAT_ARGB32;
        break;
    case MX_PIXEL_FORMAT_MONO_1:
        format = CAIRO_FORMAT_A1;
        break;
    case MX_PIXEL_FORMAT_MONO_8:
        format = CAIRO_FORMAT_A8;
        break;
    default:
        cout << "Unsupported pixel format " << frameBuffer.info.format << endl;
        return -1;
    }

#if USE_INPUT
    Fuchsia::InputHandler inputHandler;
    inputHandler.openDevices();
    std::map<int, Fuchsia::Cursor> cursors;
#endif

    WebView webView;
    webView.setup(reinterpret_cast<unsigned char*>(buffer), frameBuffer.info.format, frameBuffer.info.width, frameBuffer.info.height, rowbytes);
    webView.setURL(urlToOpen);

    webView.setFocused(true);
    webView.setVisible(true);
    bool shiftDown = false;
    bool controlDown = false;
    float webScale = 1.0;

    while (true) {
#if USE_INPUT
        if (inputHandler.hasEvents()) {
            auto events = inputHandler.getPendingEvents();
            for (const auto& oneEvent : events) {
                if (oneEvent->type() == Event::kMouse) {
                    MouseEvent* mouseEvent = static_cast<MouseEvent*>(oneEvent.get());
                    auto cursorP = cursors.find(mouseEvent->eventSource());
                    if (cursorP == cursors.end()) {
                        auto insertResult = cursors.insert(std::make_pair(mouseEvent->eventSource(),
                            Fuchsia::Cursor(frameBuffer.info.width, frameBuffer.info.height)));
                        cursorP = insertResult.first;
                    }
                    auto actions = cursorP->second.handleEvent(*mouseEvent);
                    for (const auto& actionPair : actions) {
                        if (actionPair.first == 0) {
                            if (actionPair.second == Fuchsia::Cursor::ButtonAction::kDown) {
                                webView.handleMouseEvent(cursorP->second.getX(), cursorP->second.getY(), WebView::kMouseDown);
                            } else if (actionPair.second == Fuchsia::Cursor::ButtonAction::kUp) {
                                webView.handleMouseEvent(cursorP->second.getX(), cursorP->second.getY(), WebView::kMouseUp);
                            } else {
                                webView.handleMouseEvent(cursorP->second.getX(), cursorP->second.getY(), WebView::kMouseMoved);
                            }
                        }
                    }
                } else if (oneEvent->type() == Event::kKey) {
                    KeyEvent* keyEvent = static_cast<KeyEvent*>(oneEvent.get());
                    uint8_t keycode = keyEvent->keycode();
                    bool pressed = keyEvent->pressed();
                    if (keycode == HID_USAGE_KEY_LEFT_SHIFT || keycode == HID_USAGE_KEY_RIGHT_SHIFT) {
                        shiftDown = pressed;
                    } else if (keycode == HID_USAGE_KEY_LEFT_CTRL || keycode == HID_USAGE_KEY_RIGHT_CTRL) {
                        controlDown = pressed;
                    }
                    if (controlDown && keycode == HID_USAGE_KEY_C) {
                        cout << "Exit requested." << endl;
                        exit(0);
                    }
                    uint8_t ch = hid_map_key(keycode, shiftDown, qwerty_map);
                    if (controlDown && ch == '+') {
                        float newScale = webScale * kZoomMultiplierRatio;
                        if (newScale < kMaximumZoomMultiplier) {
                            webScale = newScale;
                            webView.setPageAndTextZoomFactors(webScale, 1);
                        }
                    } else if (controlDown && ch == '-') {
                        float newScale = webScale / kZoomMultiplierRatio;
                        if (newScale > kMinimumZoomMultiplier) {
                            webScale = newScale;
                            webView.setPageAndTextZoomFactors(webScale, 1);
                        }
                    } else if (controlDown && keycode == HID_USAGE_KEY_LEFTBRACE) {
                        webView.goBack();
                    } else if (controlDown && keycode == HID_USAGE_KEY_RIGHTBRACE) {
                        webView.goForward();
                    } else {
                        webView.handleKeyEvent(keycode, ch, pressed);
                    }
                }
            }
        }
#endif
        webView.iterateEventLoop();
        webView.layoutAndPaint();
#if USE_INPUT
        for (const auto& cursor : cursors) {
            cairo_set_source_surface(webView.cairoContext(), cursorSurface, cursor.second.getX(), cursor.second.getY());
            cairo_paint(webView.cairoContext());
        }
#endif
        result = mxio_ioctl(fd, IOCTL_DISPLAY_FLUSH_FB, nullptr, 0, nullptr, 0);
        if (result < 0) {
            cout << "IOCTL_DISPLAY_FLUSH_FB failed.";
            close(fd);
            return -1;
        }
    }
    return 0;
}
