/*-
 * Copyright (c) 2000
 * Tatsuya Kudoh(CDR/TK),ROYALPANDA.    All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include<stdlib.h>
#include"soari.h"


static unsigned char Room[(NUM_ROOM_X+1) * (NUM_ROOM_Y+1)];

#define STAND_HEIGHT	2

#define UP	1
#define RIGHT	2
#define DOWN	4
#define LEFT	8
static int Dir[4] = { -(NUM_ROOM_X+1),1,(NUM_ROOM_X+1),-1 };

static int Prob_loop;



static void move( unsigned char *p )
{
	static int i;
	static unsigned char *pp;
	static int route;
	static int dir[4];

	for(;;){
		route = 0;
		for( i = 0 ; i < 4 ; i++ ){
			pp = p + Dir[i];
			if( pp >= Room && *pp == 0xf )
				dir[route++] = i;
		}
		if( route == 0 )
			break;
		i = dir[rnd(route)];
		*p &= ~(1 << i);
		pp = p + Dir[i];
		i = (i+2) & 3;
		*pp &= ~(1 << i);
		move(pp);
	}
	if( rnd(100) < Prob_loop ){
		route = 0;
		for( i = 0 ; i < 4 ; i++ ){
			pp = p + Dir[i];
			if( pp < Room )
				continue;
			if( *pp == 0 )
				continue;
			if( *p & 1<<i )
				dir[route++] = i;
		}
		if( route > 0 ){
			i = dir[rnd(route)];
			*p &= ~(1<<i);
			pp = p + Dir[i];
			i = (i+2) & 3;
			*pp &= ~(1<<i);
		}
	}
}


static void create_room( int width, int height, int prob_loop )
{
	unsigned char *p;
	int x,y;

	p = Room;
	for( y = 0 ; y < height ; y++ ){
		for( x = 0 ; x < width ; x++ )
			*p++ = 0xf;
		for( ; x < NUM_ROOM_X+1 ; x++ )
			*p++ = 0;
	}
	for( x = 0 ; x < NUM_ROOM_X+1 ; x++ )
		*p++ = 0;

	Prob_loop = prob_loop;
	x = rnd(NUM_ROOM_X);
	y = rnd(NUM_ROOM_Y);
	move(Room+x+y*(NUM_ROOM_X+1));
}


static void fill_map( map_t *map, int x, int y, int w, int h, int b )
{
	unsigned char *p;
	int ww;

	while( h-- ){
		p = map->map + x + y * MAP_WIDTH;
		ww = w;
		while( ww-- ){
			*p++ = b;
		}
		y++;
	}
}


void create_map( map_t *map, int width, int height, int prob_loop )
{
	int stand_pos;
	int rx,ry;
	int sx;
	int x,y;
	unsigned char *p;

	create_room(width,height,prob_loop);

	x = 0;
	for( rx = 0 ; rx < width ; rx++ ){
		p = &Room[rx];
		y = 0;
		stand_pos = rnd(2);
		for( ry = 0 ; ry < height ; ry++ ){
			fill_map(map,x+1,y+1,ROOM_WIDTH-1,ROOM_HEIGHT-1,0);
			fill_map(map,x,y,ROOM_WIDTH,1,1);
			fill_map(map,x,y+1,1,ROOM_HEIGHT,(*p & LEFT) ? 1 : 0);
			if( !(*p & UP) ){
				if( stand_pos )
					sx = 4;
				else
					sx = ROOM_WIDTH-6;
				stand_pos = !stand_pos;
				fill_map(map,x+sx,y,3,1,0);
				fill_map(map,x+sx,y+ROOM_HEIGHT-STAND_HEIGHT,
				    3,STAND_HEIGHT,1);
			}else{
				stand_pos = rnd(2);
			}
			p += NUM_ROOM_X+1;
			y += ROOM_HEIGHT;
		}
		x += ROOM_WIDTH;

	}
	fill_map(map,0,ROOM_HEIGHT*NUM_ROOM_Y,MAP_WIDTH,1,1);
	fill_map(map,ROOM_WIDTH*NUM_ROOM_X,0,1,MAP_HEIGHT,1);

	map->width = ROOM_WIDTH*NUM_ROOM_X+1;
	map->height = ROOM_HEIGHT*NUM_ROOM_Y+1;
}


void layout_ene( int width, int height, ene_t *ene_list, int hx, int hy  )
{
	unsigned char *p;
	ene_t *ep;
	int x,y;

	p = Room;
	for( y = 0 ; y < height ; y++ )
		for( x = 0 ; x < width ; x++ )
			*p++ = 0;

	Room[hx+hy*(NUM_ROOM_X+1)] = 1;

	ep = ene_list->next;
	while( ep ){
		do{
			x = rnd(width);
			y = rnd(height);
			p = &Room[x+y*(NUM_ROOM_X+1)];
		}while( *p );
		*p = 1;
		ep->x = (x+1) * (ROOM_WIDTH) * 64 - 192;
		ep->y = (y+1) * (ROOM_HEIGHT) * 64 - 1;

		ep = ep->next;
	}
}
