/*
 *  Draw the empty boxes for:
 *   the artwork box,
 *   the text bars for name and type lines,
 *   the rules text box(es) [flip-cards have two boxes],
 *   the power toughness box (if any).
 *
 *  Also, draw the outermost border, and ensure there are
 *  transparent bits at the edges (particularly the corners) of the image.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "app.h"

#include "GenCard.h"

char *form_powtgh_filename(
			int bitfield,		/* bit-field: IS_BLUE | IS_ARTIFACT */
			int num_colours,	/* # unique colours */
			int num_genmana,	/* # unique mana symbols generated */
			char *tb_name		/* e.g. Red or Land */
	)
{
	char *filename;

	if ((bitfield & IS_MULTI) && (num_colours >= 3))
		filename = copy_string("Multi");
	else if (bitfield & IS_HYBRID)
		filename = copy_string("Hybrid");
	else if (bitfield & IS_MULTI)
		filename = copy_string("Multi");
	else if ((bitfield & IS_ARTIFACT) && (num_colours == 0))
		filename = copy_string("Artifact");
	else if ((bitfield & IS_LAND) && (num_genmana == 0))
		filename = copy_string("Land");
	else if ((bitfield & IS_LAND) && (num_genmana >= 3))
		filename = copy_string("Multi");
	else if ((bitfield & IS_LAND) && (num_genmana >= 2))
		filename = copy_string("Land");
	else
		filename = copy_string(tb_name);

	return append_string(filename, "_PowerToughness.png");
}


Image * form_normal_card_8th_ed(Image *bgd, Image *bdr, Image *bar, Image *txt, Image *pow, Colour border_colour)
{
	const int border_line = 1;
	const int border_size = 30;
	const int artwork_line = 2;
	Rect background	= rect(  0,   0,  744,     1042);
	Rect borders	= rect( 35,  48,  704- 35,  952- 48);
	Rect powtgh 	= rect(546, 926,  693-546, 1000-926);
	Rect textbox	= rect( 58, 650,  684- 58,  938-650);
	Rect textbars	= rect( 46,  51,  697- 46,  650- 51);
	Rect artwork	= rect( 60, 122,  622,      456);
	Rect artborder	= app_inset_rect(artwork, -artwork_line);
	Graphics *g;
	Image *result;

	result = app_copy_image(bgd);
	if (result == NULL)
		return NULL;

	/* Draw into the image now. */
	g = app_get_image_graphics(result);

	/* Draw the black or white outer card border. */
	draw_outer_border(g, result, background, border_size, border_line, border_colour);

	/* Overlay the borders, textbars, textbox and powertoughness box. */
	if (bdr && (bdr->width == bgd->width) && (bdr->height == bgd->height))
		borders = background;
	if (bar && (bar->width == bgd->width) && (bar->height == bgd->height))
		textbars = background;
	if (txt && (txt->width == bgd->width) && (txt->height == bgd->height))
		textbox = background;
	if (pow && (pow->width == bgd->width) && (pow->height == bgd->height))
		powtgh = background;
	
	/* Overlay the borders, textbars, textbox and powertoughness box. */
	if (bdr)
		app_draw_image(g, borders,  bdr, app_get_image_area(bdr));
	if (bar)
		app_draw_image(g, textbars, bar, app_get_image_area(bar));
	if (txt)
		app_draw_image(g, textbox,  txt, app_get_image_area(txt));
	if (pow)
		app_draw_image(g, powtgh,   pow, app_get_image_area(pow));

	/* Draw artwork box outer border */
	app_set_colour(g, BLACK);
	app_set_line_width(g, artwork_line);
	app_draw_rect(g, artborder);

	/* Blank artwork box. */
	app_set_colour(g, WHITE);
	app_fill_rect(g, artwork);

	/* Tidy up. */
	app_del_graphics(g);

	/* Return the constructed 300 DPI image to the caller. */
	return result;
}

Image * form_flip_card_8th_ed(Image *bgd, Image *bdr, Image *bar, Image *txt, Image *pow, int pow_bitfield, Colour border_colour)
{
	const int flip_gap    = 46;
	const int border_line = 1;
	const int border_size = 30;
	const int artwork_line = 2;
	Rect background	= rect(  0,   0,  744,     1042);
	Rect borders	= rect( 35,  48,  704- 35,  952- 48);
	Rect powtgh 	= rect(546, 243,  693-546, 1000-926);
	Rect textbox	= rect( 58, 120,  684- 58,  118);
	Rect textbars	= rect( 46,  51,  697- 46,  650- 51);
//	Rect namebar	= rect( 62,  58,  651- 32,  64);
//	Rect costbar	= rect( 62,  51,  651- 32,  64);
//	Rect typebar	= rect( 64, 587,  651- 36,  64);
	Rect artwork	= rect( 60, 316,  622,      362);
	Rect artborder	= app_inset_rect(artwork, -artwork_line);
	Rect dr;
	Rect sr;
	Graphics *g;
	Image *result;

	result = app_copy_image(bgd);
	if (result == NULL)
		return NULL;

	/* Draw into the image now. */
	g = app_get_image_graphics(result);

	/* Draw the black or white outer card border. */
	draw_outer_border(g, result, background, border_size, border_line, border_colour);

	/* Handle special cases where graphics are same size as whole image. */
	/* Assume in those cases that the graphics include flippedness already. */
	if (bdr && (bdr->width == bgd->width) && (bdr->height == bgd->height)) {
		app_draw_image(g, background, bdr, app_get_image_area(bdr));
		bdr = NULL;
	}
	if (bar && (bar->width == bgd->width) && (bar->height == bgd->height)) {
		app_draw_image(g, background, bar, app_get_image_area(bar));
		bar = NULL;
	}
	if (txt && (txt->width == bgd->width) && (txt->height == bgd->height)) {
		app_draw_image(g, background, txt, app_get_image_area(txt));
		bgd = NULL;
	}
	if (pow && (pow->width == bgd->width) && (pow->height == bgd->height)) {
		app_draw_image(g, background, pow, app_get_image_area(pow));
		pow = NULL;
	}

	/* Overlay the upright borders, textbars, textbox and powertoughness box. */
	if (bdr) {
		/* Draw some plain border next to the artwork box. */
		dr = rect(borders.x, borders.y + 192 + 280, borders.width - 20, 170);
		sr = rect(        0, 90,                    dr.width,        dr.height);
		app_draw_image(g, dr, bdr, sr);
	}

	/* Now rotate the whole image 180 degrees to draw the flipped components. */	
	rotate_image_32bpp_180_degrees(result);

	/* Overlay the flipped borders, textbars, textbox and powertoughness box. */
	if (bdr) {
		/* The name bar border up the top is fairly normal. */
		dr = rect(borders.x, borders.y + flip_gap, borders.width,  192);
		sr = rect(        0,         0,            dr.width,      dr.height);
		app_draw_image(g, dr, bdr, sr);

		/* Move the type bar border upwards for flip cards. */
		dr = rect(dr.x, dr.y + dr.height, dr.width,  280);
		sr = rect(sr.x, 532,              dr.width, dr.height);
		app_draw_image(g, dr, bdr, sr);

		/* Draw some plain border next to the artwork box. */
		dr = rect(dr.x, dr.y + dr.height, dr.width - 20, 170);
		sr = rect(sr.x, 90,               dr.width  , dr.height);
		app_draw_image(g, dr, bdr, sr);
	}
	if (bar) {
		/* The name bar up the top is fairly normal. */
		dr = rect(textbars.x, textbars.y + flip_gap, textbars.width,  192);
		sr = rect(         0,          0,            dr.width,       dr.height);
		app_draw_image(g, dr, bar, sr);

		/* Move the type bar upwards for flip cards. */
		dr = rect(dr.x, dr.y + dr.height, dr.width, 66);
		sr = rect(sr.x, 532,              dr.width, dr.height);
		app_draw_image(g, dr, bar, sr);
	}
	if (txt) {
		/* Text boxes are between the name and type bar on flip cards. */
		dr = rect(textbox.x, textbox.y + flip_gap, textbox.width,  112);
		sr = rect(        0,         0,            dr.width,      dr.height);
		app_draw_image(g, dr, txt, sr);
			
		/* Reapply the textbox bottom bevel, which the above omitted. */
		dr = rect(dr.x, dr.y + dr.height,        dr.width,   6);
		sr = rect(sr.x, txt->height - dr.height, dr.width, dr.height);
		app_draw_image(g, dr, txt, sr);
	}
	if (pow) {
		if (pow_bitfield & 2) {
			/* There are up to two pow/tgh boxes on flip cards. */
			/* This is the bottom one. */
			sr = app_get_image_area(pow);
			dr = rect(powtgh.x, powtgh.y + flip_gap, sr.width, sr.height);
			app_draw_image(g, dr, pow, sr);
		}
	}

	/* Now rotate the whole image 180 degrees back again. */	
	rotate_image_32bpp_180_degrees(result);

	if (bdr) {
		/* The name bar border up the top is fairly normal. */
		dr = rect(borders.x, borders.y,   borders.width,  192);
		sr = rect(        0,         0,   dr.width,       dr.height);
		app_draw_image(g, dr, bdr, sr);

		/* Move the type bar border upwards for flip cards. */
		dr = rect(dr.x, dr.y + dr.height, dr.width,  280);
		sr = rect(sr.x, 532,              dr.width, dr.height);
		app_draw_image(g, dr, bdr, sr);

		/* Draw some plain border next to the artwork box. */
		/*
		dr = rect(dr.x, dr.y + dr.height, dr.width/2, 170); //364);
		sr = rect(sr.x, 90,               dr.width  , dr.height);
		app_draw_image(g, dr, bdr, sr);
		*/
	}
	if (bar) {
		/* The name bar up the top is fairly normal. */
		dr = rect(textbars.x, textbars.y, textbars.width,  192);
		sr = rect(         0,          0, dr.width,        dr.height);
		app_draw_image(g, dr, bar, sr);

		/* Move the type bar upwards for flip cards. */
		dr = rect(dr.x, dr.y + dr.height, dr.width,  66);
		sr = rect(sr.x, 532,              dr.width, dr.height);
		app_draw_image(g, dr, bar, sr);
	}
	if (txt) {
		/* Text boxes are between the name and type bar on flip cards. */
		dr = rect(textbox.x, textbox.y,    textbox.width,  112);
		sr = rect(        0,         0,    dr.width,      dr.height);
		app_draw_image(g, dr, txt, sr);
		
		/* Reapply the textbox bottom bevel, which the above omitted. */
		dr = rect(dr.x, dr.y + dr.height,        dr.width,   6);
		sr = rect(sr.x, txt->height - dr.height, dr.width, dr.height);
		app_draw_image(g, dr, txt, sr);
	}
	if (pow) {
		if (pow_bitfield & 1) {
			/* There are up to two pow/tgh boxes on flip cards. */
			/* This is the top one. */
			sr = app_get_image_area(pow);
			dr = rect(powtgh.x, powtgh.y, sr.width, sr.height);
			app_draw_image(g, dr, pow, sr);
		}
	}

	/* Draw artwork box outer border */
	app_set_colour(g, BLACK);
	app_set_line_width(g, artwork_line);
	app_draw_rect(g, artborder);

	/* Blank artwork box. */
	app_set_colour(g, WHITE);
	app_fill_rect(g, artwork);

	/* Tidy up. */
	app_del_graphics(g);

	/* Return the constructed 300 DPI image to the caller. */
	return result;
}

/*
 * This is the new extensible way of generating card backgrounds.
 */
Image * form_card_template_1_8th_ed(Colour bg_border,  /* BLACK, WHITE, GOLD */
			int bitfield,		/* bit-field: IS_BLUE | IS_ARTIFACT */
			int num_colours,	/* # unique colours */
			int num_genmana,	/* # unique mana symbols generated */
			int num_hybrids,	/* # unique hybrid mana symbols */
			char *bg_name,          /* e.g. Red or Land */
			char *tb_name,          /* e.g. Red or Land */
			int is_creature,        /* is it a creature card? */
			int is_flip)            /* is it a flip card? */
{
	/* This function draws normal or normal flip-cards, not hybrids. */
	Image *bgd, *bdr, *bar, *txt, *pow;
	char *bgd_filename, *bdr_filename, *bar_filename, *txt_filename, *pow_filename;
	Image *template = NULL;

	/* Background */
	if (bitfield & IS_LAND)
		bgd_filename = copy_string("Land");
	else if (bitfield & IS_ARTIFACT)
		bgd_filename = copy_string("Artifact");
	else if ((bitfield & IS_MULTI) && (num_colours >= 3))
		bgd_filename = copy_string("Multi");
	else if ((bitfield & IS_HYBRID) && (num_colours <= 2))
		bgd_filename = copy_string(bg_name); /* Blend later. */
	else if (bitfield & IS_MULTI)
		bgd_filename = copy_string("Multi");
	else
		bgd_filename = copy_string(bg_name);
	bgd_filename = append_string(bgd_filename, "_Background.png");

	/* Borders */
	if (num_colours >= 3)
		bdr_filename = copy_string("Multi");
	else if (num_colours == 2)
		bdr_filename = copy_string(tb_name); /* Blend later. */
	else if (num_colours == 1)
		bdr_filename = copy_string(tb_name); /* Single colour. */
	else if (bitfield & IS_MULTI)
		bdr_filename = copy_string("Multi");
	else if ((bitfield & IS_ARTIFACT) && (bitfield & IS_LAND) && (num_genmana == 1))
		bdr_filename = copy_string(tb_name);
	else if ((bitfield & IS_ARTIFACT) && (bitfield & IS_LAND) && (num_genmana == 2))
		bdr_filename = copy_string(tb_name);
	else if ((bitfield & IS_ARTIFACT) && (bitfield & IS_LAND) && (num_genmana >= 3))
		bdr_filename = copy_string("Multi");
	else if (bitfield & IS_ARTIFACT)
		bdr_filename = copy_string("Artifact");
	else if ((bitfield & IS_LAND) && (num_genmana == 0))
		bdr_filename = copy_string("Land");
	else if ((bitfield & IS_LAND) && (num_genmana >= 3))
		bdr_filename = copy_string("Multi");
	else
		bdr_filename = copy_string(tb_name);
	bdr_filename = append_string(bdr_filename, "_Border.png");

	/* TextBars */
	if ((bitfield & IS_MULTI) && (num_colours >= 3))
		bar_filename = copy_string("Multi");
	else if (bitfield & IS_HYBRID)
		bar_filename = copy_string("Hybrid");
	else if (bitfield & IS_MULTI)
		bar_filename = copy_string("Multi");
	else if ((bitfield & IS_ARTIFACT) && (num_colours == 0))
		bar_filename = copy_string("Artifact");
	else if ((bitfield & IS_LAND) && (num_genmana == 0))
		bar_filename = copy_string("Land");
	else if ((bitfield & IS_LAND) && (num_genmana >= 3))
		bar_filename = copy_string("Multi");
	else if ((bitfield & IS_LAND) && (num_genmana >= 2))
		bar_filename = copy_string("Land");
	else
		bar_filename = copy_string(tb_name);

	/* TextBox */
	if ((bitfield & IS_MULTI) && (num_colours >= 3))
		txt_filename = copy_string("Multi");
	else if ((bitfield & IS_ARTIFACT) && (num_colours == 0))
		txt_filename = copy_string("Artifact");
	else if ((bitfield & IS_LAND) && (num_genmana == 0))
		txt_filename = copy_string("Land");
	else if ((bitfield & IS_LAND) && (num_genmana >= 3))
		txt_filename = copy_string("Multi");
	else
		txt_filename = copy_string(tb_name);
	txt_filename = append_string(txt_filename, "_TextBox.png");

	/* PowerToughness */
	pow_filename = copy_string(bar_filename);
	pow_filename = append_string(pow_filename, "_PowerToughness.png");
	bar_filename = append_string(bar_filename, "_TextBars.png");

	/* Try to load those files as images. */
	bgd = find_cached_image(bgd_filename);
	bdr = find_cached_image(bdr_filename);
	bar = find_cached_image(bar_filename);
	txt = find_cached_image(txt_filename);
	if (is_creature)
		pow = find_cached_image(pow_filename);
	else
		pow = NULL;

	/* Create a card template. */
	if (bgd != NULL)
	{
		if (is_flip)
			template = form_flip_card_8th_ed(bgd, bdr, bar, txt, pow, is_creature, bg_border);
		else
			template = form_normal_card_8th_ed(bgd, bdr, bar, txt, pow, bg_border);
	}

	/* Tidy up. */
	if (pow)
		app_del_image(pow);
	if (txt)
		app_del_image(txt);
	if (bar)
		app_del_image(bar);
	if (bdr)
		app_del_image(bdr);
	if (bgd)
		app_del_image(bgd);
	if (pow_filename)
		app_free(pow_filename);
	if (txt_filename)
		app_free(txt_filename);
	if (bar_filename)
		app_free(bar_filename);
	if (bdr_filename)
		app_free(bdr_filename);
	if (bgd_filename)
		app_free(bgd_filename);

	return template;
}

/* Hybrids with two colours blended horizontally. */
Image * form_card_template_2_8th_ed(Colour bg_border,  /* BLACK, WHITE, GOLD */
			int bitfield,		/* bit-field: IS_BLUE */
			int num_colours,	/* # unique colours */
			int num_genmana,	/* # unique mana symbols generated */
			int num_hybrids,	/* # unique hybrid mana symbols */
			char *bg_name1,         /* e.g. Blue or Land */
			char *tb_name1,         /* e.g. Blue or Land */
			char *bg_name2,         /* e.g. Purple or Land */
			char *tb_name2,         /* e.g. Purple or Land */
			int is_creature,        /* is it a creature card? */
			int is_flip)            /* is it a flip card? */
{
	/* This function draws hybrids or flip-cards hybrids. */
	Image *template1 = NULL;
	Image *template2 = NULL;

	if ((bg_name2 == NULL) && (tb_name2 == NULL))
	{
		/* Not a hybrid. Handle it as a normal or flip card. */
		return form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name1, tb_name1, is_creature, is_flip);
	}

	if (bg_name2 == NULL)
		bg_name2 = bg_name1;
	if (tb_name2 == NULL)
		tb_name2 = tb_name1;

	/*
	 * Left card.
	 */
	template1 = form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name1, tb_name1, is_creature, is_flip);
	if (template1 == NULL) {
		return NULL;
	}

	/*
	 * Right card.
	 */
	template2 = form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name2, tb_name2, is_creature, is_flip);
	if (template2 == NULL) {
		app_del_image(template1);
		return NULL;
	}

	/* Blend the hybrid templates left-right. */
	blend_two_images_32bpp_horizontally(template1, template2, BLEND_DIST);

	app_del_image(template2);

	return template1;
}


/* Hybrids with three colours blended horizontally. */
Image * form_card_template_3_8th_ed(Colour bg_border,  /* BLACK, WHITE, GOLD */
			int bitfield,		/* bit-field: IS_BLUE | IS_LAND */
			int num_colours,	/* # unique colours */
			int num_genmana,	/* # unique mana symbols generated */
			int num_hybrids,	/* # unique hybrid mana symbols */
			char *bg_name1,         /* e.g. Blue or Land */
			char *tb_name1,         /* e.g. Blue or LandU */
			char *bg_name2,         /* e.g. Purple or Land */
			char *tb_name2,         /* e.g. Purple or LandP */
			char *bg_name3,         /* e.g. Red or Land */
			char *tb_name3,         /* e.g. Red or LandR */
			int is_creature,        /* is it a creature card? */
			int is_flip)            /* is it a flip card? */
{
	/* This function draws hybrids or flip-cards hybrids. */
	Image *template1 = NULL;
	Image *template2 = NULL;
	Image *template3 = NULL;

	if ((bg_name2 == NULL) && (tb_name2 == NULL))
	{
		/* Not a hybrid. Handle it as a normal or flip card. */
		return form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name1, tb_name1, is_creature, is_flip);
	}
	else if ((bg_name3 == NULL) && (tb_name3 == NULL))
	{
		/* Two-colour hybrid. Handle it as a normal or flip card. */
		return form_card_template_2_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name1, tb_name1,
				bg_name2, tb_name2,
				is_creature, is_flip);
	}

	if (bg_name2 == NULL)
		bg_name2 = bg_name1;
	if (tb_name2 == NULL)
		tb_name2 = tb_name1;

	if (bg_name3 == NULL)
		bg_name3 = bg_name2;
	if (tb_name3 == NULL)
		tb_name3 = tb_name2;

	/*
	 * Left card.
	 */
	template1 = form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name1, tb_name1, is_creature, is_flip);
	if (template1 == NULL) {
		return NULL;
	}

	/*
	 * Middle card.
	 */
	template2 = form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name2, tb_name2, is_creature, is_flip);
	if (template2 == NULL) {
		app_del_image(template1);
		return NULL;
	}

	/*
	 * Right card.
	 */
	template3 = form_card_template_1_8th_ed(bg_border,
				bitfield, num_colours, num_genmana, num_hybrids,
				bg_name3, tb_name3, is_creature, is_flip);
	if (template3 == NULL)
	{
		app_del_image(template2);
		app_del_image(template1);
		return NULL;
	}

	/* Blend the hybrid templates left-right. */
	blend_three_images_32bpp_horizontally(template1, template2, template3, BLEND_DIST);

	/* Final tidy up. */
	app_del_image(template3);
	app_del_image(template2);

	return template1;
}

