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

	Bubble Fight EX
	relminator
	http://rel.betterwebber.com


	Level class


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

#include "Level.h"

//--------------------------------------
//	Ctor and Dtor
//--------------------------------------
Level::Level()
{
	Width	= MAP_WIDTH;
	Height	= MAP_HEIGHT;
	
	CameraX = 0;
	CameraY = 0;
	
	TileX 	= 0;
	TileY 	= 0;
	
	PixelX 	= 0;
	PixelY 	= 0;
	
}

Level::~Level()
{
}


//--------------------------------------
//	
//--------------------------------------
void Level::Init( int Palette, glImage* const Sprites,  int stage )
{
	
	Width	= MAP_WIDTH;
	Height	= MAP_HEIGHT;
	
	CameraX = 0;
	CameraY = 0;
	
	TileX 	= 0;
	TileY 	= 0;
	
	PixelX 	= 0;
	PixelY 	= 0;
	
	ColorTable = Palette;		// init needed data for drawing
	Tiles = Sprites;
	
	
	// Fill Map
	switch( stage ) // Level 01
	{
		case 1:
			for( int y = 0; y < MAP_HEIGHT; y++ )
			{
				for( int x = 0; x < MAP_WIDTH; x++ ) 
				{
					
					map[x][y] = ( (y & 15)* 8 + (x & 7) ) & 255;
				}
			}
			break;
		case 2:
			// Level 02
			for( int y = 0; y < MAP_HEIGHT; y++ )
			{
				for( int x = 0; x < MAP_WIDTH; x++ ) 
				{
					
					map[x][y] = ( (y & 3)* 16 + (x & 15) ) & 255;
				}
			}
			break;
		default:
			for( int y = 0; y < MAP_HEIGHT; y++ )
			{
				for( int x = 0; x < MAP_WIDTH; x++ ) 
				{
					
					map[x][y] = ( (y & 15)* 8 + (x & 7) ) & 255;
				}
			}
			
	}  // stage switch
	
}


//--------------------------------------
//	
//--------------------------------------
void Level::Update( int Stage, int Frame )
{

	switch( Stage )
	{
		case 1:			// none tunnel is auto updated
			break;
		case 2:			// 2d scroller
			UpdateMap( floattof32(1.5) );
			break;
		case 3:			
			break;
		case 4:        // mode7 and supershapes
			Fx3D::Instance()->UpdateShapes();
			
	}
		
	
		
	
}
	

//--------------------------------------
//	
//--------------------------------------
void Level::Draw3D( int Stage, int Frame ) const
{

	switch( Stage )
	{
		case 1:			// tunnel
			Fx3D::Instance()->DrawAscaris();
			break;
		case 2:			// 2d scroller is 2d so no
			break;
		case 3:
			Fx3D::Instance()->DrawAscaris2();
			break;
		case 4:			// mode7 and supershapes
			Fx3D::Instance()->DrawGrid();
			Fx3D::Instance()->DrawShapes();
	
	}
		
	
}

//--------------------------------------
//	
//--------------------------------------
void Level::Draw2D( int Stage, int Frame ) const
{

	switch( Stage )
	{
		case 1:			// tunnel is 3d
			break;
		case 2:			// 2d scroller is 2d so draw
			DrawMap();
			
	}
		
	
}

//--------------------------------------
//	
//--------------------------------------
void Level::UpdateMap( s32 speed )
{
	const int TILE_SIZE = 16;
 
	// update the camera
	CameraX += speed >> 12;
	CameraY = 0;
	
	// limit camera X values
	if ( CameraX > ((Width) * TILE_SIZE ) - SCREEN_WIDTH )
	{
		CameraX = 0;
	}
	
	
	// calculate level starting tiles
	TileX = CameraX / TILE_SIZE; 
	TileY = CameraY / TILE_SIZE; 
	
	// calculate tile pixel offsets
	// Only works with power of 2 tilesize
	// use "%" for non-power of 2 sizes
	PixelX = CameraX & (TILE_SIZE - 1);
	PixelY = CameraY & (TILE_SIZE - 1);
	
}


//--------------------------------------
//	
//--------------------------------------
void Level::DrawMap( int Palette ) const
{
	if( Palette )
		glColorTable( GL_RGB256, Palette );
	else
		glColorTable( GL_RGB256, ColorTable );
	
	// tiles are 16x16 pixels
	const int TILE_SIZE = 16;
 
	// calculate number of tiles per row and column
	const int SCREEN_TILE_X = SCREEN_WIDTH / TILE_SIZE;
	const int SCREEN_TILE_Y = SCREEN_HEIGHT / TILE_SIZE;
	
	// we need to draw an extra tile at the bottom and right 
	// since we are scrolling
	for( int y = 0; y < SCREEN_TILE_Y; y++ )
	{
		for( int x = 0; x <= SCREEN_TILE_X; x++ ) 
		{
			int tile_x = TileX + x;		// get relative tile positions
			int tile_y = TileY + y;
			int i = map[tile_x][tile_y];		// get map index
			if( i >= 0 )
			{
				int screen_x = (x * TILE_SIZE) - PixelX;      //Calculate where to put a
				int screen_y = (y * TILE_SIZE) - PixelY;      //particular tile
				glSprite(screen_x, screen_y, GL_FLIP_NONE , &Tiles[i]);
			}
		}
	}
	
}

