/**********************************************************************

	Title :                 Map Module 
	Filename :              map.c
	Author :                Thomas Szirtes
	Revision :              2.0

	Notes :                 Responsible for reading, writing and interpreting
					the map data

	Copyright :             (C) SEGA Europe 1998

  **********************************************************************/


/*
 *      Includes
 */

#include        "file.h"
#include        "ftypes.h"
#include        "map.h"
#include        "tools.h"
#include        "future.h"

#ifndef         USING_SET4
#include        <stdio.h>
#endif


/*--------------------------------- PUBLIC FUNCTIONS --------------------------------------------// */

/*--------------------------------------------------------------------------
 
  void MAP_Init( void )

  Parameters:
	
  Returns:
 
  Notes:
	Initialize map
	
  --------------------------------------------------------------------------*/

void MAP_Init( void )
{
	int n,m;

	instance_count  =       0;

	/* initialize map items */
	for(n=0;n<MAP_SIZE;n++)
	{
		for(m=0;m<MAP_SIZE;m++)
		{
			map.map[n][m].inst      =       0xffff;                 /* clear instance number */
			map.map[n][m].gnd       =       0x00;
			map.map[n][m].ship      =       NO_SHIP_ID;
		}
	}
}



/*--------------------------------------------------------------------------
 
  void MAP_Save( char *filename )

  Parameters:
	filename        filename to save to
	
  Returns:
 
  Notes:
	Not effective on set4
	
  --------------------------------------------------------------------------*/

void MAP_Save( char *filename )
{
#ifndef USING_SET4
	FILE    *fd;
	int             n;
	int             version =       MAP_VERSION_1;
	
	/* open file for writing */
	fd      =       fopen(filename,"wb");

	/* save out version stamp */
	fwrite( &version, sizeof( int ), 1, fd );

	/* save out size */
	fwrite( &instance_count, sizeof( int ), 1, fd );

	/* save out data */
	for(n=0;n<instance_count;n++)
	{
		fwrite( &build_inst[n], sizeof( BUILDING_INSTANCE ), 1, fd );
	}

	fclose(fd);
#endif
}



/*--------------------------------------------------------------------------
 
  void MAP_Load( char *filename )

  Parameters:
	filename        filename to load from
	
  Returns:
 
  Notes:
	Loads map data and builds internal structures from it

  --------------------------------------------------------------------------*/

void MAP_Load( char *filename )
{
	int         t;
	Uint16		index;
	Sint8		n,m;
	int         version;
	int         i,j;
	Uint8		orient;
	float		height_factor;
#ifdef USING_SET4
	GDFS    fd;
#else
	FILE            *fd;
#endif

	MAP_Init();

	/* Open file */
	orient  =       0;

#ifdef USING_SET4
	fd      =       gdFsOpen(filename,NULL);
#else
	fd      =       fopen(filename,"rb");
#endif

	if (fd==NULL) return;

	/* read version stamp */
#ifdef USING_SET4
	t_fread( (Uint8 *)&version, sizeof( int ), 1, fd );
#else
	fread( (Uint8 *)&version, sizeof( int ), 1, fd );
#endif

	if (version!=MAP_VERSION_1)
	{
          return;
	}
			
	/* Read file */
#ifdef USING_SET4
	t_fread( (Uint8 *)&instance_count, sizeof(int), 1, fd );
#else
	fread( (Uint8 *)&instance_count, sizeof(int), 1, fd );
#endif

	for(t=0;t<instance_count;t++)
	{
#ifdef USING_SET4
		t_fread( (Uint8 *)&build_inst[t], sizeof(BUILDING_INSTANCE), 1, fd );
#else
		fread( &build_inst[t], sizeof(BUILDING_INSTANCE), 1, fd );
#endif
	}

#ifdef USING_SET4
	gdFsClose(fd);
#else
	fclose(fd);
#endif

	/* build map from instance */
	for (t=0;t<instance_count;t++)
	{
		if(build_inst[t].id!=0xff)
		{
			if(build_inst[t].id<MAX_BUILDINGS)
			{
			/* temporary adjustment - offset map by a certain number of units */
			build_inst[t].j	+=	18;
				
			/* place root */
			map.map[build_inst[t].i][build_inst[t].j].inst  =       t;
			if (buildings[build_inst[t].id].shadow != NULL)
			{
				index           =       0;
				orient          =       build_inst[t].flag & INST_FLAG_ORIENT_MASK;
				/* switch on orientation */
				switch (orient)
				{
				case INST_FLAG_ORIENT0  :       orient  =       0; break;
				case INST_FLAG_ORIENT1  :       orient  =       1; break;
				case INST_FLAG_ORIENT2  :       orient  =       2; break;
				case INST_FLAG_ORIENT3  :       orient  =       3; break;
				}
				while (GetBuildingShadow(build_inst[t].id, &n, &m, index++, orient)!=0)
				{
					map.map[build_inst[t].i+(int)n][build_inst[t].j+(int)m].inst    =       t;
				}
			}
			}
		}
	}

	/* Generate floor heights - flatten floor under buildings */
	for(j=0;j<MAP_SIZE;j++)
	{
		for(i=0;i<MAP_SIZE;i++) 
		{
			height_factor   =       njSqrt( (float)(((64-i)*(64-i)) + ((64-j)*(64-j))) );
			if (height_factor <50.f) 
			{
				if (map.map[i][j].inst==0xffff)
					map.map[i][j].gnd       = (Uint8)(((Uint8)GenerateRandom()%100)+57);
				else
					map.map[i][j].gnd       =       75;
			}
			else
			{
				if (map.map[i][j].inst==0xffff)
					map.map[i][j].gnd       = 0;
				else
					map.map[i][j].gnd       =       70;
			}
			map.map[i][j].ship              =       -1;
			}

	}
		
}
