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

namespace Server.Items
{
	public enum DecorateCommand
	{
		None,
		Turn,
		Up,
		Down,
// added by Greywolf
		North,
		East,
		South,
		West
// end added
	}

	public class InteriorDecorator : Item
	{
		private DecorateCommand m_Command;

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

		[Constructable]
		public InteriorDecorator() : base( 0xFC1 )
		{
			Weight = 1.0;
			LootType = LootType.Blessed;
		}

		public override int LabelNumber{ get{ return 1041280; } } // an interior decorator

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

		public override void GetProperties( ObjectPropertyList list )
		{
			base.GetProperties( list );
            if ( m_Command == DecorateCommand.North )
                list.Add( "North" );
            else if ( m_Command == DecorateCommand.East )
                list.Add( "East" );
            else if ( m_Command == DecorateCommand.South )
                list.Add( "South" );
            else if ( m_Command == DecorateCommand.West )
                list.Add( "West" );
            else if ( m_Command != DecorateCommand.None )
                list.Add( 1018322 + (int)m_Command ); // Turn/Up/Down
		}

		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 ( !CheckUse( this, from ) )
				return;

// 			if ( m_Command == DecorateCommand.None )
         m_Command = DecorateCommand.None;
         
			if( from.HasGump( typeof(InternalGump) ) )
				from.CloseGump( typeof(InternalGump) );
            
				from.SendGump( new InternalGump( this ) );
// 			else
// 				from.Target = new InternalTarget( this );
		}

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

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

		public static bool CheckUse( InteriorDecorator tool, Mobile from )
		{
			/*if ( tool.Deleted || !tool.IsChildOf( from.Backpack ) )
				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
			else*/
			if ( !InHouse( from ) )
				from.SendLocalizedMessage( 502092 ); // You must be in your house to do this.
			else
				return true;

			return false;
		}

		private class InternalGump : Gump
		{
			private InteriorDecorator m_Decorator;

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

            this.Closable=true;
            this.Disposable=true;
            this.Dragable=true;
            this.Resizable=false;
            this.AddPage(0);
            this.AddImageTiled(14, 14, 172, 256, 2624);
            this.AddAlphaRegion(14, 14, 172, 256);
            this.AddImage(0, 0, 9007);
            this.AddButton(109, 43, 4501, 4501, 4, GumpButtonType.Reply, 0);
            this.AddTooltip( 1075389 ); // north
            this.AddButton(108, 110, 4503, 4503, 5, GumpButtonType.Reply, 0);
            this.AddTooltip( 1075387 ); // east
            this.AddButton(40, 109, 4505, 4505, 6, GumpButtonType.Reply, 0);
            this.AddTooltip( 1075386 ); // south
            this.AddButton(42, 42, 4507, 4507, 7, GumpButtonType.Reply, 0);
            this.AddTooltip( 1075390 ); // west
            this.AddButton(90, 53, 9900, 9902, 2, GumpButtonType.Reply, 0);
            this.AddTooltip( 1018324 ); // Up
            this.AddButton(90, 127, 9906, 9908, 3, GumpButtonType.Reply, 0);
            this.AddTooltip( 1018325 ); // Down
            this.AddButton(86, 86, 2151, 2153, 1, GumpButtonType.Reply, 0);
            this.AddTooltip( 1018323 ); // Turn
            this.AddLabel(40, 188, 1152, @"I wish to secure this");
            this.AddButton(15, 190, 5601, 5605, 10, GumpButtonType.Reply, 0);
            this.AddLabel(40, 208, 1152, @"I wish to lock this down");
            this.AddButton(15, 210, 5601, 5605, 11, GumpButtonType.Reply, 0);
            this.AddLabel(40, 228, 1152, @"I wish to release this");
            this.AddButton(15, 230, 5601, 5605, 12, GumpButtonType.Reply, 0);
            this.AddLabel(40, 248, 1152, @"Place trash barrel");
            this.AddButton(15, 250, 5601, 5605, 13, GumpButtonType.Reply, 0);
			}

         public override void OnResponse( NetState sender, RelayInfo info )
			{
				DecorateCommand command = DecorateCommand.None;
				Mobile from = sender.Mobile;
			   BaseHouse m_House = BaseHouse.FindHouseAt( from );
			   
				switch ( info.ButtonID )
				{
					case 1: command = DecorateCommand.Turn; break;
					case 2: command = DecorateCommand.Up; break;
					case 3: command = DecorateCommand.Down; break;
// added by Greywolf
					case 4: command = DecorateCommand.North; break;
					case 5: command = DecorateCommand.East; break;
					case 6: command = DecorateCommand.South; break;
					case 7: command = DecorateCommand.West; break;
//end added by Greywolf
				}

				if ( command != DecorateCommand.None && info.ButtonID < 10 )
				{
					m_Decorator.Command = command;
					from.Target = new InternalTarget( m_Decorator );
					
			      if( from.HasGump( typeof(InternalGump) ) )
				     from.CloseGump( typeof(InternalGump) );
					from.SendGump( new InternalGump( m_Decorator ) );
				}
				
            if ( info.ButtonID > 9 && m_House != null)
				{
               
               bool isOwner = m_House.IsOwner( from );
			      bool isCoOwner = isOwner || m_House.IsCoOwner( from );
			      bool isFriend = isCoOwner || m_House.IsFriend( from );
               
               if ( info.ButtonID == 11 ) // I wish to lock this down
      			{
      				if ( isCoOwner )
      				{
      					from.SendLocalizedMessage( 502097 ); // Lock what down?
      					from.Target = new LockdownTarget( false, m_House );
      				}
      				else if ( isFriend )
      				{
      					from.SendLocalizedMessage( 1010587 ); // You are not a co-owner of this house.
      				}
      				else
      				{
      					from.SendLocalizedMessage( 502094 ); // You must be in your house to do this.
      				}
      			}
      			else if ( info.ButtonID == 12 ) // I wish to release this
      			{
      				if ( isCoOwner )
      				{
      					from.SendLocalizedMessage( 502100 ); // Choose the item you wish to release
      					from.Target = new LockdownTarget( true, m_House );
      				}
      				else if ( isFriend )
      				{
      					from.SendLocalizedMessage( 1010587 ); // You are not a co-owner of this house.
      				}
      				else
      				{
      					from.SendLocalizedMessage( 502094 ); // You must be in your house to do this.
      				}
      			}
      			else if ( info.ButtonID == 10 ) // I wish to secure this
      			{
      				if ( isOwner )
      				{
      					from.SendLocalizedMessage( 502103 ); // Choose the item you wish to secure
      					from.Target = new  SecureTarget( false, m_House );
      				}
      				else
      				{
      					from.SendLocalizedMessage( 502094 ); // You must be in your house to do this.
      				}
      			}
			      else if ( info.ButtonID == 13 ) //Place trash barrel
      			{
      				if ( isCoOwner )
      				{
      					m_House.AddTrashBarrel( from );
      				}
      				else if ( isFriend )
      				{
      					from.SendLocalizedMessage( 1010587 ); // You are not a co-owner of this house.
      				}
      				else
      				{
      					from.SendLocalizedMessage( 502094 ); // You must be in your house to do this.
      				}
      			}
			      
               if( from.HasGump( typeof(InternalGump) ) )
				     from.CloseGump( typeof(InternalGump) );
				     
      			from.SendGump( new InternalGump( m_Decorator ) );
      		}
			}
		}

		private class InternalTarget : Target
		{
			private 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 == m_Decorator )
				{
					m_Decorator.Command = DecorateCommand.None;
					from.SendGump( new InternalGump( m_Decorator ) );
				}
				else if ( targeted is Item && InteriorDecorator.CheckUse( m_Decorator, from ) )
				{
					BaseHouse house = BaseHouse.FindHouseAt( from );
					Item item = (Item)targeted;

//YARD ITEM
					if ( item is YardItem || item is YardTreeMulti || item is YardFountain
						|| item is YardIronGate || item is YardShortIronGate
						|| item is YardLightWoodGate || item is YardDarkWoodGate || item is BaseDecoSign
						|| item is YardStair || targeted is BaseAddon || targeted is AddonComponent )
					{
						switch ( m_Decorator.Command )
						{
							case DecorateCommand.Up:	Up( item, from );	break;
							case DecorateCommand.Down:	Down( item, from );	break;
							case DecorateCommand.Turn:	Turn( item, from );	break;
// added by Greywolf
							case DecorateCommand.North: checkit( item, from, 1, true, house );	break;
							case DecorateCommand.East:	checkit( item, from, 2, true, house );	break;
							case DecorateCommand.South:	checkit( item, from, 3, true, house );	break;
							case DecorateCommand.West:	checkit( item, from, 4, true, house );	break;
// end added by Greywolf

						}
					}
//YARD ITEM
					else if ( house == null || !house.IsCoOwner( from ) )
					{
						from.SendLocalizedMessage( 502092 ); // You must be in your house to do this.
					}
					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 ) )
					{
						from.SendLocalizedMessage( 1042271 ); // That is not locked down.
					}
					else if ( item is VendorRentalContract )
					{
						from.SendLocalizedMessage( 1062491 ); // You cannot use the house decorator on that object.
					}
					else if ( item.TotalWeight + item.PileWeight > 1000 )
					{
						from.SendLocalizedMessage( 1042272 ); // That is too heavy.
					}
					else
					{
						switch ( m_Decorator.Command )
						{
							case DecorateCommand.Up:	Up( item, from );	break;
							case DecorateCommand.Down:	Down( item, from );	break;
							case DecorateCommand.Turn:	Turn( item, from );	break;
// added by Greywolf
							case DecorateCommand.North: checkit( item, from, 1, false, house );	break;
							case DecorateCommand.East:	checkit( item, from, 2, false, house );	break;
							case DecorateCommand.South:	checkit( item, from, 3, false, house );	break;
							case DecorateCommand.West:	checkit( item, from, 4, false, house );	break;
// end added by Greywolf
						}
					}
				}
				m_Decorator.Command = DecorateCommand.None;
			}
			
			private void checkit( Item item, Mobile from, int dir, bool yarditem, BaseHouse house )
			{
			   Point3D p = item.GetWorldLocation();
			   
				switch ( dir )
				{
					case 1:	p.Y -= 1;	break; //North
					case 2:	p.X += 1;	break; //East
					case 3:	p.Y += 1;	break; //South
					case 4:	p.X -= 1;	break; //West
				}

            if ( ( yarditem && !from.InRange( p, 10 ) ) || ( !yarditem && !house.IsInside( p, item.ItemData.Height ) ) )
				  from.SendMessage( "Predmet jiz nelze vice posunout." );
			   else
			      item.Location = p;
			}

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

				if( attributes.Length > 0 && item.Name != "klic k auberonovu doupeti" )
					attributes[0].Flip( item );
				else
					from.SendLocalizedMessage( 1042273 ); // You cannot turn that.
			}

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

//YARD ITEM
				if( item is YardItem || item is YardTreeMulti || item is YardFountain
						|| item is YardIronGate || item is YardShortIronGate
						|| item is YardLightWoodGate || item is YardDarkWoodGate || item is BaseDecoSign
						|| item is YardStair || item is BaseAddon || item is AddonComponent )
					item.Location = new Point3D( item.Location, item.Z + 1 );
//YARD ITEM
				else if ( floorZ > int.MinValue && item.Z < (floorZ + 15) ) // 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 );
//YARD ITEM
				if( item is YardItem || item is YardTreeMulti || item is YardFountain
						|| item is YardIronGate || item is YardShortIronGate
						|| item is YardLightWoodGate || item is YardDarkWoodGate || item is BaseDecoSign
						|| item is YardStair || item is BaseAddon || item is AddonComponent )
					item.Location = new Point3D( item.Location, item.Z - 1 );
//YARD ITEM
				else 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 int GetFloorZ( Item item )
			{
				Map map = item.Map;

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

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

				int z = int.MinValue;

				for ( int i = 0; i < tiles.Length; ++i )
				{
					Tile 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;
			}
		}
	}
}