/*
 * 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/process.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 {
                        bool handled = webView.handleKeyEvent(keycode, ch, pressed);
                        if (!handled) {
                            if (keycode == HID_USAGE_KEY_DOWN) {
                                webView.scrollDownOneLine();
                            } else if (keycode == HID_USAGE_KEY_UP) {
                                webView.scrollUpOneLine();
                            }
                        }
                    }
                }
            }
        }
#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;
}
