From 5b5e5a2bf26246f4d99efc33a1a2d3199393d767 Mon Sep 17 00:00:00 2001
From: bionic85 <144353436+bionic85@users.noreply.github.com>
Date: Fri, 27 Dec 2024 00:53:37 +0100
Subject: [PATCH] Made the new UserDataManager class

doet fancy file read and write dingen
slaat settings and money op enzo
moet m nog laten werken met de settingsform enzo maar de basis is er
---
 PuzzlePlayer/PuzzleForm.cs      |   6 +-
 PuzzlePlayer/PuzzlePlayer.cs    |   6 +-
 PuzzlePlayer/SettingForm.cs     | 106 ++-------------
 PuzzlePlayer/UserDataManager.cs | 230 ++++++++++++++++++++++++++++++++
 4 files changed, 251 insertions(+), 97 deletions(-)
 create mode 100644 PuzzlePlayer/UserDataManager.cs

diff --git a/PuzzlePlayer/PuzzleForm.cs b/PuzzlePlayer/PuzzleForm.cs
index 84e3002..8a9957d 100644
--- a/PuzzlePlayer/PuzzleForm.cs
+++ b/PuzzlePlayer/PuzzleForm.cs
@@ -12,6 +12,8 @@ namespace PuzzlePlayer_Namespace
 {
     internal class PuzzleForm : Form
     {
+        public UserDataManager UserDataManager;
+
         private readonly Button solvebutton;
         private readonly Button hintbutton;
         private readonly Button generatebutton;
@@ -37,6 +39,8 @@ namespace PuzzlePlayer_Namespace
 
         public PuzzleForm(Board b, Size s = default) //takes Board and Size parameter and sets up the PuzzleForm window.
         {
+            UserDataManager = new UserDataManager();
+
             puzzleType = b.GetType().Name;
             if (s == default) s = new Size(700, 420);
             this.Size = this.MinimumSize = s;
@@ -112,7 +116,7 @@ namespace PuzzlePlayer_Namespace
 
                     foreach (Control control in this.Controls)
                     {
-                        SettingForm.UpdateSettings(control);
+                        SettingForm.UpdateControl(control);
                     }
 
                     bufferedGraphics.Graphics.Clear(this.BackColor);
diff --git a/PuzzlePlayer/PuzzlePlayer.cs b/PuzzlePlayer/PuzzlePlayer.cs
index b9d14b8..3db438e 100644
--- a/PuzzlePlayer/PuzzlePlayer.cs
+++ b/PuzzlePlayer/PuzzlePlayer.cs
@@ -71,7 +71,7 @@ namespace PuzzlePlayer_Namespace
 
                     foreach (Control control in this.Controls)
                     {
-                        SettingForm.UpdateSettings(control);
+                        SettingForm.UpdateControl(control);
                     }
 
                     this.Show();
@@ -137,7 +137,7 @@ namespace PuzzlePlayer_Namespace
 
                         foreach (Control control in this.Controls)
                         {
-                            SettingForm.UpdateSettings(control);
+                            SettingForm.UpdateControl(control);
                         }
 
                         this.Show();
@@ -185,7 +185,7 @@ namespace PuzzlePlayer_Namespace
 
                     foreach (Control control in this.Controls)
                     {
-                        SettingForm.UpdateSettings(control);
+                        SettingForm.UpdateControl(control);
                     }
 
                     this.Show();
diff --git a/PuzzlePlayer/SettingForm.cs b/PuzzlePlayer/SettingForm.cs
index f4a7931..f51a68f 100644
--- a/PuzzlePlayer/SettingForm.cs
+++ b/PuzzlePlayer/SettingForm.cs
@@ -8,61 +8,7 @@ using System.Windows.Forms;
 
 namespace PuzzlePlayer_Namespace
 {
-    // struct for saving settings
-    internal struct Settings(Theme t, string fName, int fSize)
-    {
-        public Theme theme = t;
-        public string fontName = fName;
-        public int fontSize = fSize;
-
-        public override string ToString()
-        {
-            return $"SETTINGS|{fontName}|{fontSize}|{theme.ToString()}";
-        }
-
-        public static Settings FromString(string s)
-        {
-            string[] split = s.Split('|');
-            if (split[0] != "SETTINGS")
-                throw new Exception("Invallid input string in FromString methode from Settings struct");
-
-            string themeString = "";
-            for (int i = 3; i < split.Length; i++) // add everything after the fontsize to the themestring
-            {
-                themeString += split[i];
-            }
-
-            return new Settings(Theme.FromString(themeString), split[1], int.Parse(split[2]));
-        }
-    }
-
-    // struct for saving themes
-    internal struct Theme(string s, Color col1, Color col2, Color col3)
-    {
-        public string name = s;
-        public Color primaryColor = col1;
-        public Color secondaryColor = col2;
-        public Color tertiaryColor = col3;
-
-        public override string ToString()
-        {
-            return $"THEME|{name}|{primaryColor.ToArgb()}|{secondaryColor.ToArgb()}|{tertiaryColor.ToArgb()}|";
-        }
-
-        public static Theme FromString(string s)
-        {
-            string[] split = s.Split('|');
-            if (split[0] != "THEME")
-                throw new Exception("Invallid input string in FromString methode from Theme struct");
-
-            Color c1 = Color.FromArgb(int.Parse(split[2]));
-            Color c2 = Color.FromArgb(int.Parse(split[3]));
-            Color c3 = Color.FromArgb(int.Parse(split[4]));
-
-            return new Theme(split[1],c1,c2,c3);
-        }
-    }
-
+    // form to display the settings in
     internal class SettingForm : Form
     {
         // Public variables for all settings
@@ -74,57 +20,31 @@ namespace PuzzlePlayer_Namespace
         public static string mainFontName = "Gotham";
         public static Font mainFont = new Font(mainFontName, fontSize);
         public static FlowLayoutPanel settingsPanel;
+        
+        // hardcoded default settings
+        public static UserData defaultSettings = new UserData("Dark", mainFontName, fontSize);
 
         // For storing user settings
-        private Settings settings;
+        private UserData settings;
         private static string filePath = "Settings.txt";
 
         public SettingForm()
         {
-            settings = GetUserSettings();
-
-            SetUpUi();
+            // TODO OF ZOIETS HELP
+            SetUpUI();
 
             this.BackColor = primaryColor;
 
             foreach (Control control in Controls)
             {
-                UpdateSettings(control);
+                UpdateControl(control);
             }
             Invalidate();
         }
 
-        private Settings GetUserSettings()
-        {
-            StreamReader reader = new StreamReader(System.IO.File.OpenRead(filePath));
-            Settings? newSettings = null;
-            string s = "";
-            while ((s = reader.ReadLine()) != null)
-            {
-                if(s.StartsWith("SETTINGS"))
-                {
-                    newSettings = Settings.FromString(s);
-                    break;
-                }   
-            }
-            reader.Dispose();
-
-            if (newSettings != null)
-                return (Settings)newSettings;
-            else
-                MakeNewSettingsFile();          // if the settings could not be read then a new file must be made
-
-            return GetUserSettings();           // after the new file is made it is save to call getUserSettings again
-        }
-
-        private void MakeNewSettingsFile()
-        {
-            FileStream fs = File.Create(filePath);
-            StreamReader reader = new StreamReader(fs);
-            throw new NotImplementedException();
-        }
+        
 
-        private void SetUpUi()
+        private void SetUpUI()
         {
             this.ClientSize = new Size(1115, 755);
             this.BackColor = SettingForm.primaryColor;
@@ -253,7 +173,7 @@ namespace PuzzlePlayer_Namespace
 
                 foreach (Control control in Controls)
                 {
-                    UpdateSettings(control);
+                    UpdateControl(control);
                 }
 
                 settingsPanel.BackColor = primaryColor;
@@ -275,7 +195,7 @@ namespace PuzzlePlayer_Namespace
             saveButton.BringToFront();
         }
 
-        public static void UpdateSettings(Control control)
+        public static void UpdateControl(Control control)
         {
             if (control is not FlowLayoutPanel)
             {
@@ -291,7 +211,7 @@ namespace PuzzlePlayer_Namespace
 
             foreach (Control childControl in control.Controls)
             {
-                UpdateSettings(childControl);
+                UpdateControl(childControl);
             }
 
             if (control is MenuStrip menuStrip)
diff --git a/PuzzlePlayer/UserDataManager.cs b/PuzzlePlayer/UserDataManager.cs
new file mode 100644
index 0000000..28494c8
--- /dev/null
+++ b/PuzzlePlayer/UserDataManager.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+
+namespace PuzzlePlayer_Namespace
+{
+    // struct for saving settings
+    internal struct UserData(string themeName, string fName, int fSize)
+    {
+        public const string prefix = "SETTINGS";
+        public string currentThemeName = themeName;
+        public string fontName = fName;
+        public int fontSize = fSize;
+
+        public override string ToString()
+        {
+            return $"{prefix}|{fontName}|{fontSize}|{currentThemeName}";
+        }
+
+        public static UserData? FromString(string s)
+        {
+            string[] split = s.Split('|');
+            if (split[0] != prefix)
+                return null;
+
+            try
+            {
+                string fName = split[1];
+                int fSize = int.Parse(split[2]);
+                string tName = split[3];
+
+                return new UserData(tName, fName, fSize);
+            }
+            catch (Exception)
+            {
+                return null;    //unreadable file will be handled somewhere else
+            }
+        }
+    }
+
+    // struct for saving themes
+    internal struct Theme(string s, Color col1, Color col2, Color col3)
+    {
+        public const string prefix = "THEME";
+        public string name = s;
+        public Color primaryColor = col1;
+        public Color secondaryColor = col2;
+        public Color tertiaryColor = col3;
+
+        public override string ToString()
+        {
+            return $"{prefix}|{name}|{primaryColor.ToArgb()}|{secondaryColor.ToArgb()}|{tertiaryColor.ToArgb()}|";
+        }
+
+        public static Theme? FromString(string s)
+        {
+            string[] split = s.Split('|');
+            if (split[0] != prefix)
+                return null;
+            try
+            {
+                Color c1 = Color.FromArgb(int.Parse(split[2]));
+                Color c2 = Color.FromArgb(int.Parse(split[3]));
+                Color c3 = Color.FromArgb(int.Parse(split[4]));
+
+                return new Theme(split[1], c1, c2, c3);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+    }
+
+    // Class for managing and storing user data
+    internal class UserDataManager
+    {
+        private int money;
+        public int Money { get { return money; } set { UpdateMoney(value); } }
+
+        private UserData data;
+        private List<(Theme,bool)> unlockedThemes = new List<(Theme, bool)>();
+
+        private static string filePath = "Data.txt";
+        private const string moneyPrefix = "DO_NOT_TOUCH_THE_MONEY_CHEATER";
+
+        public UserDataManager()
+        {
+            money = GetMoney();
+            data = GetUserSettings();
+        }
+
+        // reads the file and returns a array of strings of each line
+        private string[] GetDataFileContents()
+        {
+            if (!File.Exists(filePath)) // if the file doesn't exists then a new one is created with default settings
+                MakeNewDataFile();
+
+            List<String> result = new List<string>();
+            using (StreamReader reader = new StreamReader(System.IO.File.OpenRead(filePath)))
+            {
+                string s = "";
+                while ((s = reader.ReadLine()) != null)
+                {
+                    result.Add(s);
+                }
+            }
+
+            if (result.Count > 0)
+                return result.ToArray();
+            else
+                MakeNewDataFile();          // is dit clean? of nah?
+
+            return GetDataFileContents();   // is dit clean? of nah?
+        }
+
+        // writes to the file
+        private void WriteDataFileContent(string[] toWrite)
+        {
+            if (!File.Exists(filePath)) // if the file doesn't exists then a new one is created with default settings
+                MakeNewDataFile();
+
+            using (StreamWriter sw = new StreamWriter(filePath))
+            {
+                foreach(string s in toWrite)
+                    sw.WriteLine(s);
+            }
+        }
+
+        private int GetMoney()
+        {
+            string[] dataFile = GetDataFileContents();
+
+            foreach (string s in dataFile)
+                if(s.StartsWith(moneyPrefix))
+                {
+                    string[] splitted = s.Split('|');
+                    try
+                    {
+                        return int.Parse(splitted[1]);
+                    }
+                    catch (Exception)
+                    {
+                        MakeNewDataFile();
+                        return 100; // default money if the file is broken
+                    }
+                    
+                }
+
+            MakeNewDataFile();
+            return 100; // default money if the file is broken
+        }
+
+        private void UpdateMoney(int newValue)
+        {
+            if(newValue < 0)
+                return;
+
+            money = newValue;
+
+            // write the new value to the data file
+            // first read the old file and replace the line containing the information for the money with the new value
+            string[] dataFile = GetDataFileContents();
+            string newString = $"{moneyPrefix}|{newValue}";
+            for (int i = 0; i < dataFile.Length; i++)
+            {
+                if (dataFile[i].StartsWith(moneyPrefix))
+                {
+                    dataFile[i] = newString;
+                    break;
+                }
+            }
+
+            // after modifying write it back
+            WriteDataFileContent(dataFile);
+        }
+
+        private UserData GetUserSettings()
+        {
+            string[] dataFile = GetDataFileContents();
+            
+            UserData? newSettings = null;
+            foreach (string s in dataFile)
+                if (s.StartsWith("SETTINGS"))
+                {
+                    newSettings = UserData.FromString(s);
+                    break;
+                }
+
+            if (newSettings != null)
+                return (UserData)newSettings;
+            else
+                MakeNewDataFile();          // if the settings could not be read then a new file must be made
+
+            return GetUserSettings();           // after the new file is made it is save to call getUserSettings again
+        }
+
+        private void UpdateUserSettings(UserData newUserData)
+        {
+            data = newUserData;
+
+            // write the new value to the data file
+            // first read the old file and replace the line containing the information for the money with the new value
+            string[] dataFile = GetDataFileContents();
+
+            for (int i = 0; i < dataFile.Length; i++)
+            {
+                if (dataFile[i].StartsWith(UserData.prefix))
+                {
+                    dataFile[i] = newUserData.ToString();
+                    break;
+                }
+            }
+
+            // after modifying write it back
+            WriteDataFileContent(dataFile);
+        }
+
+        // if there is no Settings.txt or it is damaged/modified/unreadable then a new one is created or overwritten
+        private void MakeNewDataFile()
+        {
+            using (StreamWriter writer = File.CreateText(filePath))
+            {
+                writer.WriteLine(SettingForm.defaultSettings.ToString());   // get the default settings from SettingsForm
+                writer.WriteLine($"{moneyPrefix}|100");                       // default money is 100
+            }
+        }
+    }
+}
-- 
GitLab