Skip to content
Snippets Groups Projects
UserDataManager.cs 7.28 KiB
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
            }
        }
    }
}