using Server;
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Regions;
using Server.Targeting;
using System;

namespace Server.Items
{
    public enum DecorateCommand
    {
        None,
        Secure,
        Lockdown,
        Release,
        Turn,
        Up,
        Down,
        North,
        East,
        South,
        West,
        Close
    }

    public class InteriorDecorator : Item
    {
        private DecorateCommand m_Command;

		[Constructable]
		public InteriorDecorator() : base( 0x1EBA )
		{
			Name = "Homeowner Tools";
			Weight = 1.0;
		}

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

        [CommandProperty(AccessLevel.GameMaster)]
        public DecorateCommand Command
        {
            get { return m_Command; }
            set
            {
                m_Command = value;
                InvalidateProperties();
            }
        }

        public static bool InHouse(Mobile from)
        {
            BaseHouse house = BaseHouse.FindHouseAt(from);

            return (house != null && house.IsFriend(from));
        }

        public static bool CheckUse(InteriorDecorator tool, Mobile from)
        {
            if (!InHouse(from))
                from.SendLocalizedMessage(502092); // You must be in your house to do this.
            else
                return true;

            return false;
        }

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

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

        public override void OnDoubleClick(Mobile from)
        {
            if (from.FindGump(typeof(InternalGump)) == null)
                from.SendGump(new InternalGump(from, this));

            if (m_Command != DecorateCommand.None)
                from.Target = new InternalTarget(this);
        }

        private class InternalGump : Gump
        {
            private readonly InteriorDecorator m_Decorator;

            public InternalGump(Mobile from, InteriorDecorator decorator)
                : base(150, 50)
            {
                m_Decorator = decorator;


                AddBackground(0, 0, 170, 559 , 2600);

                AddPage(0);

                AddButton(40, 45, (decorator.Command == DecorateCommand.Secure ? 2154 : 2152), 2154, 1, GumpButtonType.Reply, 0);
                AddLabel(80, 50, 0, @"Secure"); //secure

                AddButton(40, 85, (decorator.Command == DecorateCommand.Lockdown ? 2154 : 2152), 2154, 2, GumpButtonType.Reply, 0);
                AddLabel(80, 90, 0, @"Lockdown"); // lockdown

                AddButton(40, 125, (decorator.Command == DecorateCommand.Release ? 2154 : 2152), 2154, 3, GumpButtonType.Reply, 0);
                AddLabel(80, 130, 0, @"Release"); // release

                AddButton(40, 165, (decorator.Command == DecorateCommand.Turn ? 2154 : 2152), 2154, 4, GumpButtonType.Reply, 0);
                AddLabel(80, 170, 0, @"Turn"); // Turn

                AddButton(40, 205, (decorator.Command == DecorateCommand.Up ? 2154 : 2152), 2154, 5, GumpButtonType.Reply, 0);
                AddLabel(80, 210, 0, @"Up"); // Up

                AddButton(40, 245, (decorator.Command == DecorateCommand.Down ? 2154 : 2152), 2154, 6, GumpButtonType.Reply, 0);
                AddLabel(80, 250, 0, @"Down"); // Down

                AddButton(40, 285, (decorator.Command == DecorateCommand.North ? 2154 : 2152), 2154, 7, GumpButtonType.Reply, 0);
                AddLabel(80, 290, 0, @"North"); // North

                AddButton(40, 325, (decorator.Command == DecorateCommand.East ? 2154 : 2152), 2154, 8, GumpButtonType.Reply, 0);
                AddLabel(80, 330, 0, @"East"); // East

                AddButton(40, 365, (decorator.Command == DecorateCommand.South ? 2154 : 2152), 2154, 9, GumpButtonType.Reply, 0);
                AddLabel(80, 370, 0, @"South"); // South

                AddButton(40, 405, (decorator.Command == DecorateCommand.West ? 2154 : 2152), 2154, 10, GumpButtonType.Reply, 0);
                AddLabel(80, 410, 0, @"West"); // West

                AddButton(40, 485, (decorator.Command == DecorateCommand.Close ? 2472 : 2472), 2154, 13, GumpButtonType.Reply, 0);
                AddLabel(80, 490, 0, @"Close"); // close

                AddHtmlLocalized(0, 0, 0, 0, 4, false, false);
            }

            public override void OnResponse(NetState sender, RelayInfo info)
            {
                DecorateCommand command = DecorateCommand.None;
                Mobile m = sender.Mobile;

                int cliloc = 0;
                string c_String = null;

                switch (info.ButtonID)
                {
                    case 1://secure
                        c_String = "Select an object to secure."; // Select an object to secure.
                        command = DecorateCommand.Secure;
                        break;
                    case 2://lockdown
                        c_String = "Select an object to lock down."; // Select an object to lock down.
                        command = DecorateCommand.Lockdown;
                        break;
                    case 3://release
                        c_String = "Select an object to release."; // Select an object to release.
                        command = DecorateCommand.Release;
                        break;
                    case 4://turn
                        cliloc = 1073404; // Select an object to turn.
                        command = DecorateCommand.Turn;
                        break;
                    case 5://up
                        cliloc = 1073405; // Select an object to increase its height.
                        command = DecorateCommand.Up;
                        break;
                    case 6://down
                        cliloc = 1073406; // Select an object to lower its height.
                        command = DecorateCommand.Down;
                        break;
                    case 7://north
                        c_String = "Select an object to move north."; // Select an object to move north.
                        command = DecorateCommand.North;
                        break;
                    case 8://east
                        c_String = "Select an object to move east."; // Select an object to move east.
                        command = DecorateCommand.East;
                        break;
                    case 9://south
                        c_String = "Select an object to move south."; // Select an object to move south.
                        command = DecorateCommand.South;
                        break;
                    case 10://west
                        c_String = "Select an object to move west."; // Select an object to move west.
                        command = DecorateCommand.West;
                        break;
                    case 12://Close
                        c_String = "Close"; // Close
                        command = DecorateCommand.Close;
                        break;
                }

                if (command != DecorateCommand.None & command != DecorateCommand.Close)
                {
                    m_Decorator.Command = command;
                    m.SendGump(new InternalGump(m, m_Decorator));

                    if (cliloc != 0)
                        m.SendLocalizedMessage(cliloc);
                    if (c_String != null)
                        m.SendMessage(c_String);

                    m.Target = new InternalTarget(m_Decorator);
                }
                else
                {
                    Target.Cancel(m);
                }
            }
        }

        private class InternalTarget : Target
        {
            private readonly InteriorDecorator m_Decorator;

            public InternalTarget(InteriorDecorator decorator)
                : base(-1, false, TargetFlags.None)
            {
                CheckLOS = false;

                m_Decorator = decorator;
            }

            protected override void OnTargetNotAccessible(Mobile from, object targeted)
            {
                OnTarget(from, targeted);
            }

            protected override void OnTarget(Mobile from, object targeted)
            {
                if (targeted is Item && CheckUse(m_Decorator, from))
                {
                    BaseHouse house = BaseHouse.FindHouseAt(from);
                    Item item = (Item)targeted;

                    bool isDecorableComponent = false;

                    if (item is AddonComponent || item is AddonContainerComponent || item is BaseAddonContainer)
                    {
                        object addon = null;
                        int count = 0;

                        if (item is AddonComponent)
                        {
                            AddonComponent component = (AddonComponent)item;
                            count = component.Addon.Components.Count;
                            addon = component.Addon;
                        }
                        else if (item is AddonContainerComponent)
                        {
                            AddonContainerComponent component = (AddonContainerComponent)item;
                            count = component.Addon.Components.Count;
                            addon = component.Addon;
                        }
                        else if (item is BaseAddonContainer)
                        {
                            BaseAddonContainer container = (BaseAddonContainer)item;
                            count = container.Components.Count;
                            addon = container;
                        }

                        if (m_Decorator.Command == DecorateCommand.Turn)
                        {
                            FlipableAddonAttribute[] attributes = (FlipableAddonAttribute[])addon.GetType().GetCustomAttributes(typeof(FlipableAddonAttribute), false);

                            if (attributes.Length > 0)
                                isDecorableComponent = true;
                        }
                    }

					bool moveAddon = false;

					if ( item is AddonComponent && ( m_Decorator.Command == DecorateCommand.North || m_Decorator.Command == DecorateCommand.South || m_Decorator.Command == DecorateCommand.East || m_Decorator.Command == DecorateCommand.West ) )
						moveAddon = true;

                    if (house == null || !house.IsFriend(from))
                    {
                        from.SendLocalizedMessage(502092); // You must be in your house to do
                    }
                    else if (item.Parent != null || !house.IsInside(item))
                    {
                        from.SendLocalizedMessage(1042270); // That is not in your house.
                    }
                    else if (!house.IsLockedDown(item) && !house.IsSecure(item) && !isDecorableComponent && !(item is BaseAddonDeed) && !moveAddon )
                    {
                        if (item is AddonComponent && m_Decorator.Command == DecorateCommand.Turn)
                            from.SendLocalizedMessage(1042273); // You cannot turn that.
                        else if (item is AddonComponent && m_Decorator.Command == DecorateCommand.Up)
                            from.SendLocalizedMessage(1042274); // You cannot raise it up any higher.
                        else if (item is AddonComponent && m_Decorator.Command == DecorateCommand.Down)
                            from.SendLocalizedMessage(1042275); // You cannot lower it down any further.
                        else if (m_Decorator.Command == DecorateCommand.Secure)
                            Secure(item, from);
                        else if (m_Decorator.Command == DecorateCommand.Lockdown)
                            Lockdown(item, from);
                        else
                            from.SendMessage("That is not locked down or secured.");
                    }
                    else if (item is VendorRentalContract)
                    {
                        from.SendLocalizedMessage(1062491); // You cannot use the house decorator on that object.
                    }
                    else
                    {
                        switch (m_Decorator.Command)
                        {
                            case DecorateCommand.None:
                                None(item, from);
                                break;
                            case DecorateCommand.Secure:
                                Secure(item, from);
                                break;
                            case DecorateCommand.Lockdown:
                                Lockdown(item, from);
                                break;
                            case DecorateCommand.Release:
                                Release(item, from);
                                break;
                            case DecorateCommand.Turn:
                                Turn(item, from);
                                break;
                            case DecorateCommand.Up:
                                Up(item, from);
                                break;
                            case DecorateCommand.Down:
                                Down(item, from);
                                break;
                            case DecorateCommand.North:
                                North(item, from);
                                break;
                            case DecorateCommand.East:
                                East(item, from);
                                break;
                            case DecorateCommand.South:
                                South(item, from);
                                break;
                            case DecorateCommand.West:
                                West(item, from);
                                break;
                            case DecorateCommand.Close:
                                Close(item, from);
                                break;
                        }
                    }
                }

                from.Target = new InternalTarget(m_Decorator);
            }

            protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
            {
                if (cancelType == TargetCancelType.Canceled)
                    from.CloseGump(typeof(InteriorDecorator.InternalGump));
            }

            private static void None(Item item, Mobile from)
            {
            }

            private static void Secure(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(from);
                if (house.IsLockedDown(item))
                    from.SendMessage("That is already locked down.");
                else if (house.IsSecure(item))
                    from.SendMessage("That is already secured.");
                else if (house.IsFriend(from)&&!house.IsCoOwner(from))
                { from.SendMessage("Only Owners and CoOwners are allowed to secure things in a house.");
                    return;
                }
                else
                    house.AddSecure(from, item);
            }

            private static void Lockdown(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(from);
                if (house.IsLockedDown(item))
                    from.SendMessage("That is already locked down.");
                else if (house.IsSecure(item))
                    from.SendMessage("That is already secured.");
                else
                    house.LockDown(from, item, true);
            }

            private static void Release(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(from);
                if (!house.IsLockedDown(item) && !house.IsSecure(item) && (item.Movable))
                    from.SendMessage("That is not locked down or secured.");
                else
                    house.Release(from, item);
            }

            private static void Turn(Item item, Mobile from)
            {
				FlipableAttribute[] attributes = (FlipableAttribute[])item.GetType().GetCustomAttributes(typeof(FlipableAttribute), false);

				Item deed = null;

				if ( item is AnvilEastDeed ){ deed = new AnvilSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is AnvilSouthDeed ){ deed = new AnvilEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is BrownBearRugEastDeed ){ deed = new BrownBearRugSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is BrownBearRugSouthDeed ){ deed = new BrownBearRugEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is PolarBearRugEastDeed ){ deed = new PolarBearRugSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is PolarBearRugSouthDeed ){ deed = new PolarBearRugEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is DartBoardEastDeed ){ deed = new DartBoardSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is DartBoardSouthDeed ){ deed = new DartBoardEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is FlourMillEastDeed ){ deed = new FlourMillSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is FlourMillSouthDeed ){ deed = new FlourMillEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LightFlowerTapestryEastDeed ){ deed = new LightFlowerTapestrySouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LightFlowerTapestrySouthDeed ){ deed = new LightFlowerTapestryEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is DarkFlowerTapestryEastDeed ){ deed = new DarkFlowerTapestrySouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is DarkFlowerTapestrySouthDeed ){ deed = new DarkFlowerTapestryEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is GrayBrickFireplaceEastDeed ){ deed = new GrayBrickFireplaceSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is GrayBrickFireplaceSouthDeed ){ deed = new GrayBrickFireplaceEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LargeBedEastDeed ){ deed = new LargeBedSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LargeBedSouthDeed ){ deed = new LargeBedEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LadderSouthAddonDeed ){ deed = new LadderEastAddonDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LadderEastAddonDeed ){ deed = new LadderSouthAddonDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LargeForgeEastDeed ){ deed = new LargeForgeSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LargeForgeSouthDeed ){ deed = new LargeForgeEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LargeStoneTableEastDeed ){ deed = new LargeStoneTableSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LargeStoneTableSouthDeed ){ deed = new LargeStoneTableEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is LoomEastDeed ){ deed = new LoomSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is LoomSouthDeed ){ deed = new LoomEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is MediumStoneTableEastDeed ){ deed = new MediumStoneTableSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is MediumStoneTableSouthDeed ){ deed = new MediumStoneTableEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is PickpocketDipEastDeed ){ deed = new PickpocketDipSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is PickpocketDipSouthDeed ){ deed = new PickpocketDipEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is SandstoneFireplaceEastDeed ){ deed = new SandstoneFireplaceSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is SandstoneFireplaceSouthDeed ){ deed = new SandstoneFireplaceEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is SmallBedEastDeed ){ deed = new SmallBedSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is SmallBedSouthDeed ){ deed = new SmallBedEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is SpinningwheelEastDeed ){ deed = new SpinningwheelSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is SpinningwheelSouthDeed ){ deed = new SpinningwheelEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is StoneFireplaceEastDeed ){ deed = new StoneFireplaceSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is StoneFireplaceSouthDeed ){ deed = new StoneFireplaceEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is StoneOvenEastDeed ){ deed = new StoneOvenSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is StoneOvenSouthDeed ){ deed = new StoneOvenEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is SmallStretchedHideEastDeed ){ deed = new SmallStretchedHideSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is SmallStretchedHideSouthDeed ){ deed = new SmallStretchedHideEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is MediumStretchedHideEastDeed ){ deed = new MediumStretchedHideSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is MediumStretchedHideSouthDeed ){ deed = new MediumStretchedHideEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is TrainingDummyEastDeed ){ deed = new TrainingDummySouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is TrainingDummySouthDeed ){ deed = new TrainingDummyEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is WaterTroughEastDeed ){ deed = new WaterTroughSouthDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }
				else if ( item is WaterTroughSouthDeed ){ deed = new WaterTroughEastDeed(); deed.MoveToWorld(item.Location, item.Map); item.Delete(); }

				else if ( item is MyTentEastAddonDeed )
				{
					MyTentEastAddonDeed tent = (MyTentEastAddonDeed)item;
					deed = new MyTentSouthAddonDeed();
					MyTentSouthAddonDeed hut = (MyTentSouthAddonDeed)deed;
					deed.Hue = item.Hue;
					hut.TentColor = tent.TentColor;
					deed.MoveToWorld(item.Location, item.Map);
					item.Delete();
				}
				else if ( item is MyTentSouthAddonDeed )
				{
					MyTentSouthAddonDeed tent = (MyTentSouthAddonDeed)item;
					deed = new MyTentEastAddonDeed();
					MyTentEastAddonDeed hut = (MyTentEastAddonDeed)deed;
					deed.Hue = item.Hue;
					hut.TentColor = tent.TentColor;
					deed.MoveToWorld(item.Location, item.Map);
					item.Delete();
				}

				if (attributes.Length > 0)
					attributes[0].Flip(item);
				else if ( item.ItemID != FlipID( item.ItemID ) )
					item.ItemID = FlipID( item.ItemID );
				else
					from.SendLocalizedMessage(1042273); // You cannot turn that.                
            }

            private static void Up(Item item, Mobile from)
            {
                int floorZ = GetFloorZ(item);

                if (floorZ > int.MinValue && item.Z < (floorZ + 14)) // Confirmed : no height checks here
                    item.Location = new Point3D(item.Location, item.Z + 1);
                else
                    from.SendLocalizedMessage(1042274); // You cannot raise it up any higher.
            }

            private static void Down(Item item, Mobile from)
            {
                int floorZ = GetFloorZ(item);

                if (floorZ > int.MinValue && item.Z > GetFloorZ(item))
                    item.Location = new Point3D(item.Location, item.Z - 1);
                else
                    from.SendLocalizedMessage(1042275); // You cannot lower it down any further.
            }

            private static void North(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(item);

                Point3D ourLoc = item.GetWorldLocation();
                Point3D goingLoc = new Point3D(ourLoc.X, ourLoc.Y -2, ourLoc.Z);

                if (house.IsInside(goingLoc, ourLoc.Z))
                    item.Y = (item.Y -1);
                else
                    from.SendMessage("You cannot move it to the north any further.");

            }

            private static void East(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(item);

                Point3D ourLoc = item.GetWorldLocation();
                Point3D goingLoc = new Point3D(ourLoc.X +1, ourLoc.Y, ourLoc.Z);

                if (house.IsInside(goingLoc, ourLoc.Z))
                    item.X = (item.X +1);
                else
                    from.SendMessage("You cannot move it to the east any further.");

            }

            private static void South(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(item);

                Point3D ourLoc = item.GetWorldLocation();
                Point3D goingLoc = new Point3D(ourLoc.X, ourLoc.Y +1, ourLoc.Z);

                if (house.IsInside(goingLoc, ourLoc.Z))
                     item.Y = (item.Y +1); 
                else
                    from.SendMessage("You cannot move it to the south any further.");
            }

            private static void West(Item item, Mobile from)
            {
                BaseHouse house = BaseHouse.FindHouseAt(item);

                Point3D ourLoc = item.GetWorldLocation();
                Point3D goingLoc = new Point3D(ourLoc.X -2, ourLoc.Y, ourLoc.Z);

                if (house.IsInside(goingLoc, ourLoc.Z))
                    item.X = (item.X -1);
                else
                    from.SendMessage("You cannot move it to the west any further.");
            }

            private static void Close(Item item, Mobile from)
            {
                from.CloseGump(typeof(InteriorDecorator.InternalGump));
                Target.Cancel(from);
            }

            private static void Command(Item item, Mobile from)
            {
            }

            private static int GetFloorZ(Item item)
            {
                Map map = item.Map;

                if (map == null)
                    return int.MinValue;

                StaticTile[] tiles = map.Tiles.GetStaticTiles(item.X, item.Y, true);

                int z = int.MinValue;

                for (int i = 0; i < tiles.Length; ++i)
                {
                    StaticTile tile = tiles[i];
                    ItemData id = TileData.ItemTable[tile.ID & 0x3FFF];

                    int top = tile.Z; // Confirmed : no height checks here

                    if (id.Surface && !id.Impassable && top > z && top <= item.Z)
                        z = top;
                }

                if (z == int.MinValue)
                    z = map.Tiles.GetLandTile(item.X, item.Y).Z;

                return z;
            }

			public static int FlipID( int id )
			{
				if ( id == 8356 ){ id = 8357; }
				else if ( id == 8358 ){ id = 8359; }
				else if ( id == 8360 ){ id = 8361; }
				else if ( id == 8362 ){ id = 8363; }
				else if ( id == 8364 ){ id = 8365; }
				else if ( id == 8366 ){ id = 8367; }
				else if ( id == 8368 ){ id = 8369; }
				else if ( id == 8370 ){ id = 8371; }
				else if ( id == 8372 ){ id = 8373; }
				else if ( id == 8374 ){ id = 8375; }
				else if ( id == 8376 ){ id = 8377; }
				else if ( id == 8378 ){ id = 8379; }
				else if ( id == 8380 ){ id = 8381; }
				else if ( id == 8382 ){ id = 8383; }
				else if ( id == 8384 ){ id = 8385; }
				else if ( id == 8386 ){ id = 8387; }
				else if ( id == 8388 ){ id = 8389; }
				else if ( id == 8390 ){ id = 8391; }
				else if ( id == 8392 ){ id = 8393; }
				else if ( id == 8394 ){ id = 8395; }
				else if ( id == 8396 ){ id = 8397; }
				else if ( id == 0xC0F ){ id = 0xC2C; }
				else if ( id == 0xE9F ){ id = 0xEC8; }
				else if ( id == 0xEA0 ){ id = 0xEA9; }
				else if ( id == 0xEA1 ){ id = 0xEA2; }
				else if ( id == 0xEA3 ){ id = 0xEA4; }
				else if ( id == 0xEA5 ){ id = 0x121C; }
				else if ( id == 0xEA7 ){ id = 0x1229; }
				else if ( id == 0xEA8 ){ id = 0x1236; }
				else if ( id == 8357 ){ id = 8356; }
				else if ( id == 8359 ){ id = 8358; }
				else if ( id == 8361 ){ id = 8360; }
				else if ( id == 8363 ){ id = 8362; }
				else if ( id == 8365 ){ id = 8364; }
				else if ( id == 8367 ){ id = 8366; }
				else if ( id == 8369 ){ id = 8368; }
				else if ( id == 8371 ){ id = 8370; }
				else if ( id == 8373 ){ id = 8372; }
				else if ( id == 8375 ){ id = 8374; }
				else if ( id == 8377 ){ id = 8376; }
				else if ( id == 8379 ){ id = 8378; }
				else if ( id == 8381 ){ id = 8380; }
				else if ( id == 8383 ){ id = 8382; }
				else if ( id == 8385 ){ id = 8384; }
				else if ( id == 8387 ){ id = 8386; }
				else if ( id == 8389 ){ id = 8388; }
				else if ( id == 8391 ){ id = 8390; }
				else if ( id == 8393 ){ id = 8392; }
				else if ( id == 8395 ){ id = 8394; }
				else if ( id == 8397 ){ id = 8396; }
				else if ( id == 0xC2C ){ id = 0xC0F; }
				else if ( id == 0xEC8 ){ id = 0xE9F; }
				else if ( id == 0xEA9 ){ id = 0xEA0; }
				else if ( id == 0xEA2 ){ id = 0xEA1; }
				else if ( id == 0xEA4 ){ id = 0xEA3; }
				else if ( id == 0x121C ){ id = 0xEA5; }
				else if ( id == 0x1229 ){ id = 0xEA7; }
				else if ( id == 0x1236 ){ id = 0xEA8; }

				return id;
			}
        }
    }
}
