#pragma once
#include <string>
#include <termbox.h>
#include "Canvas.h"
#include "File.h"
#include "Input.h"
#include "History.h"
class Action;
class Line;
class Buffer : public File, public InputHandler {
private:
/// First visible line number, starts at 1 (just like the gutter)
/// If the user scrolled down, this number will be higher
uint m_first_visible_line_nb = 1;
/// Currently selected line number - starts at 1
uint current_line_nb = 1;
/// Dimensions of the buffer on the screen
Canvas m_canvas;
/// Event history - contains undo/redo events
History m_history;
/// Current character in the file
uint m_absolute_position = 0;
/// Current character in the line
uint m_relative_position = 0;
void set_relative_position(uint new_x);
public:
Buffer(std::string filename) : File(filename)
{
// Assume initial buffer height for scrolling
m_canvas = Canvas{ 0, 0, tb_width(), tb_height() };
// Scroll to the end of the file
scroll(1);
}
// String used for debugging - prints in status bar
std::wstring force = L"";
Line current_line();
/// Draw the buffer on the screen
void draw(Canvas canvas);
/// Handle keypresses
virtual bool handle_key(tb_event* ev) override;
/// Handle mouse actions
virtual bool handle_mouse(tb_event* ev) override;
/// Returns max width of a line
int max_line_width();
bool move_down();
bool move_to(uint line_number);
bool move_to(uint line_number, uint column);
bool move_up();
bool erase_backwards(bool log_events);
bool erase_forwards(bool log_events);
/// @returns the first line visible on screen (top)
uint first_visible_line_nb();
/// Get buffer on-screen dimensions
Canvas get_canvas();
/// Returns current line number (starts at 1)
uint get_current_line_nb() { return current_line_nb; }
/// @returns the x coordinate of the cursor
uint get_visible_x();
/// @returns the y coordinate of the cursor
uint get_visible_y();
uint get_x() { return m_relative_position; }
void set_x(uint new_x) { set_relative_position(new_x); }
// Override Editable's insert to handle newlines
void insert(const wchar_t c, bool log_events);
void insert(const wchar_t* str, bool log_events);
/// Logs the given action to allow undo/redo
void log_action(Action* action);
/// Move to the given screen coordinates
void screen_to(uint x, uint y);
/// Update m_first_visible_line_nb
void scroll(uint old_current_line_nb);
/// Set [modified] and update syntax highlighting
void update();
/// Set [modified] and update syntax highlighting for specific line
void update(Line *l);
};