// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <assert.h>

#include <gfx/gfx.h>
#include <hid/hid.h>
#include <lib/fdio/vfs.h>
#include <zircon/listnode.h>
#include <zircon/thread_annotations.h>
#include <port/port.h>
#include <stdbool.h>
#include <threads.h>

#include "textcon.h"

#define MAX_COLOR 0xf

#if BUILD_FOR_TEST
zx_status_t vc_init_gfx(gfx_surface* gfx);
#else
zx_status_t vc_init_gfx(zx_handle_t fb_vmo, int32_t width, int32_t height,
                        zx_pixel_format_t format, int32_t stride);
void vc_free_gfx();
#endif

typedef void (*keypress_handler_t)(uint8_t keycode, int modifiers);

zx_status_t new_input_device(int fd, keypress_handler_t handler);

// constraints on status bar tabs
#define MIN_TAB_WIDTH 16
#define MAX_TAB_WIDTH 32

#define STATUS_COLOR_BG 0
#define STATUS_COLOR_DEFAULT 7
#define STATUS_COLOR_ACTIVE 11
#define STATUS_COLOR_UPDATED 10

typedef struct vc {
    char title[MAX_TAB_WIDTH];
    // vc title, shown in status bar
    bool active;
    unsigned flags;

    zx_handle_t gfx_vmo;

    int fd;

    // backing store
    const gfx_font* font;

    vc_char_t* text_buf;
    // text buffer

    // Buffer containing scrollback lines.  This is a circular buffer.
    vc_char_t* scrollback_buf;
    // Maximum number of rows that may be stored in the scrollback buffer.
    unsigned scrollback_rows_max;
    // Number of rows currently stored in the scrollback buffer.
    unsigned scrollback_rows_count;
    // Offset, in rows, of the oldest row in the scrollback buffer.
    unsigned scrollback_offset;

    unsigned rows, columns;
    // screen size
    unsigned charw, charh;
    // size of character cell

    int invy0, invy1;
    // offscreen invalid lines, tracked during textcon drawing

    unsigned cursor_x, cursor_y;
    // cursor
    bool hide_cursor;
    // cursor visibility
    int viewport_y;
    // viewport position, must be <= 0

    uint32_t palette[16];
    uint8_t front_color;
    uint8_t back_color;
    // color

    textcon_t textcon;

    const keychar_t* keymap;

    struct list_node node;
    // for virtual console list

#if !BUILD_FOR_TEST
    port_fd_handler fh;
    zx_handle_t proc;
    bool is_shell;
#endif
} vc_t;

// When VC_FLAG_HASOUTPUT is set, this indicates that there was output to
// the console that hasn't been displayed yet, because this console isn't
// visible.
#define VC_FLAG_HASOUTPUT   (1 << 0)
#define VC_FLAG_FULLSCREEN  (1 << 1)

const gfx_font* vc_get_font();
zx_status_t vc_alloc(vc_t** out, bool special);
void vc_attach_gfx(vc_t* vc);
void vc_free(vc_t* vc);
void vc_flush(vc_t* vc);
void vc_flush_all(vc_t* vc);

// called to re-draw the status bar after
// status-worthy vc or global state has changed
void vc_status_update();

// used by vc_status_invalidate to draw the status bar
void vc_status_clear();
void vc_status_write(int x, unsigned color, const char* text);
void vc_status_commit();

void vc_render(vc_t* vc);
void vc_full_repaint(vc_t* vc);
int vc_get_scrollback_lines(vc_t* vc);
vc_char_t* vc_get_scrollback_line_ptr(vc_t* vc, unsigned row);
void vc_scroll_viewport(vc_t* vc, int dir);
void vc_scroll_viewport_top(vc_t* vc);
void vc_scroll_viewport_bottom(vc_t* vc);
void vc_set_fullscreen(vc_t* vc, bool fullscreen);

ssize_t vc_write(vc_t* vc, const void* buf, size_t count,
                 zx_off_t off);

static inline int vc_rows(vc_t* vc) {
    return vc->flags & VC_FLAG_FULLSCREEN ? vc->rows : vc->rows - 1;
}

// drawing:

void vc_gfx_invalidate_all(vc_t* vc);
void vc_gfx_invalidate_status();
// invalidates a region in characters
void vc_gfx_invalidate(vc_t* vc, unsigned x, unsigned y, unsigned w, unsigned h);
// invalidates a region in pixels
void vc_gfx_invalidate_region(vc_t* vc, unsigned x, unsigned y, unsigned w, unsigned h);
void vc_gfx_draw_char(vc_t* vc, vc_char_t ch, unsigned x, unsigned y,
                      bool invert);

static inline uint32_t palette_to_color(vc_t* vc, uint8_t color) {
    assert(color <= MAX_COLOR);
    return vc->palette[color];
}

extern port_t port;
extern bool g_vc_owns_display;
extern vc_t* g_active_vc;
extern int g_status_width;

void handle_key_press(uint8_t keycode, int modifiers);
void vc_toggle_framebuffer();

zx_status_t vc_create(vc_t** out, bool special);
void vc_destroy(vc_t* vc);
ssize_t vc_write(vc_t* vc, const void* buf, size_t count, zx_off_t off);
zx_status_t vc_set_active(int num, vc_t* vc);
void vc_show_active();

bool vc_display_init(void);

void set_log_listener_active(bool active);
zx_status_t handle_device_dir_event(port_handler_t* ph, zx_signals_t signals,
                                    zx_status_t (*event_handler)(unsigned event, const char* msg));
