using System;
using System.IO;
using System.Windows.Forms;
using System.Xml;

namespace TeslaConsole.RedPlanet;

internal static class RPDefaults
{
	public abstract class ScenarioDefaults
	{
		private bool mScoreCompression;

		private TimeSpan mMissionLength = new TimeSpan(0, 10, 0);

		private string mMapKey;

		private string mVehicleKey;

		private string mTimeOfDayKey;

		private string mWeatherKey;

		private int mLaunchDelay = 15;

		public bool ScoreCompression
		{
			get
			{
				return mScoreCompression;
			}
			set
			{
				mScoreCompression = value;
			}
		}

		public TimeSpan MissionLength
		{
			get
			{
				return mMissionLength;
			}
			set
			{
				mMissionLength = value;
			}
		}

		public string MapKey
		{
			get
			{
				return mMapKey;
			}
			set
			{
				mMapKey = value;
			}
		}

		public string VehicleKey
		{
			get
			{
				return mVehicleKey;
			}
			set
			{
				mVehicleKey = value;
			}
		}

		public string TimeOfDayKey
		{
			get
			{
				return mTimeOfDayKey;
			}
			set
			{
				mTimeOfDayKey = value;
			}
		}

		public string WeatherKey
		{
			get
			{
				return mWeatherKey;
			}
			set
			{
				mWeatherKey = value;
			}
		}

		public int LaunchDelay
		{
			get
			{
				return mLaunchDelay;
			}
			set
			{
				mLaunchDelay = value;
			}
		}

		public ScenarioDefaults()
		{
		}

		public abstract void Save(XmlNode parrentNode);

		protected void SaveCommonData(XmlNode scenarioNode)
		{
			scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("ScoreCompression")).InnerText = mScoreCompression.ToString();
			scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("MissionLength")).InnerText = mMissionLength.ToString();
			if (!string.IsNullOrEmpty(mMapKey))
			{
				scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("MapKey")).InnerText = mMapKey;
			}
			if (!string.IsNullOrEmpty(mVehicleKey))
			{
				scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("VehicleKey")).InnerText = mVehicleKey;
			}
			if (!string.IsNullOrEmpty(mTimeOfDayKey))
			{
				scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("TimeOfDayKey")).InnerText = mTimeOfDayKey;
			}
			if (!string.IsNullOrEmpty(mWeatherKey))
			{
				scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("WeatherKey")).InnerText = mWeatherKey;
			}
			scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("LaunchDelay")).InnerText = mLaunchDelay.ToString();
		}

		public abstract void Parse(XmlNode scenarioNode);

		protected bool ParseCommonData(XmlNode node)
		{
			switch (node.Name)
			{
			case "ScoreCompression":
			{
				if (bool.TryParse(node.InnerText, out var result2))
				{
					mScoreCompression = result2;
				}
				return true;
			}
			case "MissionLength":
			{
				if (TimeSpan.TryParse(node.InnerText, out var result3))
				{
					mMissionLength = result3;
				}
				return true;
			}
			case "MapKey":
				if (!string.IsNullOrEmpty(node.InnerText))
				{
					mMapKey = node.InnerText;
				}
				return true;
			case "VehicleKey":
				if (!string.IsNullOrEmpty(node.InnerText))
				{
					mVehicleKey = node.InnerText;
				}
				return true;
			case "TimeOfDayKey":
				if (!string.IsNullOrEmpty(node.InnerText))
				{
					mTimeOfDayKey = node.InnerText;
				}
				return true;
			case "WeatherKey":
				if (!string.IsNullOrEmpty(node.InnerText))
				{
					mWeatherKey = node.InnerText;
				}
				return true;
			case "LaunchDelay":
			{
				if (int.TryParse(node.InnerText, out var result))
				{
					mLaunchDelay = result;
				}
				return true;
			}
			default:
				return false;
			}
		}
	}

	public class DeathRaceDefaults : ScenarioDefaults
	{
		public const string DeathRaceNode = "DeathRaceDefaults";

		private string mColorKey;

		private string mBadgeKey;

		public string ColorKey
		{
			get
			{
				return mColorKey;
			}
			set
			{
				mColorKey = value;
			}
		}

		public string BadgeKey
		{
			get
			{
				return mBadgeKey;
			}
			set
			{
				mBadgeKey = value;
			}
		}

		public override void Save(XmlNode parrentNode)
		{
			XmlNode xmlNode = parrentNode.AppendChild(parrentNode.OwnerDocument.CreateElement("DeathRaceDefaults"));
			SaveCommonData(xmlNode);
			if (!string.IsNullOrEmpty(mColorKey))
			{
				xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("ColorKey")).InnerText = mColorKey;
			}
			if (!string.IsNullOrEmpty(mBadgeKey))
			{
				xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("BadgeKey")).InnerText = mBadgeKey;
			}
		}

		public override void Parse(XmlNode scenarioNode)
		{
			foreach (XmlNode childNode in scenarioNode.ChildNodes)
			{
				if (ParseCommonData(childNode))
				{
					continue;
				}
				switch (childNode.Name)
				{
				case "ColorKey":
					if (!string.IsNullOrEmpty(childNode.InnerText))
					{
						mColorKey = childNode.InnerText;
					}
					break;
				case "BadgeKey":
					if (!string.IsNullOrEmpty(childNode.InnerText))
					{
						mBadgeKey = childNode.InnerText;
					}
					break;
				}
			}
		}
	}

	public class FootballDefaults : ScenarioDefaults
	{
		public const string FootballNode = "FootballDefaults";

		private string mTeamKey;

		private string mPositionKey;

		public string TeamKey
		{
			get
			{
				return mTeamKey;
			}
			set
			{
				mTeamKey = value;
			}
		}

		public string PositionKey
		{
			get
			{
				return mPositionKey;
			}
			set
			{
				mPositionKey = value;
			}
		}

		public override void Save(XmlNode parrentNode)
		{
			XmlNode xmlNode = parrentNode.AppendChild(parrentNode.OwnerDocument.CreateElement("FootballDefaults"));
			SaveCommonData(xmlNode);
			if (!string.IsNullOrEmpty(mTeamKey))
			{
				xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("TeamKey")).InnerText = mTeamKey;
			}
			if (!string.IsNullOrEmpty(mPositionKey))
			{
				xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("PositionKey")).InnerText = mPositionKey;
			}
		}

		public override void Parse(XmlNode scenarioNode)
		{
			foreach (XmlNode childNode in scenarioNode.ChildNodes)
			{
				if (ParseCommonData(childNode))
				{
					continue;
				}
				switch (childNode.Name)
				{
				case "TeamKey":
					if (!string.IsNullOrEmpty(childNode.InnerText))
					{
						mTeamKey = childNode.InnerText;
					}
					break;
				case "PositionKey":
					if (!string.IsNullOrEmpty(childNode.InnerText))
					{
						mPositionKey = childNode.InnerText;
					}
					break;
				}
			}
		}
	}

	private static readonly string sDefaultsFilePath;

	private static readonly DeathRaceDefaults sDeathRace;

	private static readonly FootballDefaults sFootball;

	public static DeathRaceDefaults DeathRace => sDeathRace;

	public static FootballDefaults Football => sFootball;

	static RPDefaults()
	{
		sDefaultsFilePath = Path.Combine(Program.GetCommonAppDataDirectory(), "RPDefaults.rpd");
		sDeathRace = new DeathRaceDefaults();
		sFootball = new FootballDefaults();
		if (File.Exists(sDefaultsFilePath))
		{
			try
			{
				Import(sDefaultsFilePath);
			}
			catch (Exception)
			{
				MessageBox.Show("The Red Planet defaults file appears to be corrupt.  Please open the Red Planet Defaults Dialog and save to create a new defaults file.", "Error Loading Red Planet Defaults!", MessageBoxButtons.OK);
			}
		}
	}

	public static void Import(string fileName)
	{
		XmlDocument xmlDocument = new XmlDocument();
		xmlDocument.Load(fileName);
		foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes)
		{
			switch (childNode.Name)
			{
			case "DeathRaceDefaults":
				sDeathRace.Parse(childNode);
				break;
			case "FootballDefaults":
				sFootball.Parse(childNode);
				break;
			}
		}
	}

	public static void Save()
	{
		try
		{
			Export(sDefaultsFilePath);
		}
		catch (Exception)
		{
			MessageBox.Show("The Red Planet defaults file could not be saved.  These defaults will only be remembered until the application is closed.", "Error Saving Red Planet Defaults!", MessageBoxButtons.OK);
		}
	}

	public static void Export(string filePath)
	{
		XmlDocument xmlDocument = new XmlDocument();
		xmlDocument.AppendChild(xmlDocument.CreateElement("RPDefaults"));
		sDeathRace.Save(xmlDocument.DocumentElement);
		sFootball.Save(xmlDocument.DocumentElement);
		string directoryName = Path.GetDirectoryName(filePath);
		if (!Directory.Exists(directoryName))
		{
			Directory.CreateDirectory(directoryName);
		}
		xmlDocument.Save(filePath);
	}
}
