using System;
using Server;
using System.Collections;
using System.Collections.Generic;
// using Server.Gumps;
using Server.Network;
using System.IO;
using Server.Engines.Craft;

namespace Server.Items
{
	public class CraftLog
	{
		public const string SAVE_PATH = @"Saves";
		public const string FILENAME = "SoutezCraftu.bin";
		
		private static Dictionary<Mobile, int> m_ScoreLog;
		private static Mobile m_LastWinner;
		
		public static Mobile LastWinner { get { return m_LastWinner; } set { m_LastWinner = value; } }

		public static void Record( int score, Mobile craft, bool plus )
		{
			if ( m_ScoreLog == null )
				m_ScoreLog = new Dictionary<Mobile, int>();
			
			if ( m_ScoreLog.ContainsKey( craft ) && plus )
				m_ScoreLog[ craft ] += score;
			else
				m_ScoreLog[ craft ] = score;
			
			if ( m_ScoreLog[ craft ] >= 6000000 )
			{
				CraftLog.Reset();
				m_LastWinner = craft;
				World.Broadcast( 192, false, "SOUTEZ CRAFTU: {0} dosahl/a skore 6 000 000 bodu. Zacalo nove kolo.", craft.RawName );
				GiveReward( craft );
			}
		}
		
		public static ArrayList GetSortedData()
		{
			if ( m_ScoreLog == null )
				return null;
			
			ArrayList SortedLog = new ArrayList();
			
			foreach (KeyValuePair<Mobile, int> db in m_ScoreLog)
			{
				SortedLog.Add( new KeyValuePair<Mobile, int>( db.Key, db.Value ) );
			}
			
			SortedLog.Sort( new ListAmountSorter() );
			
			return SortedLog;
		}
		
		private class ListAmountSorter : IComparer
		{
			public ListAmountSorter() : base()
			{
			}

			public int Compare(object a, object b)
			{
				if ( a == null || b == null || a == b || !( a is KeyValuePair<Mobile, int> ) || !( b is KeyValuePair<Mobile, int> ) )
					return 0;
				
				KeyValuePair<Mobile, int> x = ( KeyValuePair<Mobile, int> ) a;
				KeyValuePair<Mobile, int> y = ( KeyValuePair<Mobile, int> ) b;
				
				if ( x.Key == y.Key && x.Key != null && y.Key != null )
				{
					return ((Mobile)x.Key).RawName.CompareTo( ((Mobile)y.Key).RawName );
				}
				return ( ( x.Value > y.Value ) ? -1 : 1 );
			}
		}
		
		public static void Reset()
		{
			if ( m_ScoreLog != null )
				m_ScoreLog.Clear();
				
			m_LastWinner = null;
		}
		
		public static void Configure()
		{
			EventSink.WorldLoad += new WorldLoadEventHandler( OnLoad );
			EventSink.WorldSave += new WorldSaveEventHandler( OnSave );
		}
		
		private static void OnLoad()
		{
			//don't load the file if it don't exist!
			if( !File.Exists( Path.Combine( SAVE_PATH, FILENAME ) ) )
			{
				return;
			}

			using( FileStream bin = new FileStream( Path.Combine( SAVE_PATH, FILENAME ), FileMode.Open, FileAccess.Read, FileShare.Read ) )
			{
				m_ScoreLog = new Dictionary<Mobile, int>();
				
				GenericReader reader = new BinaryFileReader( new BinaryReader( bin ) );
				
				int version = reader.ReadInt();
				
				m_LastWinner = reader.ReadMobile();
				
				int count = reader.ReadInt();

				if( count > 0 )
				{
					for( int i = 0; i < count; i++ )
					{
						Mobile m = reader.ReadMobile();
						int r = reader.ReadInt();
						
						if ( m == null || r == null )
						   continue;
						else
						   m_ScoreLog.Add( m, r );
					}
				}
				
				reader.End();
			}
		}
		
		private static void OnSave( WorldSaveEventArgs e )
		{
			if( !Directory.Exists( SAVE_PATH ) )
			{
				Directory.CreateDirectory( SAVE_PATH );
			}

			GenericWriter writer = new BinaryFileWriter( Path.Combine( SAVE_PATH, FILENAME ), true );

			writer.Write( 0 );
			
			writer.Write( m_LastWinner );
			
			if ( m_ScoreLog == null )
				m_ScoreLog = new Dictionary<Mobile, int>();
			
			writer.Write( m_ScoreLog.Count );
			
			foreach( KeyValuePair<Mobile, int> kvp in m_ScoreLog )
			{
				writer.Write( kvp.Key );
				writer.Write( kvp.Value );
			}
			
			writer.Close();
		}

		public CraftLog()
		{
		}
		
/*
    		public class CraftLogGump : Gump
		{
			private ArrayList scorelist;
			
			public CraftLogGump( Mobile from ) : base(100, 60)
			{
				//290 backgroud y
				scorelist = CraftLog.GetSortedData();
				string str = "";
				
				if ( scorelist == null | scorelist.Count < 1 )
					str = "Zatim nikdo neziskal zadne body";
				else
				{
					int count = 1;
					
					foreach ( KeyValuePair<Mobile, int> kv in scorelist )
					{
						str += String.Format( "{0}. {1} - {2} bodu<br>", count, ((Mobile)kv.Key).RawName, kv.Value );
						count++;
					}
				}
				
				this.Closable=true;
				this.Disposable=true;
				this.Dragable=true;
				this.Resizable=false;
				this.AddPage(0);
				
				this.AddBackground(0, 0, 237, 338, 9200);
				this.AddHtml( 5, 25, 225, 255, str, (bool)true, (bool)true);
				this.AddLabel(64, 3, 1152, @"Soutez craftu");
				this.AddButton(200, 310, 4005, 4007, (int)Buttons.ReloadGump, GumpButtonType.Reply, 0);
				this.AddLabel(143, 312, 0, @"Refresh");
				this.AddLabel(10, 287, 0, String.Format( "Posledni vitez: {0}", ( m_LastWinner != null ) ? m_LastWinner.RawName : "---" ));

				if ( from.AccessLevel > AccessLevel.GameMaster )
				{
					this.AddButton(10, 310, 4002, 4004, (int)Buttons.ResetStats, GumpButtonType.Reply, 0);
					this.AddLabel(45, 312, 0, @"Vymazat");
				}
			}
			
			public enum Buttons
			{
				Cancel,
				ReloadGump,
				ResetStats,
			}

			public override void OnResponse( NetState state, RelayInfo info )
			{
				Mobile from = state.Mobile;

				if ( from == null )
					return;
				
				switch( info.ButtonID )
				{
					case (int)Buttons.ReloadGump:
						{
							from.CloseGump(typeof(CraftLogGump));
							from.SendGump( new CraftLogGump( from ) );
						}
						break;
					case (int)Buttons.ResetStats:
						{
							if ( from.AccessLevel < AccessLevel.Administrator )
								return;
							
							CraftLog.Reset();
							from.CloseGump(typeof(CraftLogGump));
							from.SendGump( new CraftLogGump( from ) );
							from.SendMessage("Vysledkova listina byla vymazana");
						}
						break;
					case (int)Buttons.Cancel:
						{
						}
						break;
				}
			}
		}
*/
		
		// ============= RUNIC START
		private static int ResourcePoints( CraftResource res )
		{
			switch ( res )
			{
					case CraftResource.DullCopper: return 2; break;
					case CraftResource.ShadowIron: return 3; break;
					case CraftResource.Copper: return 4; break;
					case CraftResource.Bronze: return 5; break;
					case CraftResource.Gold: return 6; break;
					case CraftResource.Agapite: return 7; break;
					case CraftResource.Verite: return 8; break;
					case CraftResource.Valorite: return 9; break;
					case CraftResource.Silver: return 10; break;
					case CraftResource.Platinum: return 11; break;
					case CraftResource.Mythril: return 12; break;
					case CraftResource.Obsidian: return 13; break;
					case CraftResource.Jade: return 14; break;
					case CraftResource.Moonstone: return 15; break;
					case CraftResource.Sunstone: return 16; break;
					case CraftResource.Bloodstone: return 17; break;
					
					case CraftResource.SpinedLeather: return 2; break;
					case CraftResource.HornedLeather: return 3; break;
					case CraftResource.BarbedLeather: return 4; break;
					case CraftResource.DragonLeather: return 10; break;
					case CraftResource.DaemonLeather: return 11; break;
					
					case CraftResource.Pine: return 2; break;
					case CraftResource.Cedar: return 3; break;
					case CraftResource.Cherry: return 4; break;
					case CraftResource.Mahogany: return 5; break;
					case CraftResource.Oak: return 6; break;
					case CraftResource.Ash: return 7; break;
					case CraftResource.Yew: return 8; break;
					case CraftResource.Heartwood: return 12; break;
					case CraftResource.Bloodwood: return 14; break;
					case CraftResource.Frostwood: return 16; break;
					case CraftResource.RedScales: return 5; break;
					case CraftResource.YellowScales: return 5; break;
					case CraftResource.BlackScales: return 5; break;
					case CraftResource.GreenScales: return 5; break;
					case CraftResource.WhiteScales: return 5; break;
					case CraftResource.BlueScales: return 5; break;
					default: return 1; break;
			}
		}
		
		public static void ComputePoints( Item item, Mobile from, BaseRunicTool tool, CraftSystem system )
		{
			//KONTROLY
			if ( item == null || tool == null || system == null )
				return;
			
			CraftResourceInfo resInfo = CraftResources.GetInfo( tool.Resource );

			if ( resInfo == null )
				return;

			CraftAttributeInfo attrs = resInfo.AttributeInfo;

			if ( attrs == null )
				return;
			
			int reward = 0;
			int resAmount = 0;
			CraftResource res;
			CraftItem craftItem = system.CraftItems.SearchFor( item.GetType() );
			
			if ( item is BaseWeapon )
				res = ((BaseWeapon)item).Resource;
			else if ( item is BaseArmor )
				res = ((BaseArmor)item).Resource;
			else
				res = CraftResource.Iron;

			if ( craftItem != null && craftItem.Ressources.Count >= 1 && craftItem.Ressources.GetAt( 0 ).Amount > 0 )
				resAmount = craftItem.Ressources.GetAt( 0 ).Amount;

			reward = ( ( attrs.RunicMinAttributes + attrs.RunicMaxAttributes + attrs.RunicMinIntensity + attrs.RunicMaxIntensity ) * ( ResourcePoints( res ) * resAmount ) );
			reward /= 10;
			
			//          from.SendMessage( "Res Points: {0}, Res Amount: {1}, Runic: {2}.", ResourcePoints( res ), resAmount, ( attrs.RunicMinAttributes + attrs.RunicMaxAttributes + attrs.RunicMinIntensity + attrs.RunicMaxIntensity ) );
			
			CraftLog.Record( reward, from, true );
			from.SendMessage( "Ziskavas {0} bodu do souteze craftu.", reward );
		}
		// ============= RUNIC
		
		private static void GiveReward( Mobile winner )
		{
			string robeName = @"<bodytext=lime><big><center>Putovni roba za vitezstvi v soutezi craftu";
			
			//Smazat stare odmeny
			ArrayList toDelete = new ArrayList();
			
			foreach ( Item item in World.Items.Values )
			{
				if ( item is Robe && item.Name == robeName )
					toDelete.Add( item );
			}
			
			foreach ( Item it in toDelete )
				it.Delete();
			
			BaseClothing robe = new Robe( 2577 );
			robe.BlessedFor = winner;
			robe.ItemID = 8271;
			robe.Name = robeName;
			robe.Attributes.BonusHits = 30;
			robe.Attributes.NightSight = 1;
			
			robe.SkillBonuses.SetValues( 0, SkillName.Blacksmith, 10 );
			robe.SkillBonuses.SetValues( 1, SkillName.Tailoring, 10 );
			robe.SkillBonuses.SetValues( 2, SkillName.Fletching, 10 );
			robe.SkillBonuses.SetValues( 3, SkillName.Carpentry, 10 );
			robe.SkillBonuses.SetValues( 4, SkillName.Tinkering, 10 );
			winner.AddToBackpack( robe );
			
			winner.AddToBackpack( new LevelItemEnhanceDeed() );
			winner.SendMessage( 0x482, "Odmena za vitezstvi v tomto kole souteze craftu byla umistena do tveho batohu." );
			winner.SendMessage( 0x482, "Po dobu nasledujuciho kola souteze muzes vylepsovat predmety se 100% uspesnosti" );
			winner.SendMessage( 0x482, "Spending point scroll prida 2 body" );
			winner.SendMessage( 0x482, "Pomoci deedu a 50ti mesicnich kamenu muzes vylepsit levelovaci predmet." );
		}
	}
}
