#region References
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading;

using Server.Accounting;
using Server.ContextMenus;
using Server.Diagnostics;
using Server.Gumps;
using Server.HuePickers;
using Server.Items;
using Server.Menus;
using Server.Menus.ItemLists;
using Server.Menus.Questions;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
#endregion

namespace Server.Network
{	
    public sealed class SmoothMovement : Packet
    {
        public SmoothMovement(BaseSmoothMulti multi, DynamicComponentList objectsToMove)
            : base(0xF6)
        {
            var length = (short)(18 + (objectsToMove.Count * 10));
			EnsureCapacity(length);

			length = (short)(((length & 0xff) << 8) | ((length >> 8) & 0xff));
			m_Stream.Seek(1, SeekOrigin.Begin);
			m_Stream.Write(length);			
			
            m_Stream.Write((int)multi.Serial);
            m_Stream.Write((byte)multi.Speed);
            m_Stream.Write((byte)multi.Moving);
            m_Stream.Write((byte)multi.Facing);

            m_Stream.Write((short)multi.X);
            m_Stream.Write((short)multi.Y);
            m_Stream.Write((short)multi.Z);

            m_Stream.Write((short)(objectsToMove.Count));
			
            objectsToMove.ForEachObject(onBoard =>
            {
                m_Stream.Write((int)onBoard.Serial);
                m_Stream.Write((short)onBoard.X);
                m_Stream.Write((short)onBoard.Y);
                m_Stream.Write((short)onBoard.Z);
            },
            onBoard =>
            {
                m_Stream.Write((int)onBoard.Serial);
                m_Stream.Write((short)onBoard.X);
                m_Stream.Write((short)onBoard.Y);
                m_Stream.Write((short)onBoard.Z);
            }
            );
        }
    }

    public sealed class ContainerMultiList : Packet
    {
        public ContainerMultiList(BaseSmoothMulti smoothMulti, DynamicComponentList objectsOnBoard)
            : base(0xF7)
        {	
            EnsureCapacity(5 + objectsOnBoard.Count * 26);
			
            m_Stream.Write((short)objectsOnBoard.Count);
			
			WorldItemHSMultiList(smoothMulti);
			
			objectsOnBoard.ForEachObject(
                item => WorldItemHSMultiList(item), 
                mob => WorldItemHSMultiList(mob));	
        }
		
		private void WorldItemHSMultiList(Item item)
		{
            m_Stream.Write((short)0x1);

            int itemID = item.ItemID;

            if (item is BaseMulti)
            {
                m_Stream.Write((byte)0x02);
                m_Stream.Write((int)item.Serial);
                itemID &= 0x3FFF;
                m_Stream.Write((ushort)itemID);
                m_Stream.Write((byte)0);
            }
            else
            {
                m_Stream.Write((byte)0x00);
                m_Stream.Write((int)item.Serial);
                itemID &= 0xFFFF;
                m_Stream.Write((ushort)itemID);
                m_Stream.Write((byte)0);
            }

            int amount = item.Amount;
            m_Stream.Write((short)amount);
            m_Stream.Write((short)amount);

            Point3D loc = item.Location;
            int x = loc.X & 0x7FFF;
            int y = loc.Y & 0x3FFF;
            m_Stream.Write((short)x);
            m_Stream.Write((short)y);
            m_Stream.Write((sbyte)loc.Z);

            m_Stream.Write((byte)item.Light);
            m_Stream.Write((short)item.Hue);
            m_Stream.Write((byte)item.GetPacketFlags());

            m_Stream.Write((short)0x00); // ??
		}
		
		private void WorldItemHSMultiList(Mobile mob)
		{
            m_Stream.Write((short)0x1);

            m_Stream.Write((byte)0x01);
            m_Stream.Write((int)mob.Serial);
            m_Stream.Write((ushort)mob.BodyValue);
            m_Stream.Write((byte)0);

            int amount = 1;
            m_Stream.Write((short)amount);
            m_Stream.Write((short)amount);

            Point3D loc = mob.Location;
            int x = loc.X & 0x7FFF;
            int y = loc.Y & 0x3FFF;
            m_Stream.Write((short)x);
            m_Stream.Write((short)y);
            m_Stream.Write((sbyte)loc.Z);

            m_Stream.Write((byte)mob.LightLevel);
            m_Stream.Write((short)mob.Hue);
            m_Stream.Write((byte)mob.GetPacketFlags());

            m_Stream.Write((short)0x00); // ??
		}		
	}
}