using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Xanthos.Interfaces;
using Server.Network;
using Server.Misc;
using Server.ContextMenus;
using Server.Gumps;
using System.Collections;
using System.Collections.Generic;

namespace Xanthos.Evo
{
	[CorpseName( "an evolution golem corpse" )]
	public class EvoGolem : BaseEvo, IEvoCreature
	{
		private int m_Absorb;
		private int m_Reflect;
		private int m_MaxAbsorb { get { return (this.Stage + 1) * 100000; } }
		private int m_MaxReflect { get { return (this.Stage + 1) * 1000; } }
		
		[CommandProperty(AccessLevel.GameMaster)]
		public int Absorb
		{
			get { return m_Absorb; }
			set
			{
				m_Absorb = value;
				m_Absorb = ( m_Absorb < 1 ) ? 0 : ( ( m_Absorb >  m_MaxAbsorb ) ? m_MaxAbsorb : m_Absorb );
			}
		}
		
		[CommandProperty(AccessLevel.GameMaster)]
		public int Reflect
		{
			get { return m_Reflect; }
			set
			{
				m_Reflect = value;
				m_Reflect = ( m_Reflect < 1 ) ? 0 : ( ( m_Reflect >  m_MaxReflect ) ? m_MaxReflect : m_Reflect );
			}
		}
		
		public int MaxAbsorb { get { return m_MaxAbsorb; } }
		public int MaxReflect { get { return m_MaxReflect; } }
		
		public override BaseEvoSpec GetEvoSpec()
		{
			return EvoGolemSpec.Instance;
		}

		public override BaseEvoEgg GetEvoEgg()
		{
			return null;
		}

		public override WeaponAbility GetWeaponAbility()
		{
			if ( this.BodyMod == 757 )
			{
				return Utility.RandomBool() ? WeaponAbility.BleedAttack : WeaponAbility.WhirlwindAttack;
			}
			else
			{
				switch ( Utility.Random( 3 ) )
				{
					default:
						case 0: return WeaponAbility.DoubleStrike;
						case 1: return WeaponAbility.ArmorIgnore;
						case 2: return WeaponAbility.CrushingBlow;
				}
			}
		}
		
		public override bool AddPointsOnDamage { get { return false; } }
		public override bool AddPointsOnMelee { get { return true; } }
		public override Type GetEvoDustType() { return null; }
		public override bool IsScaredOfScaryThings{ get{ return false; } }
		public override bool IsScaryToPets{ get{ return true; } }
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
		public override bool BleedImmune{ get{ return true; } }
		public override bool HasBreath{ get{ return true; } }
		
		private DateTime m_NextReflectShield = DateTime.Now;
		private DateTime m_NextAbsorbShield = DateTime.Now;
		private DateTime m_NextBodyMod = DateTime.Now;
		
		public override void OnThink()
		{
			base.OnThink();
			
			if ( !this.IsDeadBondedPet )
			{
				int points = 0;
				int stage = ( (this.Stage + 1) * 10 ) * 10;
				
				if ( m_Absorb > 0 && DateTime.Now > m_NextAbsorbShield && this.MeleeDamageAbsorb < ( stage / 2 ) )
				{
					points = ( stage - this.MeleeDamageAbsorb );
					
					if ( points > m_Absorb )
						points = m_Absorb;
					
					m_Absorb -= points;
					this.MeleeDamageAbsorb += points;
					
					this.FixedParticles( 0x376A, 9, 32, 5008, EffectLayer.Waist );
					this.PlaySound( 490 );
					Emote("*Invulnerability activated*");
					m_NextReflectShield += TimeSpan.FromMinutes( 0.1 );
					m_NextAbsorbShield = DateTime.Now + TimeSpan.FromMinutes( this.GetShieldDelay() );
				}
				
				if ( m_Reflect > 0 && DateTime.Now > m_NextReflectShield && this.MagicDamageAbsorb < ( this.Stage + 8 ) )
				{
					points = Math.Min( ( ( this.Stage + 8 ) - this.MagicDamageAbsorb ), 24 );
					
					if ( points > m_Reflect )
						points = m_Reflect;
					
					m_Reflect -= points;
					this.MagicDamageAbsorb += points;
					
					this.FixedParticles( 0x375A, 10, 15, 5037, EffectLayer.Waist );
					this.PlaySound( 489 );
					Emote("*Antimagic shield activated*");
					m_NextReflectShield = DateTime.Now + TimeSpan.FromMinutes( this.GetShieldDelay() );
					m_NextAbsorbShield += TimeSpan.FromMinutes( 0.1 );
				}
				
				if ( this.IsBodyMod && this.Combatant == null )
				{
					this.BodyMod = 0;
					this.PlaySound( 529 );
					m_NextBodyMod = DateTime.Now + TimeSpan.FromMinutes( 0.3 );
				}
			}
		}
		
		private double GetShieldDelay()
		{
         double delay = 2.0;        
         BaseWeapon weap = (BaseWeapon) this.Weapon;
         
         if ( weap != null && weap.Attributes.Luck > 0 )
         {
            delay -= ( ( (double) weap.Attributes.Luck ) / 100.0 );
            
            if ( delay < 1.0 )
               delay = 1.0;
         }
         
         return delay;
      }
		
		public override void AlterMeleeDamageTo( Mobile to, ref int damage )
		{
         BaseWeapon weap = (BaseWeapon) this.Weapon;
         
         if ( weap != null && weap.Attributes.Luck > 0 )
         {
            if ( Utility.RandomDouble() < ( (double) weap.Attributes.Luck ) / 1000.0 )
				  damage *= 2;
         }
		}
		
		public override void OnGaveMeleeAttack( Mobile defender )
		{
			if ( !this.IsBodyMod && Utility.RandomDouble() < 0.35 && DateTime.Now > m_NextBodyMod )
			{
				this.BodyMod = 757;
// 				this.PlaySound( 620 );
				this.PlaySound( 0x20C );
				this.PlaySound( 0x232 );
				this.FixedParticles( 0x3779, 1, 30, 9964, 3, 3, EffectLayer.Waist );

				IEntity from = new Entity( Serial.Zero, new Point3D( this.X, this.Y, this.Z ), this.Map );
				IEntity to = new Entity( Serial.Zero, new Point3D( this.X, this.Y, this.Z + 50 ), this.Map );
				Effects.SendMovingParticles( from, to, 0xFB4, 1, 0, false, false, 33, 3, 9501, 1, 0, EffectLayer.Head, 0x100 );
			}
			
			if ( !defender.Player && this.IsBodyMod )
			{
            if ( Utility.RandomDouble() < 0.065 )
            {
      			Summon( this, defender );
            }
			}
			
			base.OnGaveMeleeAttack( defender );
		}
		
		private void Summon( Mobile attacker, Mobile defender )
		{
			if ( attacker == null || defender == null )
				return;
			
			Map map = defender.Map;

			if ( map == null )
				return;

			SumBladeSpirits summon = new SumBladeSpirits();

			bool validLocation = false;
			Point3D loc = defender.Location;

			for ( int j = 0; !validLocation && j < 10; ++j )
			{
				int x = defender.X + Utility.Random( 2 ) + 1;
				int y = defender.Y + Utility.Random( 2 ) + 1;
				int z = map.GetAverageZ( x, y );

				if ( validLocation = ( map.CanFit( x, y, defender.Z, 16, false, false ) && attacker.InLOS( new Point3D(x, y, defender.Z) ) ) )
					loc = new Point3D( x, y, defender.Z );
				else if ( validLocation = ( map.CanFit( x, y, z, 16, false, false ) && attacker.InLOS( new Point3D(x, y, z) ) ) )
					loc = new Point3D( x, y, z );
			}
			
			summon.BodyValue = 0x2F4;
			summon.Hue = attacker.Hue;
			summon.Name = "a razor masticator";
         summon.MoveToWorld( loc, map );
			Effects.PlaySound(loc, map, 0x26C);
			summon.Combatant = defender;
			summon.ControlSlots = 0;
			summon.Summoned = true;
			summon.SummonMaster = attacker;
		}
		
		public override bool OnDragDrop( Mobile from, Item dropped )
		{
			PlayerMobile player = from as PlayerMobile;

			if ( this is IEvoGuardian )
				return base.OnDragDrop( from, dropped );
			
			if ( from != ControlMaster )
				return false;
			
			if ( from.Skills[SkillName.Tinkering].Value < 100.0 )
			{
				from.SendMessage("Udrzbu golema zvladne pouze grandmaster tinker.");
				return false;
			}
			
			if ( dropped is BaseIngot )
			{
				BaseIngot ingot = dropped as BaseIngot;

				if ( ingot != null )
				{
					if ( ingot.Resource < CraftResource.DullCopper )
					{
						from.SendMessage("Udrzba golema vyzaduje kvalitnejsi ingoty.");
						return false;
					}

					
					int amount = ( ingot.Amount * ( (int) ingot.Resource - 1 ) ) * 20;

					m_Ep += amount;
					PlaySound(665);
					Emote("*" + this.Name + " absorbs the ingots gaining " + amount.ToString("N0", Auberon.Chat.General.Nfi) + " experience points*");
					ingot.Delete();
					return true;
				}
			}
			else if ( dropped is BaseGranite )
			{
            BaseGranite granite = dropped as BaseGranite;

				if ( granite != null )
				{
					int amount = ( granite.Amount * ( (int) granite.Resource ) ) * 1000;
					
					if ( m_Absorb >= m_MaxAbsorb - amount )
					{
						from.SendMessage("Vice granite golem nepojme.");
						return false;
					}
// 					else if ( granite.Resource < CraftResource.DullCopper )
// 					{
// 						from.SendMessage("Udrzba golema vyzaduje kvalitnejsi granite.");
// 						return false;
// 					}

					m_Absorb += amount;
					PlaySound( 933 );
					Emote("*" + this.Name + " absorbs the granite gaining " + amount.ToString("N0", Auberon.Chat.General.Nfi) + " damage absorb points*");
					from.SendMessage( "Physical shield points: {0}/{1}", m_Absorb, m_MaxAbsorb );
					granite.Delete();
					return true;
				}
			}
			else if ( dropped is BlueDiamond || dropped is BrilliantAmber || dropped is DarkSapphire || dropped is EcruCitrine ||
			         dropped is FireRuby || dropped is PerfectEmerald || dropped is Turquoise || dropped is WhitePearl ||
			         dropped is PowerCrystal || dropped is ClockworkAssembly || dropped is ArcaneGem  )
			{
				if ( m_Reflect >= m_MaxReflect - 10 )
				{
					from.SendMessage("Vice drahokamu golem nepojme.");
					return false;
				}
				
				int amount = ( dropped.Amount * 10 );

				m_Reflect += amount;
				PlaySound( 737 );
				Emote("*" + this.Name + " absorbs the gems gaining " + amount.ToString("N0", Auberon.Chat.General.Nfi) + " spell reflect points*");
				from.SendMessage( "Antimagic shield points: {0}/{1}", m_Reflect, m_MaxReflect );
				dropped.Delete();
				return true;
			}
			
			return base.OnDragDrop( from, dropped );
		}
		
		public override bool OnBeforeDeath()
		{
			BodyMod = 0;
			
			if ( IsBonded && !Deleted )
				new EvoGolemSelfRessTimer(this, 15.0).Start();
			
			return base.OnBeforeDeath();
		}
		
		private class LookAtEntry : ContextMenuEntry
		{
			private EvoGolem m_Golem;
			private Mobile m_From;

			public LookAtEntry( EvoGolem golem, Mobile from ) : base( 6121, 12 )
			{
				m_Golem = golem;
				m_From = from;
			}

			public override void OnClick()
			{
            m_From.CloseGump( typeof(LookAtGump) );
				m_From.SendGump( new LookAtGump( m_From, m_Golem ) );
			}
		}
		
		public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
		{
			if ( !this.IsDeadBondedPet )
			{
				list.Add( new LookAtEntry( this, from ) );
			}

			base.AddCustomContextEntries( from, list );
		}
		
		private class LookAtGump : Gump
		{
			private EvoGolem m_Golem;
			
			public LookAtGump( Mobile from, EvoGolem golem ) : base( 100, 150 )
			{
				if  ( golem == null ) return;
				m_Golem = golem;
				
				this.Closable=true;
				this.Disposable=true;
				this.Dragable=true;
				this.Resizable=false;
				this.AddPage(0);
				this.AddBackground(0, 0, 310, 360, 9200);
				this.AddImageTiled(9, 9, 290, 25, 2624);
				this.AddImageTiled(10, 142, 290, 210, 2624);
				this.AddImageTiled(60, 40, 240, 95, 2624);
				this.AddAlphaRegion(10, 10, 290, 342);
				this.AddImage(10, 40, 2246, ( golem.MeleeDamageAbsorb > 0 ) ? 70 : 40 );
				this.AddImage(10, 90, 2275, ( golem.MagicDamageAbsorb > 0 ) ? 70 : 40 );
				
				this.AddHtml( 10, 10, 285, 20, String.Format( "<center><basefont color=white>{0} {1}</center>", golem.RawName.ToUpper(), golem.Title.ToUpper() ), (bool)false, (bool)false);

				this.AddLabel(65, 40, 1152, @"PHYSICAL SHIELD");
				this.AddLabel(65, 63, 1152, String.Format( "{0} / {1}", golem.MeleeDamageAbsorb, ( (golem.Stage + 1) * 10 ) * 10 ) );
				this.AddLabel(65, 88, 1152, @"ANTIMAGIC SHIELD");
				this.AddLabel(65, 108, 1152, String.Format( "{0} / {1}", golem.MagicDamageAbsorb, Math.Min( golem.Stage + 8, 24 ) ) );
				this.AddItem(235, 60, 9744, golem.Hue); //img golema
				
				string html = String.Format( "<basefont color=white>SHIELDS:<br>Physical shield points: {0} / {1}", golem.Absorb, golem.MaxAbsorb );
				html = html + String.Format( "<br>Antimagic shield points: {0} / {1}<br>", golem.Reflect, golem.MaxReflect );
				html = html + String.Format( "Shield delay: {0:F2} minute<br><br>", golem.GetShieldDelay() );
				html = html + String.Format( "EVOLUTION:<br>Level: {0}<br>Experience: {1}<br><br>", golem.Stage + 1, golem.Ep.ToString("N0", Auberon.Chat.General.Nfi) );
				html = html + String.Format( "INFO:<br>Hits: {0}/{1}<br>Stamina: {2}/{3}<br>Mana: {4}/{5}<br>", golem.Hits, golem.HitsMax, golem.Stam, golem.StamMax, golem.Mana, golem.ManaMax );
// 				html = html + String.Format( "Strength: {0}<br>Dexterity: {1}<br>Inteligence: {2}<br><br>", golem.Str, golem.Dex, golem.Int );
				
            html = html + String.Format( "<br>GOLEM'S WEAPON:<br>Damage: {0} - {1}<br>", golem.DamageMin, golem.DamageMax );
			
				//START WEAPONSTATS
				BaseWeapon weap = (BaseWeapon) golem.Weapon;
				
				if (weap != null )
				{
              int prop;
              
              if ((prop = weap.Attributes.Luck) != 0)
                  html = html + String.Format( "Double damage chance: {0:F1}%<br>Luck: {1}<br>", (double) prop / 10.0, prop  );
 
              if ((prop = (weap.GetDamageBonus() + weap.Attributes.WeaponDamage)) != 0)
                  html = html + String.Format( "Damage increase: {0}%<br>", prop );
                  
              if ((prop = weap.Attributes.DefendChance) != 0)
                  html = html + String.Format( "Defense chance increase: {0}%<br>", prop );
  
              if ((prop = weap.Attributes.AttackChance) != 0)
                  html = html + String.Format( "Hit chance increase: {0}%<br>", prop );
                  
              if ((prop = weap.Attributes.WeaponSpeed) != 0)
                  html = html + String.Format( "Swing speed increase: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitLeechHits) != 0)
                  html = html + String.Format( "Hit leech hits: {0}%<br>", prop );
  
              if ((prop = weap.WeaponAttributes.HitLeechStam) != 0)
                  html = html + String.Format( "Hit leech stamina: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitLeechMana) != 0)
                  html = html + String.Format( "Hit leech mana: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitLowerAttack) != 0)
                  html = html + String.Format( "Hit lower attack: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitLowerDefend) != 0)
                  html = html + String.Format( "Hit lower defense: {0}%<br>", prop );   
                  
              if ((prop = weap.WeaponAttributes.HitPhysicalArea) != 0)
                  html = html + String.Format( "Hit physical area: {0}%<br>", prop );
  
              if ((prop = weap.WeaponAttributes.HitColdArea) != 0)
                  html = html + String.Format( "Hit cold area: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitFireArea) != 0)
                  html = html + String.Format( "Hit fire area: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitEnergyArea) != 0)
                  html = html + String.Format( "Hit energy area: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitPoisonArea) != 0)
                  html = html + String.Format( "Hit poison area: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitDispel) != 0)
                  html = html + String.Format( "Hit dispel: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitFireball) != 0)
                  html = html + String.Format( "Hit fireball: {0}%<br>", prop );
                  
              if ((prop = weap.WeaponAttributes.HitHarm) != 0)
                  html = html + String.Format( "Hit harm: {0}%<br>", prop );
  
              if ((prop = weap.WeaponAttributes.HitMagicArrow) != 0)
                  html = html + String.Format( "Hit magic arrow: {0}%<br>", prop );
  
              if ((prop = weap.WeaponAttributes.HitLightning) != 0)
                  html = html + String.Format( "Hit lightning: {0}%<br>", prop );
                  
              int TR = ( weap.PhysicalResistance + weap.ColdResistance + weap.FireResistance + weap.PoisonResistance + weap.EnergyResistance );
              if ( TR > 0 ) 
              {
                  html = html + String.Format( "Resistances: <basefont color=silver>{0} ", weap.PhysicalResistance );
                  html = html + String.Format( "<basefont color=red>{0} ", weap.FireResistance );
                  html = html + String.Format( "<basefont color=aqua>{0} ", weap.ColdResistance );
                  html = html + String.Format( "<basefont color=lime>{0} ", weap.PoisonResistance );
                  html = html + String.Format( "<basefont color=fuchsia>{0}", weap.EnergyResistance );
                  html = html + String.Format( "<basefont color=white><br>Total resistances bonus: {0}<br>", TR );
              }
            }
				//END WEAPON STATS
				this.AddHtml( 15, 143, 285, 182, html, (bool)false, (bool)true);
				AddButton(10, 330, 4005, 4007, 1, GumpButtonType.Reply, 0 );
				AddLabel(47, 331, 1152, @"Animal lore gump");
				AddLabel(221, 331, 1152, @"Reload");
				AddButton(270, 330, 4011, 4013, 2, GumpButtonType.Reply, 0 );
				AddTooltip( 3005099 ); //Reload
			}

			public override void OnResponse(NetState sender, RelayInfo info)
			{
				Mobile from = sender.Mobile;
				if ( m_Golem == null || m_Golem.Deleted || m_Golem.IsDeadBondedPet || from.Map != m_Golem.Map )
					return;

				switch(info.ButtonID)
				{
					case 0:
						{
							break;
						}
					case 1:
						{
							from.CloseGump( typeof( Server.SkillHandlers.AnimalLoreGump ) );
							from.SendGump( new Server.SkillHandlers.AnimalLoreGump( m_Golem ) );
							break;
						}
					case 2:
						{
							from.CloseGump( typeof( LookAtGump ) );
							from.SendGump( new LookAtGump( from, m_Golem ) );
							break;
						}
				}
			}
		}
		
		public override int GetAngerSound()
		{
			return 541;
		}

		public override int GetIdleSound()
		{
			if ( !Controlled )
				return 542;

			return base.GetIdleSound();
		}

		public override int GetDeathSound()
		{
			if ( !Controlled )
				return 545;

			return base.GetDeathSound();
		}

		public override int GetAttackSound()
		{
			return 562;
		}

		public override int GetHurtSound()
		{
			if ( Controlled )
				return 320;

			return base.GetHurtSound();
		}

		public EvoGolem( string name ) : base( name, AIType.AI_Melee, 0.01 )
		{
         SpeechHue = Utility.RandomDyedHue();
         EmoteHue = Utility.RandomDyedHue();
         
         CreateWeapon();
		}
		
		private void CreateWeapon()
		{
        BaseWeapon weapon = new HammerPick();
        weapon.Name = "Golem's Hammer";
        weapon.Layer = Layer.TwoHanded;
        weapon.Skill = SkillName.Wrestling;
        weapon.WeaponAttributes.SelfRepair = 10;
        weapon.MaxHitPoints = 500;
        weapon.HitPoints = 500;
        AddItem( weapon );
        weapon.Movable = false;
      }

		public EvoGolem( Serial serial ) : base( serial )
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);

			writer.Write( (int)1 );
			
			writer.Write( m_Absorb );
			writer.Write( m_Reflect );
		}

		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);

			int version = reader.ReadInt();
			
			m_Absorb = reader.ReadInt();
			m_Reflect = reader.ReadInt();
			
			if ( version < 1 )
			   CreateWeapon();
			
			this.MeleeDamageAbsorb = ( (this.Stage + 1) * 10 ) * 10;
		}
	}
}
