/*
 * 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_old(zx_vmar_root_self(), 0, frameBuffer.vmo, 0, size,
        ZX_VM_FLAG_PERM_READ | ZX_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 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;
}
