/*
 * Viewer de fichier
 */

#include <fstream>

#include "CError.h"
#include "CSDLVideo.h"
#include "CCPCVideo.h"

#include "CCPCFileManager.h"

#include "CCPCScreenView.h"
#include "CCPCWindowView.h"
#include "CCPCFontView.h"

CCPCDataView *File = NULL;

bool loadScreen(std::string &i_filename)
{
	unsigned char *data;
	unsigned int size;

	COCPFileManager::loadScreen(i_filename,data,size);

	if (File != NULL)
		delete File;
	File = new CCPCScreenView(data,size);
	delete[] data;
	
	return true;
}

bool loadWindow(std::string &i_filename)
{
	unsigned char *data, *nData;
	unsigned int size,width, widtho, height;

	CCPCFileManager::loadRawData(i_filename,data,size);
	COCPFileManager::readWindow(data,size,nData,width,widtho,height);
	if (File != NULL)
		delete File;
	File = new CCPCWindowView(nData,size,widtho,height);
	
	delete[] data;
	delete[] nData;
	return true;
}

bool loadFont(std::string &i_filename)
{
	unsigned char *data;
	unsigned int size;

	CCPCFileManager::loadRawData(i_filename,data,size);
	if (File != NULL)
		delete File;
	File = new CCPCFontView(data,size);
	
	delete[] data;
	return true;
}

void loadFile(std::string &filename, CCPCVideo &scr)
{
	std::string fileExt;
	fileExt = filename.substr(filename.find_last_of('.')+1,filename.size()-(filename.find_last_of('.')+1));
	for (int i=0;i<fileExt.size();i++)
		fileExt[i] = toupper(fileExt[i]);

	if (fileExt == std::string("WIN"))
	{
		try
		{
			std::string pal;
			pal = filename.substr(0,filename.find_last_of('.')+1)+"PAL";
			int mode;
			unsigned int palette[16];
			if (COCPFileManager::loadPalette(pal,mode,palette))
			{
				scr.setMode((CPCVideoMode)mode);
				scr.setHardPalette(palette,16);
			}
		}
		catch (CException &e)
		{
			CERR(e);
		}
		loadWindow(filename);
		return;
	}
	if (fileExt == std::string("SCR"))
	{
		try
		{
			std::string pal;
			pal = filename.substr(0,filename.find_last_of('.')+1)+"PAL";
			int mode;
			unsigned int palette[16];
			if (COCPFileManager::loadPalette(pal,mode,palette))
			{
				scr.setMode((CPCVideoMode)mode);
				scr.setHardPalette(palette,16);
			}
		}
		catch (CException &e)
		{
			CERR(e);
		}
		loadScreen(filename);
		return;
	}
	
	loadScreen(filename);
}

int main(int argc, char **argv)
{
	COUT("cpcFileViewer (c) Ramlaid 2004");

	if (argc != 2)
	{
		CERR("No file to view !");
		return -1;
	}

	try
	{
		std::string filename = argv[1];

		CSDLVideo::init();

		CSDLVideo::setCaption("CPC File Viewer");

		CCPCVideo *scr = new CCPCVideo(Mode0,40,25);
		
		loadFile(filename,*scr);

		bool redisplay = true;
		while (!CSDLVideo::isSpacePressed())
		{
			if (redisplay)
			{
				redisplay = File->display(*scr);
			}
			SDLKey key;
			SDLMod mod;
			if (CSDLVideo::getKeyPressed(key,mod))
			{
				if (!File->keyPressed(*scr,key,mod,redisplay))
				{
					switch(mod & 0xfff)
					{
					case KMOD_NONE:
					{
						switch (key)
						{
						case SDLK_F1:{loadScreen(filename);redisplay = true;break;}
						case SDLK_F2:{loadWindow(filename);redisplay = true;break;}
						case SDLK_F3:{loadFont(filename);redisplay = true;break;}
						case SDLK_0 :{scr->setMode(Mode0);redisplay = true;break;}
						case SDLK_1 :{scr->setMode(Mode1);redisplay = true;break;}
						case SDLK_2 :{scr->setMode(Mode2);redisplay = true;break;}
						default:{break;}
						}
						break;
					}

					case KMOD_RCTRL:
					case KMOD_LCTRL:
						{
							int r1,r6;
							scr->getCRTCValue(r1,r6);
							switch (key)
							{
							case SDLK_UP:
								{
									r6--;
									scr->setCRTCValue(r1,r6);
									redisplay = true;
									break;
								}
							case SDLK_DOWN:
								{
									r6++;
									scr->setCRTCValue(r1,r6);
									redisplay = true;
									break;
								}
							case SDLK_LEFT:
								{
									r1--;
									scr->setCRTCValue(r1,r6);
									redisplay = true;
									break;
								}
							case SDLK_RIGHT:
								{
									r1++;
									scr->setCRTCValue(r1,r6);
									redisplay = true;
									break;
								}
							default:{break;}
							}
							break;
						}
					default:{break;}
					}
				}
			}
		}

		delete scr;
		if (File != NULL)
			delete File;
		CSDLVideo::finish();
	}
	catch (CException &e)
	{
		CERR(e);
		exit(-1);
	}
	return 0;
}
