using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;

namespace Server.Items
{
    public enum IsTileType
    {
        Flamestrike,
        Fireball,
        Lightning,
        Poison
    }

    public class ISTile5 : Item
    {
        private int m_Damage;
        private IsTileType m_Type;
        private DateTime m_NextTriggerTime = DateTime.Now;

        public static string[] TypeText = new string[]
		{
			"flamestrike",
			"fireball",
			"lightning",
			"poison"
		};

        public static int[] TypeItemID = new int[]
		{
			6099,
			6108,
			6117,
			6144
		};

        [CommandProperty(AccessLevel.GameMaster)]
        public int Damage
        {
            get { return m_Damage; }
            set
            {
                m_Damage = value;
                if ( m_Damage < 1 ) m_Damage = 1;
                Name = String.Format("area {0} trap [{1}% dmg]", TypeText[(int)m_Type], m_Damage);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public IsTileType Type
        {
            get { return m_Type; }
            set
            {
                m_Type = value;
                Name = String.Format("area {0} trap [{1}% dmg]", TypeText[(int)m_Type], m_Damage);
                ItemID = TypeItemID[(int)m_Type];
            }
        }

        [Constructable]
        public ISTile5()
            : this(30, IsTileType.Fireball)
        {
        }

        [Constructable]
        public ISTile5(int damage)
            : this(damage, IsTileType.Fireball)
        {
        }

        [Constructable]
        public ISTile5(int damage, IsTileType type)
            : base(6099)
        {
            Weight = 1.0;
            Visible = false;
            Movable = false;
            Hue = 1;
            m_Damage = damage;

            if (((int)type) > 3 || ((int)type) < 0)
                type = IsTileType.Poison;

            m_Type = type;
            Name = String.Format("area {0} trap [{1}% dmg]", TypeText[(int)m_Type], m_Damage);
            ItemID = TypeItemID[(int)m_Type];
        }

        public ISTile5(Serial serial)
            : base(serial)
        {
        }

        public override bool OnMoveOver(Mobile m)
        {
            if (!m.Player || !m.Alive || m.Blessed || DateTime.Now < m_NextTriggerTime || m.AccessLevel > AccessLevel.Player)
                return true;

            if (!BaseTrap.CheckResisted(m))
            {
                m_NextTriggerTime = DateTime.Now + TimeSpan.FromSeconds( 1.5 );
                Aura();
            }

            return true;
        }

        private void Aura()
        {
            ArrayList targets = new ArrayList();

            foreach (Mobile m in this.GetMobilesInRange(6))
            {
                if (m == null || m.Deleted)
                    continue;

                if (m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned))
                {
                    if (!m.IsDeadBondedPet && m.Alive && !m.Blessed && m.InLOS(this))
                        targets.Add(m);
                }
                else if (m.Player && !m.Blessed && m.AccessLevel == AccessLevel.Player && m.Alive && m.InLOS(this))
                    targets.Add(m);
            }

            for (int i = 0; i < targets.Count; ++i)
            {
                Mobile m = (Mobile)targets[i];

                if (m == null || m.Deleted)
                    continue;

                m.RevealingAction();

                int auradamage = Engines.XmlSpawner2.XmlSpecial.PercentualDamage( GetDamage( m_Damage, m ), m );
                int scalebyrange;

                if (m.InRange(this.Location, 3))
                    scalebyrange = 1;
                else
                    scalebyrange = 2;

                auradamage /= scalebyrange;

                switch (m_Type)
                {
                    case IsTileType.Flamestrike:
                        {
                            m.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.Waist);
                            Effects.SendMovingEffect(this, m, 0x36D4, 5, 0, false, false);
                            m.PlaySound(0x208);
                            break;
                        }
                    case IsTileType.Fireball:
                        {
				                m.FixedParticles( 0x36BD, 20, 10, 5044, EffectLayer.Head );
				                m.PlaySound( 0x307 );
                            Effects.SendMovingEffect(this, m, 0x36D4, 5, 0, false, false);
                            break;
                        }
                    case IsTileType.Lightning:
                        {
                            m.BoltEffect(0);
                            break;
                        }
                    case IsTileType.Poison:
                        {
                            m.FixedParticles(0x374A, 10, 15, 5021, EffectLayer.Waist);
                            m.PlaySound(0x231);
                            m.ApplyPoison(m, Poison.Deadly);
                            break;
                        }
                }
                
                m.Hits -= auradamage;
                SendDmgPacket( m, auradamage );
                if (m.Hits < 2)
                  m.Kill();
            }
        }
        
        public static int GetDamage( int damage, Mobile from )
        {
            int gLevel = Guilds.Guild.GetLevel( from );
            
            if ( gLevel > 0 )            
               damage -= Math.Min( 10, (int) ( gLevel / 3 ) );

            return Math.Max( 1, damage );
        }
        
        public static void SendDmgPacket( Mobile to, int amount )
        {
            if ( to == null )
               return;
               
				if ( to.NetState != null && amount > 0 )
				{
					Packet p = null;
               bool newPacket = ( to.NetState.Version != null && to.NetState.Version >= DamagePacket.Version );

					if ( newPacket )
						p = Packet.Acquire( new DamagePacket( to, amount ) );
					else
						p = Packet.Acquire( new DamagePacketOld( to, amount ) );

					to.NetState.Send( p );
					Packet.Release( p );
				}
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version

            writer.Write(m_Damage);
            writer.Write((int)m_Type);
        }

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

            int version = reader.ReadInt();

            m_Damage = reader.ReadInt();
            m_Type = (IsTileType)reader.ReadInt();
            Name = String.Format("area {0} trap [{1}% dmg]", TypeText[(int)m_Type], m_Damage);
        }
    }
}