/*
 * 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 <fcntl.h>
#include <math.h>

#include <assert.h>
#include <dirent.h>
#include <hid/hid.h>
#include <hid/usages.h>
#include <zircon/device/console.h>
#include <zircon/device/display.h>
#include <zircon/pixelformat.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <lib/fdio/io.h>
#include <stdlib.h>
#include <sys/stat.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;

// TODO: replace the hard coded device 000 with some method of getting
//       the first device.
constexpr char kVirtualConsole[] = "/dev/class/framebuffer/000";

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 = fdio_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 = fdio_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 = fdio_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;

    zx_status_t status = zx_vmar_map(zx_vmar_root_self(),
        ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, frameBuffer.vmo, 0, size, &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 ZX_PIXEL_FORMAT_RGB_565:
        format = CAIRO_FORMAT_RGB16_565;
        break;
    case ZX_PIXEL_FORMAT_RGB_x888:
        format = CAIRO_FORMAT_RGB24;
        break;
    case ZX_PIXEL_FORMAT_ARGB_8888:
        format = CAIRO_FORMAT_ARGB32;
        break;
    case ZX_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

    mkdir("/data/web_view", 0777);

    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 (pressed && controlDown && ch == '+') {
                        float newScale = webScale * kZoomMultiplierRatio;
                        if (newScale < kMaximumZoomMultiplier) {
                            webScale = newScale;
                            webView.setPageAndTextZoomFactors(webScale, 1);
                        }
                    } else if (pressed && controlDown && ch == '-') {
                        float newScale = webScale / kZoomMultiplierRatio;
                        if (newScale > kMinimumZoomMultiplier) {
                            webScale = newScale;
                            webView.setPageAndTextZoomFactors(webScale, 1);
                        }
                    } else if (pressed && controlDown && keycode == HID_USAGE_KEY_LEFTBRACE) {
                        webView.goBack();
                    } else if (pressed && controlDown && keycode == HID_USAGE_KEY_RIGHTBRACE) {
                        webView.goForward();
                    } else if (pressed && controlDown && keycode == HID_USAGE_KEY_R) {
                        webView.reload();
                    } else if (pressed && controlDown && keycode == HID_USAGE_KEY_D) {
                        webView.deleteAllCookies();
                    } else {
                        bool handled = webView.handleKeyEvent(keycode, ch, pressed, false);
                        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 = fdio_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;
}
