using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;

namespace SharpQuake
{
	internal class cvar
	{
		public static cvar First
		{
			get
			{
				return cvar._Vars;
			}
		}

		public string Name
		{
			get
			{
				return this._Name;
			}
		}

		public string String
		{
			get
			{
				return this._String;
			}
		}

		public float Value
		{
			get
			{
				return this._Value;
			}
		}

		public bool IsArchive
		{
			get
			{
				return this._Flags[1];
			}
		}

		public bool IsServer
		{
			get
			{
				return this._Flags[2];
			}
		}

		public cvar Next
		{
			get
			{
				return this._Next;
			}
		}

		public static cvar Find(string name)
		{
			for (cvar cvar = cvar._Vars; cvar != null; cvar = cvar._Next)
			{
				if (cvar._Name.Equals(name))
				{
					return cvar;
				}
			}
			return null;
		}

		public static bool Exists(string name)
		{
			return cvar.Find(name) != null;
		}

		public static float GetValue(string name)
		{
			float result = 0f;
			cvar cvar = cvar.Find(name);
			if (cvar != null)
			{
				result = common.atof(cvar._String);
			}
			return result;
		}

		public static string GetString(string name)
		{
			cvar cvar = cvar.Find(name);
			if (cvar != null)
			{
				return cvar._String;
			}
			return string.Empty;
		}

		public static string[] CompleteName(string partial)
		{
			if (string.IsNullOrEmpty(partial))
			{
				return null;
			}
			List<string> list = new List<string>();
			for (cvar cvar = cvar._Vars; cvar != null; cvar = cvar._Next)
			{
				if (cvar._Name.StartsWith(partial))
				{
					list.Add(cvar._Name);
				}
			}
			if (list.Count <= 0)
			{
				return null;
			}
			return list.ToArray();
		}

		public static void Set(string name, string value)
		{
			cvar cvar = cvar.Find(name);
			if (cvar == null)
			{
				Con.Print("Cvar.Set: variable {0} not found\n", new object[]
				{
					name
				});
				return;
			}
			cvar.Set(value);
		}

		public static void Set(string name, float value)
		{
			cvar.Set(name, value.ToString(CultureInfo.InvariantCulture.NumberFormat));
		}

		public static bool Command()
		{
			cvar cvar = cvar.Find(cmd.Argv(0));
			if (cvar == null)
			{
				return false;
			}
			if (cmd.Argc == 1)
			{
				Con.Print("\"{0}\" is \"{1}\"\n", new object[]
				{
					cvar._Name,
					cvar._String
				});
			}
			else
			{
				cvar.Set(cmd.Argv(1));
			}
			return true;
		}

		public static void WriteVariables(Stream dest)
		{
			StringBuilder stringBuilder = new StringBuilder(4096);
			for (cvar cvar = cvar._Vars; cvar != null; cvar = cvar._Next)
			{
				if (cvar.IsArchive)
				{
					stringBuilder.Append(cvar._Name);
					stringBuilder.Append(" \"");
					stringBuilder.Append(cvar._String);
					stringBuilder.AppendLine("\"");
				}
			}
			byte[] bytes = Encoding.ASCII.GetBytes(stringBuilder.ToString());
			dest.Write(bytes, 0, bytes.Length);
		}

		public void Set(string value)
		{
			if (string.Compare(this._String, value) == 0)
			{
				return;
			}
			this._String = value;
			this._Value = common.atof(this._String);
			if (this.IsServer && server.sv.active)
			{
				server.BroadcastPrint("\"{0}\" changed to \"{1}\"\n", new object[]
				{
					this._Name,
					this._String
				});
			}
		}

		public cvar(string name, string value) : this(name, value, false)
		{
		}

		public cvar(string name, string value, bool archive) : this(name, value, archive, false)
		{
		}

		public cvar(string name, string value, bool archive, bool server)
		{
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentNullException("name");
			}
			if (cvar.Find(name) != null)
			{
				throw new ArgumentException(string.Format("Can't register variable {0}, already defined!\n", name));
			}
			if (cmd.Exists(name))
			{
				throw new ArgumentException(string.Format("Can't register variable: {0} is a command!\n", name));
			}
			this._Next = cvar._Vars;
			cvar._Vars = this;
			this._Name = name;
			this._String = value;
			this._Flags[1] = archive;
			this._Flags[2] = server;
			this._Value = common.atof(this._String);
		}

		protected cvar()
		{
		}

		private static cvar _Vars;

		private string _Name;

		private string _String;

		private BitVector32 _Flags;

		private float _Value;

		private cvar _Next;

		private class Flags
		{
			public const int Archive = 1;

			public const int Server = 2;
		}
	}
}
