#ifndef WINDOW_H
#define WINDOW_H

#include <memory>
#include <utility>
#include <vector>
#include "Font.h"
#include "Buffer.h"
#include "GL.h"
#include "EncodedString.h"
#include "CommandParser.h"
#include "Jtk.h"
#include "Command.h"

class BufferPane;

class Window
{
public:
    enum class ScrollMode : uint8_t
    {
        ONE_LINE,
        WHEEL,
        HALF_SCREEN,
        WHOLE_SCREEN,
    };

    enum class EnterInsertModeMode : uint8_t
    {
        START_OF_CHAR,
        END_OF_CHAR,
        START_OF_LINE,
        END_OF_LINE,
        NEW_LINE_BEFORE,
        NEW_LINE_AFTER,
    };

    bool create(std::shared_ptr<Buffer> buffer);
    void run_event_loop();
    void request_redraw() { m_redraw_requested = true; }
    std::shared_ptr<Font> font() const { return m_font; }
    std::shared_ptr<GL> gl() const { return m_gl; }

protected:
    void resize(size_t width, size_t height);
    void redraw();
    void handle_event(Jtk_Event & event);
    void handle_keypress(uint32_t keyval);
    void change_focus(std::shared_ptr<BufferPane> buffer_pane);
    void set_window_icon();
    void handle_command(const EncodedString & command);
    void evaluate_command_input();
    void execute_command(const Command & command);
    void draw_command_input();

    void command_write_file(const CommandParser & cp);
    void command_quit(const CommandParser & cp);

    void * m_window;
    bool m_exit_requested;
    bool m_redraw_requested;
    int m_width;
    int m_height;
    int m_command_buffer_screen_rows;

    std::shared_ptr<Font> m_font;
    uint32_t m_target_column;

    std::shared_ptr<GL> m_gl;

    std::shared_ptr<BufferPane> m_buffer_pane;
    std::shared_ptr<BufferPane> m_focused_buffer_pane;
    std::shared_ptr<Buffer> m_command_buffer;
    std::shared_ptr<BufferPane> m_command_buffer_pane;
    std::vector<uint32_t> m_command_input;
    bool m_command_invalid;
};

#endif
