using System;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using Server.Targeting;
using Server.Network;
using Server.Targets;
using Server.Misc;
using Server.Commands;
using Server.Spells;
using Server.Mobiles;
using Server.Factions;

namespace Server.Mobiles
{
	[CorpseName( "a rotting corpse" )]
	public class Zombiex : BaseCreature
	{

		public override bool CanRegenHits{ get{ return false; } }		
		public override bool IsScaredOfScaryThings{ get{ return false; } }
		public override bool IsScaryToPets{ get{ return false; } }
		private RotTimer m_Timer;

		[Constructable]
		public Zombiex() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.4 )
		{
			Name = "Infected";

			BaseSoundID = 471;

			SetStr( 40 );
			SetDex( 25 );
			SetInt( 10 );

			SetHits( 60 );
			SetStam( 50 );
			SetMana( 0 );

			SetDamage( 10, 15 );

			//SetDamageType( ResistanceType.Physical, 25 );
			//SetDamageType( ResistanceType.Cold, 25 );
			//SetDamageType( ResistanceType.Poison, 50 );

			//SetResistance( ResistanceType.Physical, 30, 40 );
			//SetResistance( ResistanceType.Fire, 0, 10 );
			//SetResistance( ResistanceType.Cold, 99, 100 );
			//SetResistance( ResistanceType.Poison, 99, 100 );
			//SetResistance( ResistanceType.Energy, 30, 60 );

			//SetSkill( SkillName.Poisoning, 120.0 );
			//SetSkill( SkillName.MagicResist, 100.0 );
			//SetSkill( SkillName.Tactics, 100.0 );
			SetSkill( SkillName.Wrestling, 90.1, 100.0 );

			//PassiveSpeed = .8;
			//ActiveSpeed = .15;

            		InitBody();
            		InitOutfit();

			/*
			Container pack = new Backpack(); 
			pack.Movable = false; 
			AddItem( pack ); 
			*/


//Remove timer here to stop decay don't forget the Deserialize timer 
//			m_Timer = new RotTimer(this);
//            		m_Timer.Start();
		}

        #region Initialize
        public virtual void InitBody()
        {
            if (Female = Utility.RandomBool())
            {
                Body = 0x191;
		Hue = 908;

            }
            else
            {
                Body = 0x190;
		Hue = 908;

                // add beard
                switch (Utility.Random(6))
                {
                    default: FacialHairItemID = 0x00; break; //None
                    case 0: FacialHairItemID = 0x2041; break; //Mustache
                    case 1: FacialHairItemID = 0x203F; break; //ShortBeard
                    case 2: FacialHairItemID = 0x204D; break; //Vandyke
                    case 3: FacialHairItemID = 0x203E; break;//LongBeard
                    case 4: FacialHairItemID = 0x2040; break;//Goatee

                }
            }

            switch (Utility.Random(7))
            {
                case 0: HairItemID = 0x2047; break; //Afro
                case 1: HairItemID = 0x2045; break; //PageboyHair
                case 2: HairItemID = 0x203D; break; //PonyTail
                case 3: HairItemID = 0x203B; break; //ShortHair
                case 4: HairItemID = 0x2049; break; //TwoPigTails
                case 5: HairItemID = 0x203C; break; //LongHair
                case 6:
                    {
                        if (Female)
                            HairItemID = 0x2046; //BunsHair
                        else
                            HairItemID = 0x2048; //ReceedingHair
                        break;
                    }
            }


            HairHue = 915;
            FacialHairHue = 915;
            SpeechHue = Utility.RandomDyedHue();
        }

        public virtual void InitOutfit()
        {

            // shoes 
            switch (Utility.Random(6))
            {
                case 0: break; // barefoot 
                case 1: AddItem(new Shoes()); break; 
                case 2: AddItem(new Sandals()); break; 
                case 3: AddItem(new Shoes()); break; 
                case 4: AddItem(new Boots()); break; 
                case 5: AddItem(new ThighBoots()); break;
            }

            if (Female)
            {
                switch (Utility.Random(3))
                {
                    case 0: 
                        {
                            switch (Utility.Random(2))
                            {
                                case 0: AddItem(new ShortPants()); break;
                                case 1: AddItem(new Kilt()); break;
                            }

                            break;
                        }
                    case 1: 
                        {
                            switch (Utility.Random(4))
                            {
                                case 0:
                                    {
                                        AddItem(new PlainDress());
                                        break;
                                    }
                                case 1:
                                    {
                                        AddItem(new Skirt());
                                        AddItem(new Shirt());
                                        break;
                                    }
                                case 2:
                                    {
                                        AddItem(new LongPants());
                                        AddItem(new Shirt());
                                        break;
                                    }
                                case 3:
                                    {
                                        AddItem(new ShortPants());
                                        AddItem(new Shirt());
                                        break;
                                    }
                            }


                            if (Utility.RandomDouble() < .08)
                                AddItem(new FullApron(Utility.RandomNeutralHue()));

                            if (Utility.RandomBool())
                                AddItem(new GoldRing());

                            break;
                        }
                    case 2: 
                        {
                            switch (Utility.Random(2))
                            {
                                case 0:
                                    {
                                        AddItem(new Skirt());
                                        switch (Utility.Random(2))
                                        {
                                            case 0: AddItem(new FancyShirt()); break;
                                            case 1: AddItem(new Shirt()); break;
                                        }
                                        break;
                                    }
                                case 1:
                                    {
                                        AddItem(new FancyDress());
                                        if (Utility.RandomDouble() < .667)
                                            AddItem(new Cloak());

                                        break;
                                    }
                            }


                            if (Utility.RandomBool())
                                AddItem(new GoldRing());
                            if (Utility.RandomBool())
                                AddItem(new GoldEarrings());
                            if (Utility.RandomDouble() < .2)
                                AddItem(new GoldBracelet());
                            if (Utility.RandomDouble() < .2)
                                AddItem(new GoldBeadNecklace());
                            else if (Utility.RandomDouble() < .2)
                                AddItem(new GoldNecklace());

                            break;
                        }
                }
            }
        #endregion

            else // Male 
            {
                switch (Utility.Random(2))
                {
                    case 0: 
                        {
                            switch (Utility.Random(2))
                            {
                                case 0: AddItem(new LongPants(Utility.RandomNeutralHue())); break;
                                case 1: AddItem(new ShortPants(Utility.RandomNeutralHue())); break;
                            }
                            break;
                        }
                    case 1: 
                        {
                            switch (Utility.Random(3))
                            {
                                case 0: AddItem(new FancyShirt()); break;
                                case 1: AddItem(new Doublet()); break;
                                case 2: AddItem(new Shirt()); break;
                            }

                            switch (Utility.Random(2))
                            {
                                case 0: AddItem(new LongPants()); break;
                                case 1: AddItem(new ShortPants()); break;
                            }


                            if (Utility.RandomDouble() < .16)
                                AddItem(new FullApron(Utility.RandomNeutralHue()));

                            if (Utility.RandomBool())
                                AddItem(new GoldRing());

                            break;
                        }
                    case 2: 
                        {
                            AddItem(new LongPants());

                            switch (Utility.Random(2))
                            {
                                case 0: AddItem(new FancyShirt()); break;
                                case 1: AddItem(new Shirt()); break;
                            }

                            if (Utility.RandomBool())
                                AddItem(new Cloak());
                            if (Utility.RandomBool())
                                AddItem(new BodySash());


                            if (Utility.RandomBool())
                                AddItem(new GoldRing());
                            if (Utility.RandomDouble() < .2)
                                AddItem(new GoldBracelet());

                            break;
                        }
                }
            }
        }

		public override void GenerateLoot()
		{
			AddLoot( LootPack.Poor );
		}

		//public override bool OnBeforeDeath()
		//{
		//	m_Timer.Stop();
		//	return base.OnBeforeDeath();	
		//}

		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			//This finds the mobiles in the area looking for enemies 
			if (!m.Hidden && InRange( m, 20 ) && !InRange( oldLocation, 1 ) && InLOS( m ))
			{
				if (IsEnemy(m) &&  m.AccessLevel < AccessLevel.Counselor)
				{
					this.Combatant = (m);
				}
				
				//This deals with the Zombie's calls to other zombiex's in the area 
				if ( m is Zombiex && this.Combatant != null )
				{
					if ( m.Combatant == null )
					{
						m.Combatant = this.Combatant;
						m.Say ("*Moan*");  // what does the zombie getting called say
						this.Say("*MMooaann*"); // what does the zombie doing the calling say
					}			
				}
			}
			return;

		}

		public override bool IsEnemy( Mobile m )
		{
			//What should the zombie not Attack? figured the not attack list would be smaller than an attack list
			if ( m is Zombiex || m is AncientLich || m is Bogle || m is LichLord || m is Shade || m is Spectre || m is Wraith || m is BoneKnight || m is Ghoul || m is Mummy || m is SkeletalKnight || m is Skeleton || m is Zombie || m is ShadowKnight || m is DarknightCreeper || m is RevenantLion || m is LadyOfTheSnow || m is RottingCorpse || m is SkeletalDragon || m is Lich || m is Cow || m is Cat || m is Dog || m is Hind || m is Bird || m is Rabbit || m is Chicken || m is Sheep) 
			    return false;

			
            		else
    			return true;
		}

		public override void OnGotMeleeAttack( Mobile attacker )
		{
			if ( this.HitsMaxSeed < 10 )
			{
				this.HitsMaxSeed = 10;
			}
			if ( this.Hits < this.HitsMax / 4 )
			{
				this.CantWalk = true; 
			}
			if ( attacker is PlayerMobile )
			{
				switch ( Utility.Random( 2 ) )
				{
					case 0: this.Str -= 1; 
						//this.Say(" losing 1 Str from getting hit"); 
						break;
					//case 1: this.HitsMaxSeed -= Utility.RandomMinMax(1,10); break;  
				}	
			}
		}

		public override void OnGaveMeleeAttack( Mobile defender )
		{
			base.OnGaveMeleeAttack( defender );

			if ( defender is BaseCreature )
			{
				switch ( Utility.Random( 4 ) )
				{
					case 0: this.Str -= 1;
						//this.Say(" losing 1 Str from hitting"); 
						break;	
				}
			}
		}

		public Item CloneItem( Item item )
		{
			if ((item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack))
			{
				Item newItem = new Item( item.ItemID );
				newItem.Hue = item.Hue;
				newItem.Layer = item.Layer;

				return newItem;
			}
			/* 
			else
			{
				Item newItem = new Bandage();
				return newItem;
			}*/
			return null;
		}

		public virtual void BaseCreatureModule(Mobile from, Zombiex zomb)
		{
			BaseCreature mob = (BaseCreature) from;
			//What Should the Zombie virus not affect
			//if ( this.Summoned || this is Zombiex || this is AncientLich || this is Bogle || this is LichLord || this is Shade || this is Spectre || this is Wraith || this is BoneKnight || this is Ghoul || this is Mummy || this is SkeletalKnight || this is Skeleton || this is Zombie || this is ShadowKnight || this is DarknightCreeper || this is RevenantLion || this is LadyOfTheSnow || this is RottingCorpse || this is SkeletalDragon || this is AirElemental || this is IceElemental || this is ToxicElemental || this is PoisonElemental || this is FireElemental || this is WaterElemental || this is EarthElemental || this is Efreet || this is SnowElemental || this is AgapiteElemental || this is BronzeElemental || this is CopperElemental || this is DullCopperElemental || this is GoldenElemental || this is ShadowIronElemental || this is ValoriteElemental || this is VeriteElemental || this is BloodElemental ) 
			if (!mob.CanInfect)
			{
				zomb.Delete();
				return;
			}
			else 
			{
				double dhits, dstr;

				//Zombiex zomb = new Zombiex();
					
				zomb.Female = mob.Female;
				zomb.Body = mob.Body;
				zomb.Hue = 908;
				zomb.Name = mob.Name;
				zomb.Title = "*Infected*";

				zomb.HairItemID = mob.HairItemID;
				zomb.HairHue = mob.HairHue;
				zomb.FacialHairItemID = mob.FacialHairItemID;
				zomb.FacialHairHue = mob.FacialHairHue;

				dhits = mob.HitsMax/2;
				dstr = mob.Str/2;

				for ( int i = 0; i < mob.Skills.Length; ++i )
				{
					zomb.Skills[i].Base = mob.Skills[i].Base;
					zomb.Skills[i].Cap = mob.Skills[i].Cap;
				}

				for( int i = 0; i < mob.Items.Count; i++ )
				{
					zomb.AddItem( zomb.CloneItem( mob.Items[i] ) );
				}
				
				zomb.HitsMaxSeed = mob.HitsMax + (int) dhits;
				zomb.Hits = mob.HitsMax + (int) dhits;
				zomb.Str = mob.Str + (int) dstr; 
				zomb.MoveToWorld(mob.Location, mob.Map);
				mob.Delete();
			}
		}

		public virtual void PlayerMobileModule(Mobile from, Zombiex zomb)
		{
			PlayerMobile mob = (PlayerMobile) from;

			double dhits, dstr;
			//Zombiex zomb = new Zombiex();
					
			zomb.Female = mob.Female;
			zomb.Body = mob.Body;
			zomb.Hue = 908;
			zomb.Name = mob.Name;
			zomb.Title = "*Infected*";

			zomb.HairItemID = mob.HairItemID;
			zomb.HairHue = mob.HairHue;
			zomb.FacialHairItemID = mob.FacialHairItemID;
			zomb.FacialHairHue = mob.FacialHairHue;

			dhits = mob.HitsMax/2;
			dstr = mob.Str/2;
			for ( int i = 0; i < mob.Skills.Length; ++i )
			{
				zomb.Skills[i].Base = mob.Skills[i].Base;
				zomb.Skills[i].Cap = mob.Skills[i].Cap;
			}
			
			if ( mob.Mounted )
			{
				if ( mob.Mount is EtherealMount )
				{
					EtherealMount pet = mob.Mount as EtherealMount;
					pet.Internalize();
					pet.Rider = null;
				}
				else if ( mob.Mount is BaseMount )
				{
					BaseMount petm = mob.Mount as BaseMount;
					petm.Rider = null;
					BaseCreature pet = petm as BaseCreature;
					pet.Internalize();
					pet.ControlTarget = null;
					pet.SetControlMaster( null );
					pet.SummonMaster = null;
					pet.MoveToWorld(zomb.Location, zomb.Map);
				}
			}
			
			for( int i = 0; i < mob.Items.Count; i++ )
			{
				zomb.AddItem( zomb.CloneItem( mob.Items[i] ) );
			}

			Container pack = mob.Backpack;
			ArrayList equipitems = new ArrayList(mob.Items);
			foreach (Item item in equipitems)
			{
				if ((item.Insured == false) && (item.LootType != LootType.Blessed) && (item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack) && (item.Layer != Layer.Hair) && (item.Layer != Layer.FacialHair))
				{
					pack.DropItem( item );
				}
			}

			Backpack bag = new Backpack();
			
			ArrayList packitems = new ArrayList( pack.Items );
			foreach (Item items in packitems)
			{
				if ((items.Insured == false) && (items.LootType != LootType.Blessed))
				{
					bag.DropItem(items);
				}
			}

			bag.Hue = 768;
			//bag.MoveToWorld (zomb.Location, zomb.Map);
			zomb.AddItem( bag );

			zomb.HitsMaxSeed = mob.HitsMax + (int) dhits;
			zomb.Hits = mob.HitsMax + (int) dhits;
			zomb.Str = mob.Str + (int) dstr; 
			zomb.MoveToWorld(mob.Location, mob.Map);
		}

		private class RotTimer : Timer
		{
			private Mobile m_Mobile;

//Change timespan to change the rate of decay 

			public RotTimer( Mobile m ) : base( TimeSpan.FromMinutes( 1.0 ) )
			{
				m_Mobile = m;
			}

			protected override void OnTick()
			{
				RotTimer rotTimer = new RotTimer( m_Mobile );
				if ( m_Mobile.Str < 2 )
				{
					m_Mobile.Kill();
					Stop();
				}
				else
				{
					if ( m_Mobile.Hits > m_Mobile.HitsMax / 2 ) 
					{
						m_Mobile.Hits -= m_Mobile.HitsMax / 100;
						//m_Mobile.Say(" losing 1% Hits");
					}
						
					if ( m_Mobile.Hits <= m_Mobile.HitsMax / 2 )
					{ 
						m_Mobile.Hits -= 1;
						//m_Mobile.Say(" losing 1 Hitpoint");
					}

					if ( m_Mobile.Hits < m_Mobile.HitsMax / 4 )  
					{
						m_Mobile.CantWalk = true;
						//m_Mobile.Say(" Cant Walk Anymore");
					}

					if ( m_Mobile.Str > 100 )
					{ 
						m_Mobile.Str -= m_Mobile.Str / 30;
						//m_Mobile.Say(" losing 3.33% Str");
					}

					if ( m_Mobile.Str <= 100 )
					{ 
						m_Mobile.Str -= 1;
						//m_Mobile.Say(" losing 1 Str point");
					}
					rotTimer.Start();
				}
			}
		}

		public override bool AlwaysMurderer{ get{ return true; } }

		public override bool BleedImmune{ get{ return true; } }
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
		//public override Poison HitPoison{ get{ return Poison.Lethal; } }
		public override bool CanRummageCorpses{ get{ return true; } }

		public Zombiex( Serial serial ) : base( serial )
		{
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 0 );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();

//Remove timer here to stop decay but don't forget the one Constructable section!
//			m_Timer = new RotTimer(this);
//            m_Timer.Start();
		}
	}
}