#include <string.h>
#include "settings.h"

PlaybackMode Settings::playMode = MODE_SEQUENTIAL;
int Settings::masterX = 0;
int Settings::masterY = 0;
char Settings::themeName[128] = { 0 };

Settings::Settings()
{	
	// Remember that this is theme
	whichVars = 1;
	
	if(!_instance[whichVars])
	{
		// Ensure document pointer is null
		_document[whichVars] = NULL;
		
		// Ensure no invalid path
		skinPath[whichVars][0] = 0;
	}
	
	// Keep track of copies
	_instance[whichVars]++;
}

int Settings::loadSettings()
{
	// Wrapper to make things readable
	if(loadTheme(DATAPATH "settings.xml")) { return -1; }
	
	// Loader for wii drive light
	char setting[128];
	
	// Grab flashing light setting
	getString("DriveLight.Flash", setting);
	strlwr(setting);
	
	if(strcmp(setting, "yes") == 0)
	{
		// Enable light flashing
		sound.enableDiskLight(true);
	}
	else
	{
		// Disable light flashing
		sound.enableDiskLight(false);
	}
	
	// Loader for screen position
	Rect fLoc;
	if(getRect("Screen.Position", &fLoc) < 2)
	{
		// Defaults
		fLoc.x = X_LEFT;
		fLoc.y = Y_TOP;
	}
	
	// Remember master position
	setOffset(-fLoc.x, -fLoc.y);
	
	// Loader for theme
	getString("Theme.Name", themeName, "default");
	
	// Great success!!!!
	return 0;
}

int Settings::saveSettings()
{
	File f;
	int indent = 0;
	
	// Open settings
	if(f.open(DATAPATH "settings.xml", "w"))
	{
		return -1;
	}
	
	// Fake rectangle for screen position
	Rect tRect;
	tRect.x = -getOffsetX();
	tRect.y = -getOffsetY();
	
	// Write settings
	openSetting(f, "Settings", indent);
	
	openSetting(f, "Screen", indent);
	writeSetting(f, "Position", tRect, 2, indent);
	closeSetting(f, "Screen", indent);
	
	openSetting(f, "DriveLight", indent);
	writeSetting(f, "Flash", sound.getDiskLightEnabled() ? "yes" : "no", indent);
	closeSetting(f, "DriveLight", indent);
	
	openSetting(f, "Theme", indent);
	writeSetting(f, "Name", getTheme(), indent);
	closeSetting(f, "Theme", indent);
	
	closeSetting(f, "Settings", indent);
	
	// Finalize file
	f.close();
	
	return 0;
}

void Settings::openSetting(File &f, const char *setting, int &indent)
{
	char o = '<';
	char c = '>';
	char n = '\n';
	
	// Write in setting
	writeTabs(f, indent);
	f.write(&o, 1, 1);
	f.write(setting, 1, strlen(setting));
	f.write(&c, 1, 1);	
	f.write(&n, 1, 1);
	
	// Make sure indent goes up
	indent++;
}

void Settings::closeSetting(File &f, const char *setting, int &indent)
{
	char o = '<';
	char s = '/';
	char c = '>';
	char n = '\n';
	
	// Make sure indent goes down
	indent--;
	
	// Write in setting
	writeTabs(f, indent);
	f.write(&o, 1, 1);
	f.write(&s, 1, 1);
	f.write(setting, 1, strlen(setting));
	f.write(&c, 1, 1);	
	f.write(&n, 1, 1);
}

void Settings::writeSetting(File &f, const char *setting, const char *value, int indent)
{
	char o = '<';
	char s = '/';
	char c = '>';
	char n = '\n';
	
	// Write in setting
	writeTabs(f, indent);
	
	// Write open tag
	f.write(&o, 1, 1);
	f.write(setting, 1, strlen(setting));
	f.write(&c, 1, 1);
	
	// Write value
	f.write(value, 1, strlen(value));

	// Write close tag
	f.write(&o, 1, 1);
	f.write(&s, 1, 1);
	f.write(setting, 1, strlen(setting));
	f.write(&c, 1, 1);	
	f.write(&n, 1, 1);
}

void Settings::writeSetting(File &f, const char *setting, const int value, int indent)
{
	char tSetting[128];	
	sprintf(tSetting, "%d", value);
	
	// Write out integer
	writeSetting(f, setting, tSetting, indent);
}

void Settings::writeSetting(File &f, const char *setting, const Rect value, int entries, int indent)
{
	char tSetting[128];
	
	switch(entries)
	{
		case 1:
			sprintf(tSetting, "%d", value.x);
			break;
		case 2:
			sprintf(tSetting, "%d, %d", value.x, value.y);
			break;
		case 3:
			sprintf(tSetting, "%d, %d, %d", value.x, value.y, value.width);
			break;
		case 4:
			sprintf(tSetting, "%d, %d, %d, %d", value.x, value.y, value.width, value.height);
			break;
	}
	
	// Write out rect
	writeSetting(f, setting, tSetting, indent);
}

void Settings::writeTabs(File &f, int indent)
{
	char c = '\t';
	
	// Simply write out tabs to the file
	for(int i = 0; i < indent; i++)
	{
		f.write(&c, 1, 1);
	}
}

void Settings::setOffset(int x, int y)
{
	masterX = x;
	masterY = y;
}

int Settings::getOffsetX()
{
	return masterX;
}

int Settings::getOffsetY()
{
	return masterY;
}

char *Settings::getTheme()
{
	return themeName;
}

void Settings::setTheme(const char *theme)
{
	strcpy(themeName, theme);
}
