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

namespace Server
{
    public class Utilitky
    {
        public static ArrayList GetTargets(Mobile mob, int range, bool pets)
        {
            ArrayList targets = new ArrayList();

            foreach (Mobile m in mob.GetMobilesInRange(range))
            {
                if (mob == null || m == mob || !mob.CanBeHarmful(m) || !m.InLOS(mob))
                    continue;

                if (pets && IsPlayersPet(m))
                {
                    targets.Add(m);
                }
                else if (m.Player && m.AccessLevel == AccessLevel.Player)
                    targets.Add(m);
            }

            return targets;
        }

        public static ArrayList GetPlayerTargets(Mobile mob, int range)
        {
            ArrayList targets = new ArrayList();

            foreach (Mobile m in mob.GetMobilesInRange(range))
            {
                if (mob == null || m == mob || !mob.CanBeHarmful(m) || !m.InLOS(mob))
                    continue;

                if (m is BaseCreature && !(((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned))
                {
                    if (!m.IsDeadBondedPet && m.Alive && !m.Blessed)
                        targets.Add(m);
                }
            }

            return targets;
        }

        public static bool IsPlayersPet(Mobile m)
        {
            if (m is BaseCreature)
            {
                BaseCreature bc = (BaseCreature)m;

                if (bc.Controlled || bc.Summoned)
                {
                    if (bc.ControlMaster is PlayerMobile)
                        return true;
                    else if (bc.SummonMaster is PlayerMobile)
                        return true;
                }
            }

            return false;
        }

        public static int[] RandomUniqueNumbers(int start, int end)
        {
            List<int> numbers = new List<int>((end - start) + 1);
            int[] returning = new int[(end - start) + 1];

            for (int i = start; i <= end; i++)
            {
                numbers.Add(i);
            }

            Random r = new Random();
            int c = 0;

            while (numbers.Count > 0)
            {
                int index = r.Next(numbers.Count);
                returning[c] = numbers[index];
                numbers.RemoveAt(index);
                c++;
            }

            return returning;
        }

        //Corpse Explosion (monster)
        public static void CorpseExplosion(Mobile victim, Mobile from)
        {
            if (victim != null && !victim.Deleted && victim.Alive && from != null && !from.Deleted && from.Alive)
            {
                int count = 0;

                foreach (Item item in victim.GetItemsInRange(2))
                {
                    if (item is Corpse)
                    {
                        Corpse corpse = (Corpse)item;

                        if (corpse.Hue == 2544 || corpse.Owner is PlayerMobile)
                            continue;
                        else
                        {
                            Timer.DelayCall(TimeSpan.FromMilliseconds(Utility.RandomMinMax(500, 3000)), new TimerStateCallback(ExplodeNearbyCorpse), new object[] { corpse, victim, from });
                            count++;

                            if (count > 2)
                                break;
                        }
                    }
                }
            }
        }

        private static void ExplodeNearbyCorpse(object state)
        {
            object[] args = (object[])state;
            Corpse corpse = (Corpse)args[0];
            Mobile victim = (Mobile)args[1];
            Mobile from = (Mobile)args[2];

            if (corpse == null || corpse.Deleted || corpse.Owner == null || victim == null || victim.Deleted || !victim.Alive || from == null)
                return;
            else
            {
                Effects.SendLocationParticles(EffectItem.Create(corpse.Location, corpse.Map, EffectItem.DefaultDuration), 14000, 9, 32, 5024);
                Effects.PlaySound(corpse.Location, corpse.Map, Utility.RandomList(0x309, 0x208, 0x307));

                victim.RevealingAction();
                from.DoHarmful(victim);

                int auradamage = AOS.Scale(corpse.Owner.HitsMax, Utility.RandomMinMax(30, 45));

                if (victim is Xanthos.Interfaces.IEvoCreature)
                    auradamage *= 2;

                victim.Hits -= auradamage;
                ISTile5.SendDmgPacket(victim, auradamage);

                if (victim.Hits < 2)
                    victim.Kill();

                corpse.Channeled = true;
                corpse.ProcessDelta();
                corpse.SendRemovePacket();
                corpse.ItemID = Utility.Random(0xECA, 9); // bone graphic
                corpse.Hue = 2544;
                corpse.ProcessDelta();
            }
        }

        public static void IncreaseByDirection(ref Point3D point, Direction d)
        {
            switch (d)
            {
                case (Direction)0x0:
                case (Direction)0x80:
                    point.Y--;
                    break; //North
                case (Direction)0x1:
                case (Direction)0x81:
                    {
                        point.X++;
                        point.Y--;
                        break;
                    }//Right
                case (Direction)0x2:
                case (Direction)0x82:
                    point.X++;
                    break; //East
                case (Direction)0x3:
                case (Direction)0x83:
                    {
                        point.X++;
                        point.Y++;
                        break;
                    }//Down
                case (Direction)0x4:
                case (Direction)0x84:
                    point.Y++;
                    break; //South
                case (Direction)0x5:
                case (Direction)0x85:
                    {
                        point.X--;
                        point.Y++;
                        break;
                    }//Left
                case (Direction)0x6:
                case (Direction)0x86:
                    point.X--;
                    break; //West
                case (Direction)0x7:
                case (Direction)0x87:
                    {
                        point.X--;
                        point.Y--;
                        break;
                    }//Up
                default:
                    {
                        break;
                    }
            }
        }
    }
}
