#include "SettingsDialogs.h"

#include "Settings.h"
#include "Project.h"

#include "Theme.h"

#include <plugin/astyle/astyle.h>

static void HlPusherFactory(One<Ctrl>& ctrl)
{
	ctrl.Create<ColorPusher>().Track();
}

// constructor
SettingsDialog::SettingsDialog()
{
	CtrlLayout(compiler);
	CtrlLayout(uploader);
	CtrlLayout(editor);
	CtrlLayout(ide);
	CtrlLayout(theme);
	CtrlLayout(formatter);
	CtrlLayout(locations);

	CtrlLayout(fonts);
	CtrlLayout(colors);
	CtrlLayout(hilight);
	
	CtrlLayout(*this);

	settingsTab.Crosses(false);
	settingsTab.AddCtrl(compiler,	t_("Compiler"));
	settingsTab.AddCtrl(uploader,	t_("Uploader"));
	settingsTab.AddCtrl(editor,		t_("Editor"));
	settingsTab.AddCtrl(ide,		t_("Ide"));
	settingsTab.AddCtrl(theme,		t_("Theme"));
	settingsTab.AddCtrl(formatter,	t_("Formatter"));
	settingsTab.AddCtrl(locations,	t_("Files locations"));
	
	theme.themeTab.Crosses(false);
	theme.themeTab.AddCtrl(fonts,	t_("Fonts"));
	theme.themeTab.AddCtrl(colors,	t_("Colors"));
	theme.themeTab.AddCtrl(hilight,	t_("Syntax highlight"));
	theme.themeTab.SetCursor(0);
	
	colors.colors.AddColumn("Style");
	colors.colors.AddColumn("Color").Ctrls(HlPusherFactory);
	colors.colors.ColumnWidths("211 80");
	colors.colors.EvenRowColor().NoHorzGrid().SetLineCy(EditField::GetStdHeight() + 2);
	
	hilight.hlstyle.AddColumn("Style");
	hilight.hlstyle.AddColumn("Color").Ctrls(HlPusherFactory);
	hilight.hlstyle.AddColumn("Bold").Ctrls<Option>();
	hilight.hlstyle.AddColumn("Italic").Ctrls<Option>();
	hilight.hlstyle.AddColumn("Underline").Ctrls<Option>();
	hilight.hlstyle.ColumnWidths("211 80 45 45 80");
	hilight.hlstyle.EvenRowColor().NoHorzGrid().SetLineCy(EditField::GetStdHeight() + 2);
	
	fonts.ideFontDrop.Clear();
	fonts.editorFontDrop.Clear();
	fonts.consoleFontDrop.Clear();
	fonts.serialPortFontDrop.Clear();
	int faceCount = Font::GetFaceCount();
	VectorMap<Value, Value> faces;
	for(int i = 0; i < faceCount; i++)
	{
		String name = Font::GetFaceName(i);
		if(faces.Find(name) < 0)
			faces.Add(name, name);
	}
	SortByKey(faces, [](String const &a, String const &b) { return ToUpper(a) < ToUpper(b); });
	fonts.ideFontDrop *= faces;
	fonts.editorFontDrop *= faces;
	fonts.consoleFontDrop *= faces;
	fonts.serialPortFontDrop *= faces;

	fonts.ideFontHeight.Clear();
	fonts.editorFontHeight.Clear();
	fonts.consoleFontHeight.Clear();
	fonts.serialPortFontHeight.Clear();
	for(int i = 6; i < 64; i++)
	{
		fonts.ideFontHeight.Add(i);
		fonts.editorFontHeight.Add(i);
		fonts.consoleFontHeight.Add(i);
		fonts.serialPortFontHeight.Add(i);
	}
	
	// fill theme data
	fillThemeDrop();
	fillTheme();
	
	// setup theme selector callback
	theme.themeDrop <<= THISBACK(themeDropCb);
	theme.newThemeBtn <<= THISBACK(newThemeCb);
	theme.removeThemeBtn <<= THISBACK(removeThemeCb);
	theme.renameThemeBtn <<= THISBACK(renameThemeCb);
	theme.exportThemeBtn <<= THISBACK(exportThemeCb);
	theme.importThemeBtn <<= THISBACK(importThemeCb);
	theme.previewThemeBtn <<= THISBACK(testThemeCb);

	// connect buttons
	okBtn.Ok() << Acceptor(IDOK);
	cancelBtn.Cancel() << Rejector(IDCANCEL);
	
	// load data from global settings
	compiler.warningSwitch			= Settings.GetCompilerWarnLevel();
	compiler.warningEdit			= Settings.GetCompilerUserWarnings();
	compiler.warningEdit.Enable(Settings.GetCompilerWarnLevel() == 4);
	compiler.verbositySwitch		= Settings.GetCompilerVerbosity();
	compiler.optimizationSwitch		= Settings.GetCompilerOptimizations();
	compiler.forceRebuildOption		= Settings.GetCompilerFullRebuild();
	compiler.libAutoDependOption	= Settings.GetCompilerAutoLibDependencies();
	
	compiler.warningSwitch <<= THISBACK(userWarnCb);
	userWarnCb();
	
	uploader.verbositySwitch		= Settings.GetUploaderVerbosity();
	
	ide.projectStubsOption			= Settings.GetIdeCreateProjectStubs();
	ide.libraryStubsOption			= Settings.GetIdeCreateLibraryStubs();
	ide.rememberFilesOption			= Settings.GetIdeRememberFiles();
	ide.rememberProjectOption		= Settings.GetIdeRememberProjects();
	ide.sysReadOnlyOption			= Settings.GetIdeSysLibsReadOnly();
	ide.splashOption				= Settings.GetIdeShowSplash();

	editor.tabsize					<<= Settings.GetEditorTabsize();
	editor.indentAmount				<<= Settings.GetEditorIndentAmount();
	editor.showTabs					= Settings.GetEditorShowTabs();
	editor.indentSpaces				= Settings.GetEditorIndentSpaces();
	editor.noParenthesisIndent		= Settings.GetEditorNoParenthesisIndent();
	editor.showLineNumbers			= Settings.GetEditorShowLineNumbers();
	editor.bookmarkPos				= Settings.GetEditorBookmarkPos();
	editor.findpicksel				= Settings.GetEditorFindpicksel();
	editor.findpicktext				= Settings.GetEditorFindpicktext();
	editor.persistentFindReplace	= Settings.GetEditorPersistentFindReplace();
	editor.findReplaceRestorePos	= Settings.GetEditorFindReplaceRestorePos();
	editor.autoEnclose				= Settings.GetEditorAutoEnclose();

	formatter.BracketFormatMode.Add(astyle::NONE_MODE, t_("none"));
	formatter.BracketFormatMode.Add(astyle::ATTACH_MODE, t_("attach"));
	formatter.BracketFormatMode.Add(astyle::BREAK_MODE, t_("break"));
	formatter.ParensPaddingMode.Add(astyle::PAD_NONE, t_("no space pad around parenthesis"));
	formatter.ParensPaddingMode.Add(astyle::PAD_INSIDE, t_("pad parenthesis inside with space"));
	formatter.ParensPaddingMode.Add(astyle::PAD_OUTSIDE, t_("pad parenthesis outside with space"));
	formatter.ParensPaddingMode.Add(astyle::PAD_BOTH, t_("pad both parenthesis sides with spaces"));
	
	formatter.BracketIndent						= Settings.GetAstyleBracketIndent();
	formatter.NamespaceIndent					= Settings.GetAstyleNamespaceIndent();
	formatter.BlockIndent						= Settings.GetAstyleBlockIndent();
	formatter.CaseIndent						= Settings.GetAstyleCaseIndent();
	formatter.ClassIndent						= Settings.GetAstyleClassIndent();
	formatter.LabelIndent						= Settings.GetAstyleLabelIndent();
	formatter.SwitchIndent						= Settings.GetAstyleSwitchIndent();
	formatter.PreprocessorIndent				= Settings.GetAstylePreprocessorIndent();
	formatter.MinInStatementIndentLength		= Settings.GetAstyleMinInStatementIndentLength();
	formatter.MaxInStatementIndentLength		= Settings.GetAstyleMaxInStatementIndentLength();
	formatter.BreakClosingHeaderBracketsMode	= Settings.GetAstyleBreakClosingHeaderBracketsMode();
	formatter.BreakElseIfsMode					= Settings.GetAstyleBreakElseIfsMode();
	formatter.BreakOneLineBlocksMode			= Settings.GetAstyleBreakOneLineBlocksMode();
	formatter.SingleStatementsMode				= Settings.GetAstyleSingleStatementsMode();
	formatter.BreakBlocksMode					= Settings.GetAstyleBreakBlocksMode();
	formatter.BreakClosingHeaderBlocksMode		= Settings.GetAstyleBreakClosingHeaderBlocksMode();
	formatter.BracketFormatMode.SetIndex(Settings.GetAstyleBracketFormatMode());
	formatter.ParensPaddingMode.SetIndex(Settings.GetAstyleParensPaddingMode());
	formatter.ParensUnPaddingMode				= Settings.GetAstyleParensUnPaddingMode();
	formatter.OperatorPaddingMode				= Settings.GetAstyleOperatorPaddingMode();
	formatter.EmptyLineFill						= Settings.GetAstyleEmptyLineFill();
	formatter.TabSpaceConversionMode			= Settings.GetAstyleTabSpaceConversionMode();

	formatter.TestBox.Set((String)
		"#include <stdio.h>\n"
		"#ifndef __abcd_h\n"
		"#include <abcd.h>\n"
		"#endif\n"
		"\n"
		"void test(int a, int b)\n"
		"{\n"
		"  /* this is a switch */\n"
		"  switch(a)\n"
		"\n"
		"  {\n"
		"    case 1:\n"
		"      b = 2;\n"
		"      break;\n"
		"    case 2:\n"
		"      b = 4;\n"
		"      break;\n"
		"    default:\n"
		"    break;\n"
		"  }\n"
		"\n"
		"  /* this are more statements on one line */\n"
		"  a = 2*a;b=-5;a=2*(b+2)*(a+3)/4;\n"
		"\n"
		"  /* single line blocks */\n"
		"  {int z;z = 2*a+b;}\n"
		"\n"
		"  /* loop */\n"
		"  for(int i = 0;i< 10;i++) { a = b+2*i;}\n"
		"\n"
		"}\n"
	);
	formatter.Test <<= THISBACK(astyleTest);
	formatter.Defaults << THISBACK(astyleDefaults);

	locations.sketchbookFolder		= Settings.GetSketchFolder();
	locations.packagesURLsEdit.Set(Settings.GetPackagesURLs());
	locations.librariesURLsEdit.Set(Settings.GetLibrariesURLs());
	locations.examplesURLsEdit.Set(Settings.GetExamplesURLs());

	// backup settings
	settingsBackup = StoreAsXML(Settings, "");
	
	// backup themes
	themesBackup = StoreAsXML(Themes, "");
	currentTheme = Themes.GetCurrent();

	if(Settings.GetSketchFolder().IsEmpty())
		settingsTab.SetCursor(5);
	else
		settingsTab.SetCursor(0);
}

// destructor
SettingsDialog::~SettingsDialog()
{
}

// react to theme selection
void SettingsDialog::themeDropCb(void)
{
	// store current theme data
	storeTheme();
	activeTheme = theme.themeDrop.GetIndex();
	fillTheme();
}

// fill themes droplist
void SettingsDialog::fillThemeDrop(void)
{
	Vector<String> themes = Themes.GetNames();
	theme.themeDrop.Clear();
	for(int i = 0; i < themes.GetCount(); i++)
		theme.themeDrop.Add(themes[i]);
	int curr = Themes.GetCurrentIndex();
	if(curr >= 0 && curr < themes.GetCount())
		activeTheme = curr;
	else if(theme.themeDrop.GetCount())
		activeTheme = 0;
	theme.themeDrop.SetIndex(activeTheme);
}

static void SetFontLine(Theme::FontInfo const &fi, DropList &fd, DropList &hd, Option &bold, Option &italic, Option &nn)
{
	int idx = fd.Find(fi._name);
	if(idx >= 0)
		fd.SetIndex(idx);
	else
		fd.Adjust(Font::GetStdFont().GetFaceName());
	int h = fi._height;
	h = max(h, 6);
	h = min(h, 63);
	hd.SetIndex(h - 6);
	bold <<= fi._bold;
	italic <<= fi._italic;
	nn <<= fi._nonAntiAliased;
}

// fill theme dialogs
void SettingsDialog::fillTheme(void)
{
	String name;
	
	// we suppose that default theme is always present
	Theme const *theme = Themes.Get(activeTheme);
	if(!theme)
		return;
	
	// font data
	SetFontLine(theme->GetIdeFontInfo()			, fonts.ideFontDrop, fonts.ideFontHeight, fonts.ideFontBold, fonts.ideFontItalic, fonts.ideFontNonAntialiased);
	SetFontLine(theme->GetEditorFontInfo()		, fonts.editorFontDrop, fonts.editorFontHeight, fonts.editorFontBold, fonts.editorFontItalic, fonts.editorFontNonAntialiased);
	SetFontLine(theme->GetConsoleFontInfo()		, fonts.consoleFontDrop, fonts.consoleFontHeight, fonts.consoleFontBold, fonts.consoleFontItalic, fonts.consoleFontNonAntialiased);
	SetFontLine(theme->GetSerialPortFontInfo()	, fonts.serialPortFontDrop, fonts.serialPortFontHeight, fonts.serialPortFontBold, fonts.serialPortFontItalic, fonts.serialPortFontNonAntialiased);
	
	// color data
	VectorMap<String, Color> const &col = theme->GetColors();
	colors.colors.Clear();
	for(int i = 0; i < col.GetCount(); i++)
		colors.colors.Add(col.GetKey(i), col[i]);
	
	// syntax highlight data
	VectorMap<String, Theme::HL> const &syntax = theme->GetSyntax();
	hilight.hlstyle.Clear();
	for(int i = 0; i < syntax.GetCount(); i++)
		hilight.hlstyle.Add(syntax.GetKey(i), syntax[i]._color, syntax[i]._bold, syntax[i]._italic, syntax[i]._underline);
	
	hilight.hilite_scope		= theme->GetScopeHL();
	hilight.hilite_bracket		= theme->GetBracesHL();
	hilight.hilite_ifdef		= theme->GetConditionalsInfo();
	hilight.hilite_if_endif		= theme->GetConditionalTracing();
	hilight.thousands_separator	= theme->GetThousandsSeparator();
	hilight.hline				= theme->GetCurrentLine();

	// theme 0 is read only, so fix controls if needed
	bool ro = (activeTheme == 0);

	Ctrl *child = fonts.GetFirstChild();
	while(child)
	{
		child->Enable(!ro);
		child = child->GetNext();
	}
		
	for(int i = 0; i < colors.colors.GetCount(); i++)
		colors.colors.GetCtrl(i, 1)->Enable(!ro);

	for(int i = 0; i < hilight.hlstyle.GetCount(); i++)
		for(int j = 1; j < 5; j++)
			hilight.hlstyle.GetCtrl(i, j)->Enable(!ro);
		
	hilight.hlstyle.SetEditable(!ro);
	hilight.hilite_scope.SetEditable(!ro);
	hilight.hilite_bracket.SetEditable(!ro);
	hilight.hilite_ifdef.SetEditable(!ro);
	hilight.hilite_if_endif.SetEditable(!ro);
	hilight.thousands_separator.SetEditable(!ro);
	hilight.hline.SetEditable(!ro);
	hilight.hl_restore.Enable(!ro);
}

static void GetFontLine(Theme::FontInfo &fi, DropList &fd, DropList &hd, Option &bold, Option &italic, Option &nn)
{
	fi._name			= fd.Get();
	fi._height			= hd.GetIndex() + 6;
	fi._bold			= ~bold ? true : false;
	fi._italic			= ~italic ? true : false;
	fi._nonAntiAliased	= ~nn ? true : false;
}

// store theme data into currenttheme
void SettingsDialog::storeTheme(void)
{
	// do not modify theme 0
	if(activeTheme == 0)
		return;
	Theme *t = Themes.Get(activeTheme);
	if(!t)
		return;
	
	// font data
	GetFontLine(t->GetIdeFontInfo()			, fonts.ideFontDrop, fonts.ideFontHeight, fonts.ideFontBold, fonts.ideFontItalic, fonts.ideFontNonAntialiased);
	GetFontLine(t->GetEditorFontInfo()		, fonts.editorFontDrop, fonts.editorFontHeight, fonts.editorFontBold, fonts.editorFontItalic, fonts.editorFontNonAntialiased);
	GetFontLine(t->GetConsoleFontInfo()		, fonts.consoleFontDrop, fonts.consoleFontHeight, fonts.consoleFontBold, fonts.consoleFontItalic, fonts.consoleFontNonAntialiased);
	GetFontLine(t->GetSerialPortFontInfo()	, fonts.serialPortFontDrop, fonts.serialPortFontHeight, fonts.serialPortFontBold, fonts.serialPortFontItalic, fonts.serialPortFontNonAntialiased);

	// color data
	VectorMap<String, Color> cols;
	for(int i = 0; i < colors.colors.GetCount(); i++)
		cols.Add(colors.colors.Get(i, 0), colors.colors.Get(i, 1));
	t->SetColors(cols); 

	// syntax highlight data
	VectorMap<String, Theme::HL> syntax;
	for(int i = 0; i < hilight.hlstyle.GetCount(); i++)
		syntax.Add(hilight.hlstyle.Get(i, 0), Theme::HL(hilight.hlstyle.Get(i, 1), hilight.hlstyle.Get(i, 2), hilight.hlstyle.Get(i, 3), hilight.hlstyle.Get(i, 4)));
	t->SetSyntax(syntax);

	t->SetScopeHL(hilight.hilite_scope);
	t->SetBracesHL(hilight.hilite_bracket);
	t->SetConditionalsInfo(hilight.hilite_ifdef);
	t->SetConditionalTracing(hilight.hilite_if_endif);
	t->SetThousandsSeparator(hilight.thousands_separator);
	t->SetCurrentLine(hilight.hline);
}

// themes buttons handlers
void SettingsDialog::newThemeCb(void)
{
	WithSettingsNewThemeLayout<TopWindow> dlg;
	CtrlLayout(dlg);
	dlg.newThemeOkBtn.Ok() <<= dlg.Acceptor(IDOK);
	dlg.newThemeCancelBtn.Cancel() <<= dlg.Rejector(IDCANCEL);
	Vector<String> const &names = Themes.GetNames();
	dlg.themeDrop.Clear();
	for(int i = 0; i < names.GetCount(); i++)
		dlg.themeDrop.Add(names[i]);
	dlg.themeDrop.SetIndex(theme.themeDrop.GetIndex());

	dlg.themeNameEdit.Clear();
	while(true)
	{
		int res = dlg.Execute();
		if(res != IDOK)
			return;
		String name = ~dlg.themeNameEdit;
		if(FindIndex(names, name) >= 0)
		{
			Exclamation(Format(t_("Theme '%s' already exists&Please choose another name"), name));
			continue;
		}
		Theme const *base = Themes.Get(dlg.themeDrop.Get().ToString());
		if(!base)
			base = Themes.Get(0);
		Themes.Add(name, *base);

		// store current theme data
		storeTheme();
		
		// refill droplist and select addet theme
		fillThemeDrop();
		activeTheme = Themes.GetCount() - 1;
		theme.themeDrop.SetIndex(activeTheme);
		
		// get theme data
		fillTheme();
		break;
	}
}

void SettingsDialog::renameThemeCb(void)
{
	WithSettingsRenameThemeLayout<TopWindow> dlg;
	CtrlLayout(dlg);
	dlg.okBtn.Ok() <<= dlg.Acceptor(IDOK);
	dlg.cancelBtn.Cancel() <<= dlg.Rejector(IDCANCEL);

	dlg.themeNameEdit <<= theme.themeDrop.Get();
	while(true)
	{
		int res = dlg.Execute();
		if(res != IDOK)
			return;
		String name = ~dlg.themeNameEdit;
		if(theme.themeDrop.Find(name) >= 0)
		{
			Exclamation(Format(t_("Theme '%s' already exists&Please choose another name"), name));
			continue;
		}
		Themes.Rename(theme.themeDrop.Get(), name);
		
		// refill droplist and select addet theme
		fillThemeDrop();
		break;
	}
}

void SettingsDialog::exportThemeCb(void)
{
	FileSel fs;
	fs.Type("FishIDE themes", "*.fishtheme");
	fs.ActiveDir(Settings.GetSketchFolder());
	fs.Set(theme.themeDrop.Get());
	if(fs.ExecuteSaveAs(t_("Export theme")))
	{
		String path = fs.Get();
		Theme *t = Themes.Get(activeTheme);
		StoreAsXMLFile(*t, String(theme.themeDrop.Get()), path);
	}
}

void SettingsDialog::importThemeCb(void)
{
	FileSel fs;
	fs.Type("FishIDE themes", "*.fishtheme");
	fs.ActiveDir(Settings.GetSketchFolder());
	if(fs.ExecuteOpen(t_("Import theme")))
	{
		String path = fs.Get();
		String name = GetFileTitle(path);
		if(theme.themeDrop.Find(name) >= 0)
		{
			WithSettingsRenameThemeLayout<TopWindow> dlg;
			CtrlLayout(dlg);
			dlg.okBtn.Ok() <<= dlg.Acceptor(IDOK);
			dlg.cancelBtn.Cancel() <<= dlg.Rejector(IDCANCEL);
			dlg.themeNameEdit <<= name;
			while(true)
			{
				int res = dlg.Execute();
				if(res != IDOK)
					return;
				name = ~dlg.themeNameEdit;
				if(theme.themeDrop.Find(name) >= 0)
				{
					Exclamation(Format(t_("Theme '%s' already exists&Please choose another name"), name));
					continue;
				}
				break;
			}
		}
		try
		{
			Theme t;
			TryLoadFromXMLFile(t, path);
			Themes.Add(name, t);

			// refill droplist and select addet theme
			fillThemeDrop();
			activeTheme = Themes.GetCount() - 1;
			theme.themeDrop.SetIndex(activeTheme);
			
			// get theme data
			fillTheme();
			return;
		}
		catch(...)
		{
			Exclamation(t_("Error importing theme"));
			return;
		}
	}
}


void SettingsDialog::removeThemeCb(void)
{
	Themes.Remove(activeTheme);
	fillThemeDrop();
	activeTheme = 0;
	theme.themeDrop.SetIndex(activeTheme);
	fillTheme();
}

void SettingsDialog::testThemeCb(void)
{
	// store current theme data
	storeTheme();
		
	Theme const *theme = Themes.Get(activeTheme);
	if(!theme)
		return;
	theme->Apply();
	Ctrl::ProcessEvents();
	Sleep(3000);
	currentTheme.Apply();
}
		

void SettingsDialog::astyleTest(void)
{
	astyle::ASFormatter Formatter;

	// sets up parameters from astyle dialog
	Formatter.setBracketIndent(formatter.BracketIndent);
	Formatter.setNamespaceIndent(formatter.NamespaceIndent);
	Formatter.setBlockIndent(formatter.BlockIndent);
	Formatter.setCaseIndent(formatter.CaseIndent);
	Formatter.setClassIndent(formatter.ClassIndent);
	Formatter.setLabelIndent(formatter.LabelIndent);
	Formatter.setSwitchIndent(formatter.SwitchIndent);
	Formatter.setPreprocessorIndent(formatter.PreprocessorIndent);
	Formatter.setMaxInStatementIndentLength(formatter.MaxInStatementIndentLength);
	Formatter.setMinConditionalIndentLength(formatter.MinInStatementIndentLength);
	Formatter.setBreakClosingHeaderBracketsMode(formatter.BreakClosingHeaderBracketsMode);
	Formatter.setBreakElseIfsMode(formatter.BreakElseIfsMode);
	Formatter.setBreakOneLineBlocksMode(formatter.BreakOneLineBlocksMode);
	Formatter.setSingleStatementsMode(formatter.SingleStatementsMode);
	Formatter.setBreakBlocksMode(formatter.BreakBlocksMode);
	Formatter.setBreakClosingHeaderBlocksMode(formatter.BreakClosingHeaderBlocksMode);
	Formatter.setBracketFormatMode((astyle::BracketMode)formatter.BracketFormatMode.GetIndex());
	switch(formatter.ParensPaddingMode.GetIndex()) {
	case astyle::PAD_INSIDE :
		Formatter.setParensInsidePaddingMode(true);
		Formatter.setParensOutsidePaddingMode(false);
		break;
	case astyle::PAD_OUTSIDE :
		Formatter.setParensInsidePaddingMode(false);
		Formatter.setParensOutsidePaddingMode(true);
		break;
	case astyle::PAD_BOTH :
		Formatter.setParensInsidePaddingMode(true);
		Formatter.setParensOutsidePaddingMode(true);
		break;
	default :
		Formatter.setParensOutsidePaddingMode(false);
		Formatter.setParensInsidePaddingMode(false);
		break;
	}
	Formatter.setParensUnPaddingMode(formatter.ParensUnPaddingMode);
	Formatter.setOperatorPaddingMode(formatter.OperatorPaddingMode);
	Formatter.setEmptyLineFill(formatter.EmptyLineFill);
	Formatter.setTabSpaceConversionMode(formatter.TabSpaceConversionMode);
	Formatter.setTabIndentation(true);
	Formatter.setSpaceIndentation(4);

	// formats text in test box
	formatter.TestBox.Set(Project::FormatCodeString(formatter.TestBox.GetW(), Formatter));
}

void SettingsDialog::astyleDefaults(void)
{
	formatter.BracketIndent = false;
	formatter.NamespaceIndent = true;
	formatter.BlockIndent = false;
	formatter.CaseIndent = true;
	formatter.ClassIndent = true;
	formatter.LabelIndent = true;
	formatter.SwitchIndent = true;
	formatter.PreprocessorIndent = false;
	formatter.MaxInStatementIndentLength = 20;
	formatter.MinInStatementIndentLength = 2;
	formatter.BreakClosingHeaderBracketsMode = 0;
	formatter.BreakElseIfsMode = true;
	formatter.BreakOneLineBlocksMode = true;
	formatter.SingleStatementsMode = true;
	formatter.BreakBlocksMode = false;
	formatter.BreakClosingHeaderBlocksMode = false;
	formatter.BracketFormatMode.SetIndex(1);
	formatter.ParensPaddingMode.SetIndex(0);
	formatter.ParensUnPaddingMode = true;
	formatter.OperatorPaddingMode = false;
	formatter.EmptyLineFill = false;
	formatter.TabSpaceConversionMode = false;
}
		
void SettingsDialog::userWarnCb(void)
{
	compiler.warningEdit.Enable(compiler.warningSwitch == 4);
}
	
void SettingsDialog::Reject(void)
{
	// reloads old settings data on cancel
	LoadFromXML(Settings, settingsBackup);

	// reloads old theme data on cancel
	LoadFromXML(Themes, themesBackup);
	
	// reapply current theme
	Themes.ApplyCurrent();
}

bool SettingsDialog::Accept(void)
{
	bool needPackagesRescan = false;
	bool needLibrariesRescan = false;
	bool needExamplesRescan = false;
	
	// put new configuration on settings
	Settings.SetCompilerWarnLevel(compiler.warningSwitch);
	Settings.SetCompilerUserWarnings(~compiler.warningEdit);
	Settings.SetCompilerVerbosity(compiler.verbositySwitch);
	Settings.SetCompilerOptimizations(compiler.optimizationSwitch);
	Settings.SetCompilerFullRebuild(compiler.forceRebuildOption);
	Settings.SetCompilerAutoLibDependencies(compiler.libAutoDependOption);
	
	Settings.SetUploaderVerbosity(uploader.verbositySwitch);
	
	Settings.SetIdeCreateProjectStubs(ide.projectStubsOption);
	Settings.SetIdeCreateLibraryStubs(ide.libraryStubsOption);
	Settings.SetIdeRememberFiles(ide.rememberFilesOption);
	Settings.SetIdeRememberProjects(ide.rememberProjectOption);
	Settings.SetIdeSysLibsReadOnly(ide.sysReadOnlyOption);
	Settings.SetIdeShowSplash(ide.splashOption);
	
	Settings.SetSketchFolder(~locations.sketchbookFolder);
	if(Settings.GetPackagesURLs() != ~locations.packagesURLsEdit)
	{
		Settings.SetPackagesURLs(~locations.packagesURLsEdit);
		needPackagesRescan = true;
	}
	if(Settings.GetLibrariesURLs() != ~locations.librariesURLsEdit)
	{
		Settings.SetLibrariesURLs(~locations.librariesURLsEdit);
		needLibrariesRescan = true;
	}
	
	if(Settings.GetExamplesURLs() != ~locations.examplesURLsEdit)
	{
		Settings.SetExamplesURLs(~locations.examplesURLsEdit);
		needExamplesRescan = true;
	}
	
	Settings.SetAstyleBracketIndent(formatter.BracketIndent);
	Settings.SetAstyleNamespaceIndent(formatter.NamespaceIndent);
	Settings.SetAstyleBlockIndent(formatter.BlockIndent);
	Settings.SetAstyleCaseIndent(formatter.CaseIndent);
	Settings.SetAstyleClassIndent(formatter.ClassIndent);
	Settings.SetAstyleLabelIndent(formatter.LabelIndent);
	Settings.SetAstyleSwitchIndent(formatter.SwitchIndent);
	Settings.SetAstylePreprocessorIndent(formatter.PreprocessorIndent);
	Settings.SetAstyleMinInStatementIndentLength(formatter.MinInStatementIndentLength);
	Settings.SetAstyleMaxInStatementIndentLength(formatter.MaxInStatementIndentLength);
	Settings.SetAstyleBreakClosingHeaderBracketsMode(formatter.BreakClosingHeaderBracketsMode);
	Settings.SetAstyleBreakElseIfsMode(formatter.BreakElseIfsMode);
	Settings.SetAstyleBreakOneLineBlocksMode(formatter.BreakOneLineBlocksMode);
	Settings.SetAstyleSingleStatementsMode(formatter.SingleStatementsMode);
	Settings.SetAstyleBreakBlocksMode(formatter.BreakBlocksMode);
	Settings.SetAstyleBreakClosingHeaderBlocksMode(formatter.BreakClosingHeaderBlocksMode);
	Settings.SetAstyleBracketFormatMode(formatter.BracketFormatMode.GetIndex());
	Settings.SetAstyleParensPaddingMode(formatter.ParensPaddingMode.GetIndex());
	Settings.SetAstyleParensUnPaddingMode(formatter.ParensUnPaddingMode);
	Settings.SetAstyleOperatorPaddingMode(formatter.OperatorPaddingMode);
	Settings.SetAstyleEmptyLineFill(formatter.EmptyLineFill);
	Settings.SetAstyleTabSpaceConversionMode(formatter.TabSpaceConversionMode);

	Settings.SetEditorTabsize(editor.tabsize);
	Settings.SetEditorIndentAmount(editor.indentAmount);
	Settings.SetEditorShowTabs(editor.showTabs);
	Settings.SetEditorIndentSpaces(editor.indentSpaces);
	Settings.SetEditorNoParenthesisIndent(editor.noParenthesisIndent);
	Settings.SetEditorShowLineNumbers(editor.showLineNumbers);
	Settings.SetEditorBookmarkPos(editor.bookmarkPos);
	Settings.SetEditorFindpicksel(editor.findpicksel);
	Settings.SetEditorFindpicktext(editor.findpicktext);
	Settings.SetEditorPersistentFindReplace(editor.persistentFindReplace);
	Settings.SetEditorFindReplaceRestorePos(editor.findReplaceRestorePos);
	Settings.SetEditorAutoEnclose(editor.autoEnclose);
	
	if(needPackagesRescan)
		Settings.RefreshPackages(true);
	if(needLibrariesRescan)
		Settings.RefreshLibraries(true);
	if(needExamplesRescan)
		Settings.RefreshExamples(true);
	
	// set current theme
	storeTheme();
	Themes.SetCurrentIndex(activeTheme);
	Themes.ApplyCurrent();

	return true;
}
