// 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/15 22:54:08 $
$Name: rel-0-3-patches $
$Revision: 1.11 $
$State: Exp $

$Log: levelhandler.cpp,v $
Revision 1.11  2006/03/15 22:54:08  cavac
* Added property/methods for setting FG objects as "ontop" which renders
them on top of everything.
* Changed levelhandler.* so that it uses the newly added "AddPixel" function
instead of doing it internally in the file parser state machine.
* Added functionality for bonus live collectables
* Adapted lua bindings so it can utilize above properties
* Removed l2b prefix from lua bindings and adapted scripts
* Added temporary 32x32 explosion graphics
* Adapted level0.bsl (Testlevel/scripting) so it has a small riddle:
  You have to turn on all switches and press the emergency stop button
  while the neon sign is ON (e.g. it lights up yellow). two small
  explosions leave one pixel and one bonus live collectible behind.
  (You can NOT finish the level without collecting the second pixel!)

Revision 1.10  2006/03/02 13:03:42  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.9  2006/02/24 20:25:39  cavac
Added sound-support to scripting engine

Revision 1.8  2006/02/24 18:48:26  cavac
Finally added real scripting support
Added Testlevel (level0) which can be enabled from globals.h

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

Revision 1.6  2006/01/23 18:47:55  cavac
Patches for unix make system for building on Linux  and other
Unix systems (thanks to: Dauti)
Tests for new colission detection (default: Use old one)
Added Joystick/Gamepad support (only tested with a cheap logitech gamepad)
Fixed some warnings on linux/gcc3
Added true-type fonts for planned menu system
Added library SDL_ttf in xcode for planned menu-system

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

Revision 1.4  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.3  2006/01/09 01:23:34  cavac
Changed level5 (the testlevel) to have exactly 300 pixels to pick up

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 "levelhandler.h"
#include "tiles.h"
#include "background.h"
#include "sound.h"
#include "drawprimitives.h"
#include "monstersprites.h"
#include "blending.h"
#include "errorhandler.h"
#include "fgobjects.h"
#include "bl_lua.h"

LEVELHANDLER lhandle;

#include <stdio.h>
#include <string.h>

void initLevel(Uint32 level) {
	char fullfname_conf[MAX_FNAME_LENGTH];
	sprintf(fullfname_conf, "%slevel%d.conf", RESPATH, level);
	
	// Prepare for LUA scripting
	initFGObjs();
	initSoundFXLua();
	
	lhandle.hasScript = false;
	lhandle.width = 0;
	lhandle.height = 0;
	lhandle.numBlocks = 0;
	lhandle.numPixels = 0;
	lhandle.dlist = 0;
	lhandle.pixels = 0;
	lhandle.numMonsters = 0;
	lhandle.monsters = 0;	
	
	FILE* fh;
	fh = fopen(fullfname_conf, "r");
	if(!fh) {
		DIE(ERROR_FILE_READ, fullfname_conf);
	}
	char key[MAX_STRING_LENGTH];
	char *tmp;
	char *val;
	while(fgets(key, sizeof(key), fh)) {
		if(key[0] == '#') {
			continue;
		}
		while((tmp = strstr(key, "\n"))) {
			*tmp = 0;
		}
		while((tmp = strstr(key, "\r"))) {
			*tmp = 0;
		}
		val = strstr(key, "=");
		if(!val) {
			continue;
		}
		*val = 0;
		val++;
		
		if(strcmp(key, "bg") == 0) {
			sprintf(lhandle.bgfile, val);
		} else if(strcmp(key, "snd") == 0) {
			sprintf(lhandle.sndfile, val);
		} else if(strcmp(key, "tiles") == 0) {
			sprintf(lhandle.tilesfile, val);
		} else if(strcmp(key, "script") == 0) {
			sprintf(lhandle.scriptfile, val);
			lhandle.hasScript = true;
		} else if(strcmp(key, "leveldata") == 0) {
			sprintf(lhandle.leveldata, val);
		} else if(strcmp(key, "leveltime") == 0) {
			lhandle.leveltime = atoi(val);
		} 
		
	}
	fclose(fh);
	
	
	soundStartMusic(lhandle.sndfile);	
	
	char fullfname_data[MAX_FNAME_LENGTH];
	sprintf(fullfname_data, "%s%s", RESPATH, lhandle.leveldata);
	
	fh = fopen(fullfname_data, "r");
	if(!fh) {
		DIE(ERROR_FILE_READ, fullfname_data);
	}
	char line[MAX_STRING_LENGTH];
	bool first_tile = true;
	Uint32 type;
	char tchar[2];
	tchar[1] = 0;
	Uint32 x = 0;
	Uint32 y = 0;
	DISPLAYLIST* thandle;
	DISPLAYLIST* lasthandle_tiles = 0;
	
	while(fgets(line, sizeof(line), fh)) {
		while((tmp = strstr(line, "\n"))) {
			*tmp = 0;
		}
		while((tmp = strstr(line, "\r"))) {
			*tmp = 0;
		}
		
		x = 0;
		printf("LINE: %s\n", line);
		for(Uint32 i = 0; i < strlen(line); i++) {
			tchar[0] = line[i];
			if(tchar[0] == '+') {
				lhandle.start_x = x;
				lhandle.start_y = y;
			} else if(tchar[0] == '-') {
				lhandle.goal_x = x;
				lhandle.goal_y = y;
			} else if(tchar[0] == '#') {
				addPixel(x, y, PIXELTYPE_PIXEL);
				incrementMaxPixels(1);
			} else if(tchar[0] == '*') {
				addPixel(x, y, PIXELTYPE_LIVE);				
			} else if(tchar[0] >= 65 && tchar[0] < 65 + MAX_MONSTER_TYPES) {
				addMonster(tchar[0] - 65, x, y);
			} else if((type = atoi(tchar)) > 0) {
				type--; // In file, first tile-type = 1 !!
				thandle = (DISPLAYLIST*)malloc(sizeof(DISPLAYLIST));
				thandle->type = type;
				thandle->x = x;
				thandle->y = y;
				thandle->next = 0;
				if(first_tile) {
					lhandle.dlist = thandle;
					first_tile = false;
				} else {
					lasthandle_tiles->next = thandle;
				}
				lasthandle_tiles = thandle;
				lhandle.numBlocks++;
			}
			x += TILESIZE;
			if(x > lhandle.width) {
				lhandle.width = x;
			}
		}
		y += TILESIZE;
		if(y > lhandle.height) {
			lhandle.height = y;
		}
	}
	
	printf("Max. Height: %d\n", lhandle.height);
	printf("Max. Width: %d\n", lhandle.width);
	printf("Max. Blocks: %d\n", lhandle.numBlocks);
	printf("Max. Pixels: %d\n", lhandle.numPixels);
	printf("Max. Monsters: %d\n", lhandle.numMonsters);
	
	initBackground(lhandle.bgfile);
	initTiles(lhandle.tilesfile);
	
	if(lhandle.hasScript) {
		printf("Script-File: %s\n", lhandle.scriptfile);
		blLuaInit(lhandle.scriptfile);
		blLuaCall("initLevel", "");
	}
	
	return;
}

void deInitLevel() {
	
	// deInit LUA add-ons
	deInitFGObjs();
	deInitSoundFXLua();
	
	if(lhandle.hasScript) {
		blLuaDeInit();
	}
	
	deInitTiles();
	deInitBackground();
	
	DISPLAYLIST* tthis;
	DISPLAYLIST* tnext = lhandle.dlist;
	tthis = lhandle.dlist; 
	while(tnext) {
		tnext = tthis->next;
		free(tthis);
		tthis = tnext;
	}
	lhandle.dlist = 0;
	
	freeMonsters();
	soundStopMusic();	
	
	return;
}

void addPixel(Uint32 x, Uint32 y, Uint32 pixeltype) {
	
	DISPLAYLIST* thandle = (DISPLAYLIST*)malloc(sizeof(DISPLAYLIST));
	thandle->type = pixeltype;
	thandle->x = x;
	thandle->y = y;
	thandle->next = 0;
	if(!lhandle.pixels) {
		lhandle.pixels = thandle;
	} else {
		// Find next pixel
		DISPLAYLIST *mhandle = lhandle.pixels;
		while(mhandle->next) {
			mhandle = mhandle->next;
		}
		mhandle->next = thandle;
	}				
}

void incrementMaxPixels(Uint32 count) {
	lhandle.numPixels += count;
}

void paintLevelPixels(Uint32 xoffs, Uint32 yoffs, Uint32 blinkbright) {
	DISPLAYLIST *tthis = lhandle.pixels;
	Uint32 color = blinkbright + blinkbright * 256 + blinkbright * 65536;
	Uint32 livecolor = (255 - blinkbright) + blinkbright * 65536;
	Sint32 xabs = 0;
	Sint32 yabs = 0;
	while(tthis) {
		xabs = tthis->x - xoffs;
		yabs = tthis->y - yoffs;
		if(tthis->type != PIXELTYPE_NONE && xabs > -TILESIZE && yabs > -TILESIZE && xabs < SCR_WIDTH && yabs < SCR_HEIGHT) {
			if(tthis->type == PIXELTYPE_PIXEL) {
				drawrect(xabs, yabs, TILESIZE, TILESIZE, 0x000000a0);
				drawrect(xabs + 2, yabs + 2, TILESIZE - 4, TILESIZE - 4, color);
			} else if(tthis->type == PIXELTYPE_LIVE) {
				drawrect(xabs + TILESIZE/3, yabs, TILESIZE/3, TILESIZE, 0x0000a000);
				drawrect(xabs, yabs + TILESIZE/3, TILESIZE, TILESIZE/3, 0x0000a000);
				drawrect(xabs + TILESIZE/3 + 1, yabs + 1, TILESIZE/3 - 2, TILESIZE - 2, livecolor);
				drawrect(xabs + 1, yabs + TILESIZE/3 + 1, TILESIZE - 2, TILESIZE/3 - 2, livecolor);
			}
			//drawcircle(tthis->x + TILESIZE / 2 - xoffs, tthis->y + TILESIZE / 2 - yoffs, TILESIZE / 3, color);
		}
		tthis = tthis->next;
	}
}

bool checkForTile(Uint32 x, Uint32 y) {
	DISPLAYLIST *tthis = lhandle.dlist;
	while(tthis) {
		if(tthis->x == x && tthis->y == y) {
			return true;
		}
		tthis = tthis->next;
	}
	
	return false;
}	
