#include "wou.h"

int brush_selected = -1; // se tenho um tile
int draw_fringe = TRUE; // é pra desenhar fringe?
int draw_objects = TRUE; // é pra desenhar objectos?
int draw_rotation = 0;
int DRAWING_LAYER;
int MENU_W, MENU_H;
int ZOOM;

//******************************************************************************
// Inicialização
//******************************************************************************
void init_all() {
	open_log("wou.log");

	allegro_init();
	install_keyboard();
	install_mouse();
	install_timer();
	display.init();
	set_window_title("WoU Map Editor");
	show_mouse(screen);
	
	/* Carrega o mapa e desenha-o */
	map.load();
	map.draw(CORNER_X,CORNER_Y,0);
}

//******************************************************************************
// Apaga a informação de brush anterior
//******************************************************************************
int brush_info(int num) {

	/* Texto indicativo do tile que tamos a meter */
	int infox = 18;
	int infoy = GAMEPLAY_H+25;

	/* Mete num bitmap o BITMAP do tile que queremos */
	BITMAP *layerBMP;
	BITMAP *brushBMP = create_bitmap(TILE_W,TILE_H);
	rectfill(vbuffer,infox,infoy,GAMEPLAY_W,SCREEN_H,1);
	int coords[2];
	get_gif_coords(tiledb[num].icon, coords);
	if (DRAWING_LAYER == 1) {
		if (num>DB_TILE_NUMBER-1) {
			brush_selected = -1;
			return -1;
		}
		layerBMP = tilesBMP;
	}
	else {
   	if (num>DB_FRINGE_NUMBER-1) {
			brush_selected = -1;
			return -1;
		}
		layerBMP = fringeBMP;
	}
	/* Temos um brush selected, vamos imprimir a informaçao dele */
	if (brush_selected>-1) {
		blit(layerBMP,brushBMP,coords[0],coords[1],0,0,TILE_W,TILE_H);
		stretch_blit(brushBMP, vbuffer, 0, 0, brushBMP->w, brushBMP->h, infox, infoy, brushBMP->w*3, brushBMP->w*3);
		/* Numero do tile por baixo */
		textprintf_ex(vbuffer, smallFONT, 18, infoy+TILE_H*3, 243, -1,"Num: %i", num);
	}
}

//******************************************************************************
// Desenha o menu com os tiles que podemos escolher
// ########## BUG ################ tá a alterar por vezes tiles no mapa!!?!??!
//******************************************************************************
void draw_menu(int layer) {
	DRAWING_LAYER = layer;
	brush_selected = -1;
	brush_info(-1);
	int x,y,advx=0,advy=0;
	int coords[2];

	/* Define quantos tiles existem para cada layer
	   e qual o PCX que se deve usar */
	int maxNumber;
	BITMAP *layerBMP;
	if (layer == 1) {
		maxNumber = DB_TILE_NUMBER;
		layerBMP = tilesBMP;
	}
	else if (layer == 2) {
		maxNumber = DB_FRINGE_NUMBER;
		layerBMP = fringeBMP;
	}
	/* Dimensoes do menu */
	MENU_W = 25*TILE_W+26;
	MENU_H = ((maxNumber/25)+1)*TILE_H+((maxNumber/25)+1)+1;

	/* Cria um bitmap para o menu com largura tile_w*num_tiles+(num_tiles+1) */
	rectfill(vbuffer,GAMEPLAY_W+20,18,WINDOW_W,WINDOW_H,1);
	BITMAP *menu = create_bitmap(MENU_W, MENU_H);
 	clear_to_color(menu,243); // fundo amarelo

	/* Desenha a palette de tiles */
	for (int i=0;i<maxNumber;i++) {
		get_gif_coords(tiledb[i].icon, coords);
		x = i%25;
		y = i/25;
		/* Para dar 1 pixel de intervalo entre os tiles */
		(i%25) ? advx++ : advx = 1;
		(i%25) ? advy = 1+i/25 : advy++;
		/* Desenha o tile_w*tile_h quadradinho consoante o layer */
		blit(layerBMP,menu,coords[0],coords[1],x*TILE_W+advx,y*TILE_H+advy,TILE_W,TILE_H);
	}
	blit(menu,vbuffer,0,0,GAMEPLAY_W+20,18,menu->w,menu->h);
	destroy_bitmap(menu);
}

//******************************************************************************
// Chamado quando se clica num quadradinho do menu de tiles/fringe/objectos
// Vai buscar qual o tile/fringe/objecto que queremos meter no mapa
//******************************************************************************
int get_brush() {
	/* Coordenadas relativas no menu do tile que tamos a carregar */
	int col = (mouse_x-GAMEPLAY_W-20)/17;
	int line = (mouse_y-18)/17;
	/* Calculo do numero do tile em que se clicou */
	int x = (TILE_W*col)+col+1;
	int y = (TILE_H*line)+line+1;
	int tileNum = col+line*25;
	brush_selected = tileNum; // define a global para depois pintar no mapa

	/* Informação do brush */
	brush_info(tileNum);
}

//******************************************************************************
// Chamado quando se clica no mapa e se tem escolhido um tile/fringe/objecto
// Mete o tile/fringe/objecto que temos na 'mao' no mapa
//******************************************************************************
void drop_tile() {
	int col,line;
	int a, b;
	col = (mouse_x-18)/16;
	line = (mouse_y-18)/16;
	
	/* Porque o mapa da a volta */
	a = CORNER_X+col;
	b = CORNER_Y+line;
	if (a>549) a = a-550;
	if (b>549) b = b-550;
	
	/* Vou pintar com um tile/fringe */
	if (brush_selected>-1) {
		if (DRAWING_LAYER == 1) map.tile[a][b].num = brush_selected;
		else if (DRAWING_LAYER == 2) map.fringe[a][b].num = brush_selected;
	}
	
	/* Nao tenho nada seleccionado, aparece info */
	else {
		rectfill(vbuffer,GAMEPLAY_W+30,MENU_H+30,WINDOW_W,MENU_H+48,1);
      textprintf_ex(vbuffer, smallFONT, GAMEPLAY_W+30, MENU_H+30, 243, -1,
		"(%i,%i) tile: %i  fringe: %i",a,b,map.tile[a][b].num,
		map.fringe[a][b].num);
		textprintf_ex(vbuffer, smallFONT, GAMEPLAY_W+30, MENU_H+38, 243, -1,
		"passable: %i",tiledb[map.tile[a][b].num].passable);
	}
}

//******************************************************************************
// Faz aparecer ou desaparecer objectos/fringe consoante se carrega mouse4
//******************************************************************************
int draw_rotate() {
	if (draw_rotation == 0) {
		draw_objects = FALSE;
		draw_rotation++;
		return 0;
	}
	else if (draw_rotation == 1) {
		draw_fringe = FALSE;
		draw_rotation++;
		return 0;
	}
	else if (draw_rotation == 2) {
		draw_objects = TRUE;
		draw_rotation++;
		return 0;
	}
	else if (draw_rotation == 3) {
		draw_fringe = TRUE;
		draw_rotation = 0;
		return 0;
	}
	return -1;
}

//******************************************************************************
// Texto que aparece no topo do gameplay
//******************************************************************************
void draw_top_text() {
	char *layer;
	if (DRAWING_LAYER == 1) layer = "TILES";
	else if (DRAWING_LAYER == 2) layer = "FRINGE";

	rectfill(vbuffer,18,0,WINDOW_W,17,1);
	textprintf_ex(vbuffer, smallFONT, 18, 4, 243, -1,"Editing Layer: %i - Coords: %i:%i - Zoom: %i", DRAWING_LAYER,CORNER_X, CORNER_Y, ZOOM);
	textprintf_ex(vbuffer, smallFONT, GAMEPLAY_W+20, 4, 243, -1,"+ %s +",layer);
}

//******************************************************************************
// Desenha tudo no ecrã, por ordem
//******************************************************************************
void draw_all() {
	acquire_screen();
	/* Texto que aparece no topo do gameplay */
	draw_top_text();
	/* Layer 1 */
	map.drawTiles(CORNER_X,CORNER_Y, ZOOM);
	/* Layer 2 */
	if (draw_fringe) map.drawFringe(CORNER_X,CORNER_Y, ZOOM);
	/* Layer 3 */
	if (draw_objects) map.drawObjects(CORNER_X,CORNER_Y, ZOOM);
	/* Mete a area de 'jogo' no buffer */
	blit(gamearea,vbuffer,0,0,18,18,gamearea->w,gamearea->h);
	blit(vbuffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);
	release_screen();
}

void do_input() {
   /* Movimento do mapa */
	if (key[KEY_UP]) {
		key[KEY_UP] = 0;
		CORNER_Y--;
		if (CORNER_Y<0) CORNER_Y = 549;
	}
	else if (key[KEY_DOWN]) {
		key[KEY_DOWN] = 0;
		CORNER_Y++;
		if (CORNER_Y>549) CORNER_Y = 0;
	}
	else if (key[KEY_LEFT]) {
		key[KEY_LEFT] = 0;
		CORNER_X--;
		if (CORNER_X<0) CORNER_X = 549;
	}
	else if (key[KEY_RIGHT]) {
		key[KEY_RIGHT] = 0;
   	CORNER_X++;
   	if (CORNER_X>549) CORNER_X = 0;
	}

	/* Para mudar os tiles de menu */
	if (key[KEY_1]) draw_menu(1);
	else if (key[KEY_2]) draw_menu(2);

	/* Zoom */
	if (key[KEY_X] && ZOOM<2) {
		ZOOM++;
		key[KEY_X] = FALSE;
	}
	else if (key[KEY_Z] && ZOOM>-2) {
		ZOOM--;
		key[KEY_Z] = FALSE;
	}
}

//******************************************************************************
// Main loop de edição do mapa
//******************************************************************************
void edit_map() {

	display.setMousePointer(1);
   /*CORNER_X = ZONE_W/2;
   CORNER_Y = ZONE_H/2;*/
   CORNER_X = 0;
   CORNER_Y = 0;

	while (!key[KEY_ESC] && !CLOSE_BUTTON_PRESSED) {
		/* Trata de keypresses */
		do_input();
		/* Rodar pelos layers de desenho */
		if (mouse_b&4) {
			draw_rotate();
			mouse_b = 0;
		}
		/* Unselect */
		else if (mouse_b&2) {
			brush_selected=-1;
			mouse_b = 0;
		}
		/* Carreguei na palette de gifs */
		if (mouse_x>GAMEPLAY_W+20 && mouse_x<GAMEPLAY_W+19+MENU_W && mouse_y<MENU_H+18) {
			if (MOUSE_NUM != 1) display.setMousePointer(1);
			if ((mouse_b&1)) {
				get_brush();
				mouse_b = 0;
			}
		}
		else {
			if (brush_selected>=0) {
				if (MOUSE_NUM != 3) display.setMousePointer(3);
			}
         else if (MOUSE_NUM != 4) display.setMousePointer(4);
		}
		/* Carreguei no mapa */
		if ((mouse_b&1) && mouse_y<GAMEPLAY_H+20) {
			drop_tile();
		}
		/* Imprime tudo no ecrã */
		draw_all();
	}
}

int main() {
	init_all();
	set_palette(black_palette);
	clear_to_color(vbuffer, 1);
	clear_to_color(screen, 1);
	set_palette((RGB*)tiles[PALETTE_GAME].dat);
	/* Desenha o menu tiles por default */
	draw_menu(1);
	/* Main loop */
	edit_map();
	allegro_exit();
	map.save();
	return 0;
}
END_OF_MAIN();
