using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

using Server;
using Server.Items;
using Server.Network;
using Server.Guilds;
using Server.Accounting;
using Server.Engines.PartySystem;

namespace Server.Misc
{
	public class StatusPage : Timer
	{
		public static void Initialize()
		{
			new StatusPage().Start();
		}

		public StatusPage() : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(180.0))
		{
			Priority = TimerPriority.FiveSeconds;
		}

		public static string FormatTimeSpan(TimeSpan ts)
		{
			if (ts.Days > 365)
			{
				return String.Format("{0:n0}roků {1:n0}dní {2:n0}hod", (int)(ts.TotalDays / 365.2425), (int)(ts.TotalDays % 365.2425), ts.Hours % 24);
			}
			else
				return String.Format("{0:n0}dní {1:n0}hod {2:n0}min", ts.Days, ts.Hours % 24, ts.Minutes % 60);

			//          return String.Format( "{0:D2}:{1:D2}:{2:D2}:{3:D2}", ts.Days, ts.Hours % 24, ts.Minutes % 60, ts.Seconds % 60 );
			//          return String.Format("Uptime: {0:n0} days, {1:n0} hours and {2:n0} minutes", m_Uptime.Days, m_Uptime.Hours, m_Uptime.Minutes);
		}

		public static string Encode(string input)
		{
			StringBuilder sb = new StringBuilder(input);

			sb.Replace("&", "&amp;");
			sb.Replace("<", "&lt;");
			sb.Replace(">", "&gt;");
			sb.Replace("\"", "&quot;");
			sb.Replace("'", "&apos;");

			return sb.ToString();
		}

		protected override void OnTick()
		{
			if (!Directory.Exists("web"))
				Directory.CreateDirectory("web");

			using (StreamWriter op = new StreamWriter("web/status.html"))
			{
				int userCount = 0;
				int playersInParty = 0;
				int houses = 0;
				List<Party> parties = new List<Party>();
				DateTime shardCreation = DateTime.Now;
				TimeSpan totalGameTime = TimeSpan.Zero;

				foreach (NetState state in NetState.Instances)
				{
					if (state.Mobile != null)
					{
						if (!(Auberon.Chat.Data.GetData(state.Mobile).Status == Auberon.Chat.OnlineStatus.Hidden/* && state.Mobile.AccessLevel > AccessLevel.Player*/))
							userCount++;

						Party p = Party.Get(state.Mobile);

						if (p != null)
						{
							playersInParty++;

							if (!parties.Contains(p))
								parties.Add(p);
						}
					}
				}

				foreach (Account a in Accounts.GetAccounts())
				{
					totalGameTime += a.TotalGameTime;

					if (a.Created < shardCreation)
						shardCreation = a.Created;
				}

				//             int userCount = NetState.Instances.Count;

				op.WriteLine("<ALL>");
				op.WriteLine("   <shard_status>");
				op.WriteLine("      <players>" + userCount + "</players>");
				op.WriteLine("      <items>" + World.Items.Count + "</items>");
				op.WriteLine("      <npc>" + World.Mobiles.Count + "</npc>");
				op.WriteLine("      <accounts>" + Accounts.Count + "</accounts>");
				op.WriteLine("      <parties>" + parties.Count + "</parties>");
				op.WriteLine("      <parties_players>" + playersInParty + "</parties_players>");
				op.WriteLine("      <gametime>" + FormatTimeSpan(totalGameTime) + "</gametime>");
				op.WriteLine("      <shard_age>" + FormatTimeSpan(DateTime.Now - shardCreation) + "</shard_age>");
				op.WriteLine("      <uptime>" + FormatTimeSpan(DateTime.Now - Clock.ServerStart) + "</uptime>");
				op.WriteLine("      <time>" + DateTime.Now + "</time>");
				op.WriteLine("   </shard_status>");
				op.WriteLine("   <online_players>");
				
				foreach (NetState state in NetState.Instances)
				{
					Mobile m = state.Mobile;

					if (m != null && !(Auberon.Chat.Data.GetData(m).Status == Auberon.Chat.OnlineStatus.Hidden/* && m.AccessLevel > AccessLevel.Player*/))
					{
						Guild g = m.Guild as Guild;
						Engines.XmlSpawner2.UspechyAttachment att = (Engines.XmlSpawner2.UspechyAttachment) Engines.XmlSpawner2.XmlAttach.FindAttachment(m, typeof(Engines.XmlSpawner2.UspechyAttachment));

						op.WriteLine("");
						op.Write("      <player");
						op.Write(" name=\"" + Encode(m.RawName) + "\"");
						op.Write(" access=\"" + m.AccessLevel + "\"");

						if (g != null)
						{
							string title = m.GuildTitle;

							if (title != null)
								title = title.Trim();
							else
								title = "";

							op.Write(" guild_title=\"" + Encode(title) + "\"");
							op.Write(" guild_abbr=\"" + Encode(g.Abbreviation) + "\"");
						}
						else
						{
							op.Write(" guild_title=\"null\"");
							op.Write(" guild_abbr=\"null\"");
						}

						op.Write(" map=\"" + m.Map + "\"");
						op.Write(" fame=\"" + (att != null ? att.AllMaps.ToString("N0", Auberon.Chat.General.Nfi) : "0") + "\"");
						op.Write(" gt=\"" + ((Server.Mobiles.PlayerMobile)m).GameTime + "\"");
						op.Write("></player>");
					}
				}

				op.WriteLine("   </online_players>");
				op.WriteLine("</ALL>");
			}
		}
	}
}