#ifndef __GRAMSCII_H__
#define __GRAMSCII_H__

#include <stdio.h>
#include <termios.h>
#include <unistd.h>



/** constants **/

#define MOVE   0x00
#define BOX    0x01
#define ARROW  0x02
#define TEXT   0x04
#define DEL    0x08
#define VIS    0x10

#define DIR_N  0x00
#define DIR_R  0x01
#define DIR_U  0x02
#define DIR_D  0x04
#define DIR_L  0x08

#define DIR_HOR (DIR_R | DIR_L)
#define DIR_VER (DIR_D | DIR_U)


#define NOFIX 0x0
#define FIX   0x1

#define BG        ' '
#define PTR       '+'
#define UND       '_'
#define ARR_L     '<'
#define ARR_R     '>'
#define ARR_U     '^'
#define ARR_D     'v'

#define HOME   0x01
#define END    0x02
#define MIDDLE 0x04

#define VIDEO_NRM 0
#define VIDEO_REV 7 

#define CUR 0x01
#define LST 0x02

/** types **/

typedef struct{
	int sz;/* allocated size*/
	int n;/* line number */
	int lst;/* last visible char (before the first \0) */
	char *s;
} line_t;

typedef struct{
	int sz;/* allocated size */
	int num;/* number of lines stored */
	line_t *l;
} lineset_t;


/** MACROS **/

#define MIN(x,y)  (x) < (y) ? (x) : (y)
#define MAX(x,y)  (x) > (y) ? (x) : (y)

#define progr_x(d) ((d) == DIR_L ? -1 : (d) == DIR_R ? 1 : 0)
#define progr_y(d) ((d) == DIR_U ? -1 : (d) == DIR_D ? 1 : 0)

#define DEBUG 1

/** global variables **/ 

lineset_t screen;
lineset_t cutbuf;
lineset_t *undo;

int undo_sz;
int undo_cur;
int undo_lst;

int WIDTH, HEIGHT;

int mode;
int dir;
int x;
int y;
int step;
int mult;
int force_new;
char cursor;
char corner;

int hlines_sz;
int vlines_sz;
int corners_sz;
int stmarks_sz;
int endmarks_sz;

int cur_hl, cur_vl, cur_corn, cur_start, cur_end;
char line_h;
char line_v;
char mark_st;
char mark_end;

char modified;
char fname[256];

char visual;
char silent;
char autoend;


struct termios t1, t2, t3;

/** screen-related functions **/
void reset_styles();
void redraw();
int move_around(char c, FILE *fc);
void check_bound();
void status_bar();
void show_cursor();
void set_cur(char c);
void update_current();
void set_xy(int _x, int _y, char c);
void draw_xy(int x, int y, char c);
char get_mark(char dir);
void set_video(int v);
char get_key(FILE *fc, char *msg);
void get_string(FILE *fc, char *msg, char *s, int sz);
void erase_box(int x1, int y1, char c);
int is_yes(char c);
void init_screen();
void erase_line(int i);
void erase_screen();
void go_to(int where);
void crop_to_nonblank();
void erase_blank_lines(int y1, int y2);

/** drawing-related functions **/
int change_style(char c);
void get_text(FILE *fc);
void get_box(FILE *fc);
void get_arrow(FILE *fc);
void erase(FILE *fc);
void visual_box(FILE *fc);
void paste();

/** file-related functions **/
void write_file(FILE *fc);
void check_modified(FILE *fc);
void load_file(FILE *fc);
void new_file(FILE *fc);

/** line-related functions **/

void dump_lines(lineset_t ls, FILE *f);
void alloc_line(line_t *l);
void ensure_line_length(line_t *l, int len);
void ensure_num_lines(lineset_t *ls, int n);
void yank_region(int x1, int y1, int x2, int y2);
void paste_region(int x1, int y1);
void copy_lines_to_ring(int y1, int y2, int which);
void undo_change();
void redo_change();

#endif