diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs
new file mode 100644
index 00000000..3c5094c3
--- /dev/null
+++ b/Vocaluxe/Base/CMain.cs
@@ -0,0 +1,315 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Text;
+
+using Vocaluxe.Menu;
+
+namespace Vocaluxe.Base
+{
+ static class CMain
+ {
+ public static IConfig Config = new BConfig();
+ public static ISettings Settings = new BSettings();
+ public static ITheme Theme = new BTheme();
+ public static IHelper Helper = new BHelper();
+ public static IBackgroundMusic BackgroundMusic = new BBackgroundMusic();
+ public static IDrawing Draw = new BDraw();
+ public static IGraphics Graphics = new BGraphics();
+ public static ILog Log = new BLog();
+ public static IFonts Fonts = new BFonts();
+ public static ILanguage Language = new BLanguage();
+ }
+
+ class BConfig : IConfig
+ {
+ public void SetBackgroundMusicVolume(int NewVolume)
+ {
+ if (NewVolume < 0)
+ CConfig.BackgroundMusicVolume = 0;
+ else if (NewVolume > 100)
+ CConfig.BackgroundMusicVolume = 100;
+ else
+ CConfig.BackgroundMusicVolume = NewVolume;
+
+ CConfig.SaveConfig();
+ }
+
+ public int GetBackgroundMusicVolume()
+ {
+ return CConfig.BackgroundMusicVolume;
+ }
+
+ public ESongMenu GetSongMenuType()
+ {
+ return CConfig.SongMenu;
+ }
+
+ public EOffOn GetVideosToBackground()
+ {
+ return CConfig.VideosToBackground;
+ }
+
+ public EOffOn GetVideoBackgrounds()
+ {
+ return CConfig.VideoBackgrounds;
+ }
+ }
+
+ class BSettings : ISettings
+ {
+ public int GetRenderW()
+ {
+ return CSettings.iRenderW;
+ }
+
+ public int GetRenderH()
+ {
+ return CSettings.iRenderH;
+ }
+
+ public bool IsTabNavigation()
+ {
+ return CSettings.TabNavigation;
+ }
+
+ public float GetZFar()
+ {
+ return CSettings.zFar;
+ }
+
+ public float GetZNear()
+ {
+ return CSettings.zNear;
+ }
+
+ public EGameState GetGameState()
+ {
+ return CSettings.GameState;
+ }
+ }
+
+ class BTheme : ITheme
+ {
+ public string GetThemeScreensPath()
+ {
+ return CTheme.GetThemeScreensPath();
+ }
+
+ public int GetSkinIndex()
+ {
+ return CTheme.GetSkinIndex();
+ }
+
+ public STexture GetSkinTexture(string TextureName)
+ {
+ return CTheme.GetSkinTexture(TextureName);
+ }
+
+ public STexture GetSkinVideoTexture(string VideoName)
+ {
+ return CTheme.GetSkinVideoTexture(VideoName);
+ }
+
+ public void SkinVideoResume(string VideoName)
+ {
+ CTheme.SkinVideoResume(VideoName);
+ }
+
+ public void SkinVideoPause(string VideoName)
+ {
+ CTheme.SkinVideoPause(VideoName);
+ }
+
+ public SColorF GetColor(string ColorName)
+ {
+ return CTheme.GetColor(ColorName);
+ }
+
+ public bool GetColor(string ColorName, int SkinIndex, ref SColorF Color)
+ {
+ return CTheme.GetColor(ColorName, SkinIndex, ref Color);
+ }
+
+
+ public void UnloadSkins()
+ {
+ CTheme.UnloadSkins();
+ }
+
+ public void ListSkins()
+ {
+ CTheme.ListSkins();
+ }
+
+ public void LoadSkins()
+ {
+ CTheme.LoadSkins();
+ }
+
+ public void LoadTheme()
+ {
+ CTheme.LoadTheme();
+ }
+
+ }
+
+ class BHelper : IHelper
+ {
+ }
+
+ class BBackgroundMusic : IBackgroundMusic
+ {
+ public bool IsDisabled()
+ {
+ return CBackgroundMusic.Disabled;
+ }
+
+ public bool IsPlaying()
+ {
+ return CBackgroundMusic.Playing;
+ }
+
+ public bool SongHasVideo()
+ {
+ return CBackgroundMusic.SongHasVideo;
+ }
+
+ public bool VideoEnabled()
+ {
+ return CBackgroundMusic.VideoEnabled;
+ }
+
+
+ public void Next()
+ {
+ CBackgroundMusic.Next();
+ }
+
+ public void Previous()
+ {
+ CBackgroundMusic.Previous();
+ }
+
+ public void Pause()
+ {
+ CBackgroundMusic.Pause();
+ }
+
+ public void Play()
+ {
+ CBackgroundMusic.Play();
+ }
+
+
+ public void ApplyVolume()
+ {
+ CBackgroundMusic.ApplyVolume();
+ }
+
+ public STexture GetVideoTexture()
+ {
+ return CBackgroundMusic.GetVideoTexture();
+ }
+ }
+
+ class BDraw : IDrawing
+ {
+ public RectangleF GetTextBounds(CText text)
+ {
+ return CDraw.GetTextBounds(text);
+ }
+
+ public void DrawTexture(STexture Texture, SRectF Rect)
+ {
+ CDraw.DrawTexture(Texture, Rect);
+ }
+
+ public void DrawTexture(STexture Texture, SRectF Rect, SColorF Color)
+ {
+ CDraw.DrawTexture(Texture, Rect, Color);
+ }
+
+ public void DrawTexture(STexture Texture, SRectF Rect, SColorF Color, SRectF Bounds)
+ {
+ CDraw.DrawTexture(Texture, Rect, Color, Bounds);
+ }
+
+ public void DrawTextureReflection(STexture Texture, SRectF Rect, SColorF Color, SRectF Bounds, float ReflectionSpace, float ReflectionHeight)
+ {
+ CDraw.DrawTextureReflection(Texture, Rect, Color, Bounds, ReflectionSpace, ReflectionHeight);
+ }
+
+ public void DrawColor(SColorF Color, SRectF Rect)
+ {
+ CDraw.DrawColor(Color, Rect);
+ }
+
+ public void DrawColorReflection(SColorF Color, SRectF Rect, float Space, float Height)
+ {
+ CDraw.DrawColorReflection(Color, Rect, Space, Height);
+ }
+ }
+
+ class BGraphics : IGraphics
+ {
+ public void ReloadTheme()
+ {
+ CGraphics.ReloadTheme();
+ }
+ }
+
+ class BLog : ILog
+ {
+ public void LogError(string ErrorText)
+ {
+ CLog.LogError(ErrorText);
+ }
+ }
+
+ class BFonts : IFonts
+ {
+ public void SetFont(string FontName)
+ {
+ CFonts.SetFont(FontName);
+ }
+
+ public void SetStyle(EStyle FontStyle)
+ {
+ CFonts.Style = FontStyle;
+ }
+
+ public RectangleF GetTextBounds(CText Text, float TextHeight)
+ {
+ return CFonts.GetTextBounds(Text, TextHeight);
+ }
+
+ public void DrawText(string Text, float TextHeight, float x, float y, float z, SColorF Color)
+ {
+ CFonts.DrawText(Text, TextHeight, x, y, z, Color);
+ }
+
+ public void DrawTextReflection(string Text, float TextHeight, float x, float y, float z, SColorF Color, float ReflectionSpace, float ReflectionHeight)
+ {
+ CFonts.DrawTextReflection(Text, TextHeight, x, y, z, Color, ReflectionSpace, ReflectionHeight);
+ }
+
+ public void DrawText(string Text, float TextHeight, float x, float y, float z, SColorF Color, float Begin, float End)
+ {
+ CFonts.DrawText(Text, TextHeight, x, y, z, Color, Begin, End);
+ }
+ }
+
+ class BLanguage : ILanguage
+ {
+ public string Translate(string KeyWord)
+ {
+ return CLanguage.Translate(KeyWord);
+ }
+
+ public bool TranslationExists(string KeyWord)
+ {
+ return CLanguage.TranslationExists(KeyWord);
+ }
+ }
+}
diff --git a/Vocaluxe/Menu/CHelper.cs b/Vocaluxe/Menu/CHelper.cs
new file mode 100644
index 00000000..f8e1bb40
--- /dev/null
+++ b/Vocaluxe/Menu/CHelper.cs
@@ -0,0 +1,313 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Vocaluxe.Menu
+{
+ class CHelper
+ {
+ ///
+ /// Concat strings into one string with ", " as separator.
+ ///
+ public static string ListStrings(string[] str)
+ {
+ string _Result = string.Empty;
+
+ for (int i = 0; i < str.Length; i++)
+ {
+ _Result += str[i];
+ if (i < str.Length - 1)
+ _Result += ", ";
+ }
+
+ return _Result;
+ }
+
+ public static int TryReadInt(StreamReader sr)
+ {
+ char chr = '0';
+ string value = String.Empty;
+
+ try
+ {
+ chr = (char)sr.Peek();
+ while ((chr.CompareTo(' ') != 0) && ((int)chr != 19) && ((int)chr != 16) && ((int)chr != 13))
+ {
+ chr = (char)sr.Read();
+ value += chr.ToString();
+ chr = (char)sr.Peek();
+ }
+ }
+ catch (Exception)
+ {
+ return 0;
+ }
+ int result = 0;
+ int.TryParse(value, out result);
+ return result;
+ }
+
+ public static void SetRect(RectangleF Bounds, ref RectangleF Rect, float RectAspect, EAspect Aspect)
+ {
+ float rW = Bounds.Right - Bounds.Left;
+ float rH = Bounds.Bottom - Bounds.Top;
+ float rA = rW / rH;
+
+ float ScaledWidth = rW;
+ float ScaledHeight = rH;
+
+ switch (Aspect)
+ {
+ case EAspect.Crop:
+ if (rA >= RectAspect)
+ {
+ ScaledWidth = rW;
+ ScaledHeight = rH * rA / RectAspect;
+ }
+ else
+ {
+ ScaledHeight = rH;
+ ScaledWidth = rW * RectAspect / rA;
+ }
+ break;
+ case EAspect.LetterBox:
+ if (RectAspect >= 1)
+ {
+ ScaledWidth = rW;
+ ScaledHeight = rH * rA / RectAspect;
+ }
+ else
+ {
+ ScaledHeight = rH;
+ ScaledWidth = rW * RectAspect / rA;
+ }
+ break;
+ default:
+ ScaledWidth = rW;
+ ScaledHeight = rH;
+ break;
+ }
+
+ float Left = (rW - ScaledWidth) / 2 + Bounds.Left;
+ float Rigth = Left + ScaledWidth;
+
+ float Upper = (rH - ScaledHeight) / 2 + Bounds.Top;
+ float Lower = Upper + ScaledHeight;
+
+ Rect = new RectangleF(Left, Upper, Rigth - Left, Lower - Upper);
+ }
+
+ public static bool TryGetEnumValueFromXML(string Cast, XPathNavigator Navigator, ref T value)
+ where T : struct
+ {
+ string val = String.Empty;
+ if (GetValueFromXML(Cast, Navigator, ref val, Enum.GetName(typeof(T), value)))
+ {
+ TryParse(val, out value, true);
+ return true;
+ }
+ return false;
+ }
+
+ public static bool TryGetIntValueFromXML(string Cast, XPathNavigator Navigator, ref int value)
+ {
+ string val = String.Empty;
+ if (GetValueFromXML(Cast, Navigator, ref val, value.ToString()))
+ {
+ int res = 0;
+ if (int.TryParse(val, out res))
+ {
+ value = res;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool TryGetFloatValueFromXML(string Cast, XPathNavigator Navigator, ref float value)
+ {
+ string val = String.Empty;
+ if (GetValueFromXML(Cast, Navigator, ref val, value.ToString()))
+ {
+ float res = 0;
+ if (TryParse(val, out res))
+ {
+ value = res;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool GetValueFromXML(string Cast, XPathNavigator Navigator, ref string Value, string DefaultValue)
+ {
+ XPathNodeIterator iterator;
+ int results = 0;
+ string val = string.Empty;
+
+ try
+ {
+ Navigator.MoveToFirstChild();
+ iterator = Navigator.Select(Cast);
+
+ while (iterator.MoveNext())
+ {
+ val = iterator.Current.Value;
+ results++;
+ }
+ }
+ catch (Exception)
+ {
+ results = 0;
+ }
+
+ if ((results == 0) || (results > 1))
+ {
+ Value = DefaultValue;
+ return false;
+ }
+ else
+ {
+ Value = val;
+ return true;
+ }
+
+ }
+
+ public static List GetValuesFromXML(string Cast, XPathNavigator Navigator)
+ {
+ List values = new List();
+
+ try
+ {
+ Navigator.MoveToRoot();
+ Navigator.MoveToFirstChild();
+ Navigator.MoveToFirstChild();
+
+ while (Navigator.Name != Cast)
+ Navigator.MoveToNext();
+
+ Navigator.MoveToFirstChild();
+
+ values.Add(Navigator.LocalName);
+ while (Navigator.MoveToNext())
+ values.Add(Navigator.LocalName);
+
+ }
+ catch (Exception)
+ {
+
+ }
+
+ return values;
+ }
+
+ public static bool ItemExistsInXML(string Cast, XPathNavigator Navigator)
+ {
+ XPathNodeIterator iterator;
+ int results = 0;
+
+ try
+ {
+ Navigator.MoveToFirstChild();
+ iterator = Navigator.Select(Cast);
+
+ while (iterator.MoveNext())
+ results++;
+ }
+ catch (Exception)
+ {
+ results = 0;
+ }
+
+ if (results == 0)
+ return false;
+
+ return true;
+ }
+
+ public List ListFiles(string path, string cast)
+ {
+ return ListFiles(path, cast, false, false);
+ }
+
+ public List ListFiles(string path, string cast, bool recursive)
+ {
+ return ListFiles(path, cast, recursive, false);
+ }
+
+ public List ListFiles(string path, string cast, bool recursive, bool fullpath)
+ {
+ List files = new List();
+ DirectoryInfo dir = new DirectoryInfo(path);
+
+ try
+ {
+
+ foreach (FileInfo file in dir.GetFiles(cast))
+ {
+ if (!fullpath)
+ files.Add(file.Name);
+ else
+ //files.Add(Path.Combine(file.DirectoryName, file.Name));
+ files.Add(file.FullName);
+ }
+
+ if (recursive)
+ {
+ foreach (DirectoryInfo di in dir.GetDirectories())
+ {
+ files.AddRange(ListFiles(di.FullName, cast, recursive, fullpath));
+ }
+ }
+ }
+ catch (Exception)
+ {
+
+ }
+
+ return files;
+ }
+
+ public static bool TryParse(string value, out T result)
+ where T : struct
+ {
+ return TryParse(value, out result, false);
+ }
+
+ public static bool TryParse(string value, out T result, bool ignoreCase)
+ where T : struct
+ {
+ result = default(T);
+ try
+ {
+ result = (T)Enum.Parse(typeof(T), value, ignoreCase);
+ return true;
+ }
+ catch { }
+
+ return false;
+ }
+
+ public static bool TryParse(string value, out float result)
+ {
+ value = value.Replace(',', '.');
+ return float.TryParse(value, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, NumberFormatInfo.InvariantInfo, out result);
+ }
+
+ public static bool IsInBounds(SRectF bounds, MouseEvent MouseEvent)
+ {
+ return IsInBounds(bounds, MouseEvent.X, MouseEvent.Y);
+ }
+
+ public static bool IsInBounds(SRectF bounds, int x, int y)
+ {
+ return ((bounds.X <= x) && (bounds.X + bounds.W >= x) && (bounds.Y <= y) && (bounds.Y + bounds.H >= y));
+ }
+ }
+}