#ifndef _draw_h
#define _draw_h

//RECT is apparently used in windef.h
#ifdef ALLEGRO_WINDOWS
#define RECT RECTANGLE
#endif

typedef enum drawcommand
{
	DRAW_SPRITE = 0,
	DRAW_TINTED_SPRITE,
	ROTATE_SPRITE,
	ROTATE_TINTED_SPRITE,
	STRETCH_SPRITE,
	BLIT_CLIPPED,
	TEXTOUT_EX,
	TEXTOUT_CENTRE_EX,
	CLIPPED_TEXTOUT_EX,
	MULTILINE_TEXTOUT_EX,
	CIRCLEFILL,
	ADDITIVE_CIRCLEFILL,
	CIRCLEFILL_GRADIENT,
	RECT,
	RECTFILL,
	RECTFILL_GRADIENT,
	RECTROUNDED,
	DISCFILL,
	MENUBACK,
	PUTPIXEL,
	MAPBLIP,
	HLINE,
	VLINE,
	LINESTRIP,
	CLEAR_TO_COLOR,
	SET_BLENDER_NORMAL,
	SET_BLENDER_ADDITIVE,
	TEXTOUT_RIGHT_EX,
	CLIPBOX_TEXTOUT_EX,
	SET_ANTIALIASING
} drawcommand;

typedef struct drawthing
{
	drawthing() :
		type (CLEAR_TO_COLOR),
		angle (0),
		x (0),
		y (0),
		w (0),
		h (0),
		color (0),
		cx (0),
		cy (0),
		alpha (0),
		r (0),
		str (""),
		bmp (0),
		fnt (0),
		l (0)
	{}
	
	drawthing(const drawthing &d) :
		type (d.type),
		angle (d.angle),
		x (d.x),
		y (d.y),
		w (d.w),
		h (d.h),
		color (d.color),
		cx (d.cx),
		cy (d.cy),
		alpha (d.alpha),
		r (d.r),
		str (d.str),
		bmp (d.bmp),
		fnt (d.fnt),
		l (d.l)
	{
		colors[0] = d.colors[0];
		colors[1] = d.colors[1];
		colors[2] = d.colors[2];
		colors[3] = d.colors[3];
	}
		
	drawthing &operator=(const drawthing &d)
	{
		type = d.type;
		angle = d.angle;
		x = d.x;
		y = d.y;
		w = d.w;
		h = d.h;
		color = d.color;
		cx = d.cx;
		cy = d.cy;
		alpha = d.alpha;
		r = d.r;
		colors[0] = d.colors[0];
		colors[1] = d.colors[1];
		colors[2] = d.colors[2];
		colors[3] = d.colors[3];
		str = d.str;
		bmp = d.bmp;
		fnt = d.fnt;
		l = d.l;
		
		return *this;
	}
	
	drawcommand type;
	short angle;  // 0 to 255
	int x, y, w, h, color, cx, cy;
	float alpha; // 0.0 to 1.0
	float r;
	ol::Rgba colors[4];
	string str;
	ol::Bitmap *bmp;
	ol::TextRenderer *fnt;
	ol::LineStrip *l;
} drawthing;

typedef struct bitmapdat
{
	bitmapdat();
	vector<ol::Bitmap*> b;
	vector<string> filenames;
	void load(DATAFILE *dat);
	void load(const char *path);
	void draw(int i, int x, int y, float a = 1.0);
	void draw_fullscreen(int i, float a = 1.0);
	void sort_by_name();
	void destroy();
	string name;
	int size;
	ol::Bitmap *bmp(int i) const;
} bitmapdat;

extern vector<drawthing> drawqueue;

void buffer_draw_sprite(ol::Bitmap *abitmap, int ax, int ay, float alpha = 1.0);
void buffer_draw_twotint_sprite(ol::Bitmap *abitmap, int ax, int ay, ol::Rgba color1, ol::Rgba color2, float alpha = 1.0);
void buffer_draw_tinted_sprite(ol::Bitmap *abitmap, int ax, int ay, ol::Rgba color, float alpha = 1.0);
void buffer_rotate_sprite(ol::Bitmap *abitmap, int ax, int ay, int aangle, float alpha = 1.0);
void buffer_rotate_tinted_sprite(ol::Bitmap *abitmap, int ax, int ay, int aangle, ol::Rgba acolor, float alpha = 1.0);
void buffer_stretch_sprite(ol::Bitmap *abitmap, int ax, int ay, int aw, int ah, float alpha = 1.0);
void buffer_blit_clipped(ol::Bitmap *abitmap, int ax, int ay, int sx, int sy, int aw, int ah, float alpha = 1.0);

void buffer_textout_ex(ol::TextRenderer &afont, const string amessage, int ax, int ay, int acolor, float alpha = 1.0);
void buffer_textout_centre_ex(ol::TextRenderer &afont, const string amessage, int ax, int ay, int acolor, float alpha = 1.0);
void buffer_textout_right_ex(ol::TextRenderer &afont, const string amessage, int ax, int ay, int acolor, float alpha = 1.0);
void clipped_textout_ex(ol::TextRenderer &f, const string text, int x, int y, int l, int c, float alpha = 1.0);
void clipbox_textout_ex(ol::TextRenderer &f, const string text, int textx, int texty, int clipx, int clipy, int clipw, int cliph, int color, float alpha = 1.0);
void multiline_textout_ex(ol::TextRenderer &f, const string text, int x, int y, int l, int c, float alpha = 1.0);
void buffer_circlefill(int ax, int ay, float ar, int acolor, float alpha = 1.0);
void buffer_additive_circlefill(int ax, int ay, float ar, int acolor, float alpha = 1.0);
void buffer_circlefill_gradient(int ax, int ay, float ar, ol::Rgba inner, ol::Rgba outer);
void buffer_rect(int ax, int ay, int bx, int by, int acolor, float alpha = 1.0);
void buffer_rectfill(int ax, int ay, int bx, int by, int acolor, float alpha = 1.0);
void buffer_rectfill_gradient(int ax, int ay, int bx, int by, int tl, int tr, int br, int bl);
void buffer_rectrounded(int ax, int ay, int bx, int by, int acolor, float alpha = 1.0, float roundness = 2.0);
void buffer_discfill(int ax, int ay, int innerradius, int outerradius, int acolor, float alpha = 1.0);
void buffer_menuback(int ax, int ay, int bx, int by, int acolor1, int acolor2, int acolor3, float alpha = 1.0);
void buffer_putpixel(int ax, int ay, int acolor, float alpha = 1.0);
void buffer_mapblip(int ax, int ay, int acolor, float alpha = 1.0);
void buffer_hline(int ax, int ay, int bx, int acolor, float alpha = 1.0);
void buffer_vline(int ax, int ay, int by, int acolor, float alpha = 1.0);
void buffer_linestrip(ol::LineStrip *al, ol::Rgba startcolor, ol::Rgba endcolor);
void buffer_clear_to_color(int acolor);
void copy_screen_to(ol::Bitmap *target);
void set_normal_blender();
void set_additive_blender();
void enable_antialiasing();
void disable_antialiasing();

void draw_all(bool refreshcanvas = true);
void draw_all(ol::Bitmap *target);

#endif
