#ifndef WINDOW_H
#define WINDOW_H

#include <memory>
#include <utility>
#include <SDL.h>
#include "Font.h"
#include "Buffer.h"
#include "GL.h"

class Window
{
public:
    bool create(std::shared_ptr<Buffer> buffer);
    void run_event_loop();

protected:
    enum
    {
        CURSOR_LEFT,
        CURSOR_RIGHT,
        CURSOR_UP,
        CURSOR_DOWN,
        CURSOR_SOL,
        CURSOR_EOL,
    };

    enum
    {
        KEYMOD_CTRL  = 0x10000,
        KEYMOD_ALT   = 0x20000,
        KEYMOD_SHIFT = 0x40000,
        KEYMOD_GUI   = 0x80000,
    };

    void resize();
    void redraw();
    void draw_cursor(int screen_column, int screen_row, bool insert_mode);
    void colrow_to_xy(int col, int row, int * x, int * y);
    void handle_event(SDL_Event & event);
    void handle_keysym(uint32_t keysym);
    void handle_keyval(uint32_t keyval);
    void cursor_move(int which);
    void draw_buffer();
    void draw_buffer_line(int screen_row, const GapBuffer::Cursor & cursor);
    void draw_buffer_character(int screen_column, int screen_row, uint32_t character);
    void update_cursor_row();
    void draw_status_bar();
    uint32_t get_keyval(SDL_Keycode keysym);
    uint32_t get_shifted(uint32_t keysym);
    int screen_rows_below_cursor(int stop_at);
    int screen_rows_above_cursor(int stop_at);
    int effective_scroll_offset()
    {
        return std::min(m_scroll_offset, (m_rows - 1) / 2);
    }

    SDL_Window * m_window;
    bool m_exit_requested;
    int m_width;
    int m_height;

    Font m_font;
    int m_columns;
    int m_rows;
    int m_cursor_row;
    int m_scroll_offset;
    uint32_t m_target_column;

    std::shared_ptr<Buffer> m_buffer;
    std::shared_ptr<GapBuffer::Cursor> m_cursor;

    std::shared_ptr<GL> m_gl;

    Uint16 m_keymod;
};

#endif
