// BlinkGame - Hunt for the Lost Pixels
// an SDL game in honor of the BlinkenArea crew
//
// (C) 2005-06 Rene Schickbauer
//
// See License.txt for licensing information
//
#ifdef NOP_CODE
/*--------------------------------------------------------------------
					CVS AUTO-GENERATED INFO
$Author: cavac $
$Date: 2006/03/02 13:03:43 $
$Name: rel-0-3-patches $
$Revision: 1.7 $
$State: Exp $

$Log: tiles.cpp,v $
Revision 1.7  2006/03/02 13:03:43  cavac
Re-formatted all .cpp and .h files a bit to get rid of the TAB/SPACE mess
that makes troubles with XCode's "re-format" feature

Revision 1.6  2006/02/17 10:49:42  cavac
Added error-handling

Revision 1.5  2006/02/10 18:56:17  cavac
Code Audit: Fixed many 64Bit based problems (mostly untested)

Revision 1.4  2006/01/19 19:19:15  cavac
Various bugfixes and performance tunings

Revision 1.3  2006/01/18 01:22:39  cavac
Added SDL_Image to load additional graphics formats
Updated osdef* and xcode-project to to add SDL_Image
Updated all image-loader functions to use SDL_Image
Added level6 as temporary testlevel
Added code to display start- and goal-points with an animation (needs some fixing)
Removed temporary "marker"-tiles from level-definitions, as we have now an
animated display for that.

Revision 1.2  2006/01/09 00:50:34  cavac
Bugfixed CVS autogenerated entries in background.cpp
Added CVS autogenerated entries to remaining .cpp and .h files
Updated copyright from "2005 Rene Schickbauer" to "2005-06 Rene Schickbauer"


--------------------------------------------------------------------*/
#endif //NOP_CODE

#include "globals.h"
#include "tiles.h"
#include "levelhandler.h"
#include "blending.h"
#include "errorhandler.h"

SDL_Surface *TILES_Surface;

void initTiles(char *fname) {
	char fullfname[MAX_FNAME_LENGTH];
	sprintf(fullfname, "%s%s", RESPATH, fname);
	SDL_Surface* temp = IMG_Load(fullfname);
	if(!temp) {
		DIE(ERROR_IMAGE_READ, fullfname);
	}
	TILES_Surface = SDL_ConvertSurface(temp, gScreen->format, SDL_SWSURFACE);
	SDL_FreeSurface(temp);
}

void deInitTiles() {
	SDL_FreeSurface(TILES_Surface);
}

void paintSingleTile(Uint32 num, Sint32 x, Sint32 y) {
	if(num >= (Uint32)(TILES_Surface->h / TILESIZE)) {
		return; // Illegal tile
	}

	if(x < (1 - TILESIZE) || 
			y < (1 - TILESIZE) ||
			x > SCR_WIDTH || 
			y > SCR_HEIGHT) {
		return; // Tile is invisible so we ignore it
	}
	
	// Calculate offset in tiles-pixmap
	Uint32 xorigoffs = 0;
	Uint32 yorigoffs = 0;
	if(x < 0) {
		xorigoffs = -x;
	}
	if(y < 0) {
		yorigoffs = -y;
	}
	
	// Calculate HEIGHT/WIDTH of tiles to copy
	Uint32 width = TILESIZE;
	Uint32 height = TILESIZE;
	if(x > (SCR_WIDTH - TILESIZE)) {
		width = SCR_WIDTH - x;
	}
	if(y > (SCR_HEIGHT - TILESIZE)) {
		height = SCR_HEIGHT - y;
	}
	
	// -- Let's get blitting!!!
	if (SDL_MUSTLOCK(TILES_Surface))
		if (SDL_LockSurface(TILES_Surface) < 0)
			return;	

	Uint32 scrpitch = gScreen->pitch / 4;
	Uint32 tilpitch = TILES_Surface->pitch / 4;
	
	/*
	for(Uint32 ybg = yorigoffs; ybg < height; ybg++) { 
		for(Uint32 xbg = xorigoffs; xbg < width; xbg++) {
			((Uint32*)gScreen->pixels)[xbg + x + (y + ybg) * scrpitch] = 
				((Uint32*)TILES_Surface->pixels)[xbg + (ybg + num*TILESIZE) * tilpitch];
		}
	}
	*/
	
	Uint32 color;
	for(Uint32 ybg = yorigoffs; ybg < height; ybg++) { 
		for(Uint32 xbg = xorigoffs; xbg < width; xbg++) {
			color = ((Uint32*)TILES_Surface->pixels)[xbg + (ybg + num*TILESIZE) * tilpitch];
			
			if(color != 0x0000ff00) {
				((Uint32*)gScreen->pixels)[xbg + x + (y + ybg) * scrpitch] = color;
			}
			
		}
	}
	
	// Unlock if needed
	if (SDL_MUSTLOCK(TILES_Surface))
		SDL_UnlockSurface(TILES_Surface);
	
		
	return;
}

Uint32 getNumOfTiles() {
	return (TILES_Surface->h / TILESIZE + 1);
}


void paintLevelTiles(Uint32 xoffs, Uint32 yoffs) {
	DISPLAYLIST *tthis = lhandle.dlist;
	Sint32 xpos;
	Sint32 ypos;
	while(tthis) {
		xpos = tthis->x - xoffs;
		ypos = tthis->y - yoffs;		
		if(xpos > -TILESIZE && xpos < SCR_WIDTH && ypos > -TILESIZE && ypos < SCR_HEIGHT) {
			paintSingleTile(tthis->type, xpos, ypos);
		}
		tthis = tthis->next;
	}
}

void paintSpecialTiles(Uint32 xoffs, Uint32 yoffs, bool canExit) {
	Sint32 xpos;
	Sint32 ypos;
	Uint32 pitch = gScreen->pitch / 4;
	static Sint32 startcoloffs = 0;
	static Sint32 goalcoloffs = 0;
	Uint32 color;
	Uint32 tilecolor;
	static Sint32 lasttick = 0;
	Sint32 tick = SDL_GetTicks();
	
	// Ignore delays over 1 second
	if((lasttick + 1000) < tick) {
		lasttick = tick;
	}
	
	while(lasttick < tick) {
		startcoloffs = (startcoloffs + 1) % TILESIZE;
		goalcoloffs--;
		if(goalcoloffs < 0) {
			goalcoloffs = TILESIZE - 1;
		}
		lasttick += SPECIALTILEDELAY;
	}
	
	
	// START-TILE
	xpos = lhandle.start_x - xoffs;
	ypos = lhandle.start_y - yoffs;
	if(xpos > -TILESIZE && xpos < SCR_WIDTH && ypos > -TILESIZE && ypos < SCR_HEIGHT) {
		for(Sint32 x = xpos; x < (xpos + TILESIZE); x++) {
			if(x > 0 && x < SCR_WIDTH) {
				for(Sint32 y = ypos; y < (ypos + TILESIZE); y++) {
					if(y > 0 && y < SCR_HEIGHT) {
						color =  blend_mul(((Uint32*)gScreen->pixels)[x + y * pitch], 0x00707040);
						tilecolor = (((TILESIZE - (abs(x - xpos - TILESIZE/2) + abs(y - ypos - TILESIZE/2))) + startcoloffs) % TILESIZE) * 16;
						((Uint32*)gScreen->pixels)[x + y * pitch] =  blend_add(color, tilecolor);
					}
				}
			}
		}
	}
	
	
	// GOAL-TILE
	xpos = lhandle.goal_x - xoffs;
	ypos = lhandle.goal_y - yoffs;
	if(xpos > -TILESIZE && xpos < SCR_WIDTH && ypos > -TILESIZE && ypos < SCR_HEIGHT) {
		for(Sint32 x = xpos; x < (xpos + TILESIZE); x++) {
			if(x > 0 && x < SCR_WIDTH) {
				for(Sint32 y = ypos; y < (ypos + TILESIZE); y++) {
					if(y > 0 && y < SCR_HEIGHT) {
						if(canExit) {
							tilecolor = ((((TILESIZE - (abs(x - xpos - TILESIZE/2) + abs(y - ypos - TILESIZE/2))) + goalcoloffs) % TILESIZE) * 16) << 8;
							color =  blend_mul(((Uint32*)gScreen->pixels)[x + y * pitch], 0x00704070);
						} else {
							tilecolor = ((((TILESIZE - (abs(x - xpos - TILESIZE/2) + abs(y - ypos - TILESIZE/2))) + goalcoloffs) % TILESIZE) * 16) << 16;
							color =  blend_mul(((Uint32*)gScreen->pixels)[x + y * pitch], 0x00407070);
						}
						((Uint32*)gScreen->pixels)[x + y * pitch] =  blend_add(color, tilecolor);
					}
				}
			}
		}
	}
}

