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

namespace Server.Mobiles 
{ 
    public class BaseHire : BaseCreature 
    { 
        private int m_Pay = 5; 
        private bool m_IsHired; 
        private int m_HoldGold = 0; 
        private Timer m_PayTimer; 
        
        public BaseHire( AIType   AI ): base( AI, FightMode.Aggressor, 10, 1, 0.01, 4.0 ) 
        { 
        } 

        public BaseHire(): base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.01, 4.0 ) 
        { 
        } 

        public BaseHire( Serial serial ) : base( serial ) 
        { 
        }
        
    		public override bool OnMoveOver( Mobile m )
    		{
    			return true;
    		}

        public override void Serialize( GenericWriter writer ) 
        { 
            base.Serialize( writer ); 

            writer.Write( (int) 0 ); // version 
          
            writer.Write( (bool)m_IsHired ); 
            writer.Write( (int)m_HoldGold ); 
        } 

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

            int version = reader.ReadInt(); 
          
            m_IsHired = reader.ReadBool(); 
            m_HoldGold = reader.ReadInt(); 
          
            m_PayTimer = new PayTimer( this ); 
            m_PayTimer.Start(); 
            
            if ( m_IsHired )
            {
               Mobile from = GetOwner();
               
               if ( from != null )
                  m_HireTable[from] = this;
            }
        } 

        private static Hashtable m_HireTable = new Hashtable(); 

        public static Hashtable HireTable 
        { 
            get{ return m_HireTable; } 
        } 

        public override bool KeepsItemsOnDeath{ get{ return true; } } 
        private int m_GoldOnDeath = 0;
        
        public override bool OnBeforeDeath() 
        { 
            // Stop the pay timer if its running 
            if( m_PayTimer != null ) 
                m_PayTimer.Stop(); 

            m_PayTimer = null; 

            // Get all of the gold on the hireling and add up the total amount 
            if( this.Backpack != null ) 
            { 
                Item[] AllGold = this.Backpack.FindItemsByType( typeof(Gold), true ); 
                if( AllGold != null ) 
                { 
                    foreach( Gold g in AllGold ) 
                        this.m_GoldOnDeath += g.Amount; 
                } 
            } 

            return base.OnBeforeDeath(); 

        } 

        public override void OnDeath( Container c ) 
        { 

            if( this.m_GoldOnDeath > 0 ) 
                c.DropItem( new Gold( this.m_GoldOnDeath ) ); 
            base.OnDeath( c ); 
        } 

        [CommandProperty( AccessLevel.Administrator )] 
        public bool IsHired 
        { 
            get 
            { 
                return m_IsHired; 
            } 
            set 
            { 
                if ( m_IsHired== value ) 
                    return; 

                m_IsHired= value; 
                Delta( MobileDelta.Noto ); 
                InvalidateProperties(); 
            } 
        } 
        
        [CommandProperty( AccessLevel.Administrator )] 
        public int HoldGold 
        { 
            get 
            { 
                return m_HoldGold; 
            } 
            set 
            { 
                if ( m_HoldGold== value ) 
                    return; 

                m_HoldGold= value; 
            } 
        }

        #region [ GetOwner ] 
        public virtual Mobile GetOwner() 
        { 
            if( !Controlled ) 
                return null; 
            Mobile Owner = ControlMaster; 
          
            m_IsHired = true; 
          
            if( Owner == null ) 
                return null; 
          
            if( Owner.Deleted/* || Owner.Map != this.Map || !Owner.InRange( Location, 50 )*/ ) 
            { 
                Say( 1005653 ); // Hmmm.  I seem to have lost my master. 
                BaseHire.HireTable.Remove( Owner ); 
                SetControlMaster( null ); 
                return null; 
            } 

            return Owner; 
        } 
        #endregion 

        #region [ AddHire ] 
        public virtual bool AddHire( Mobile m ) 
        { 
            Mobile owner = GetOwner(); 

            if( owner != null ) 
            { 
                m.SendLocalizedMessage( 1043283, owner.Name ); // I am following ~1_NAME~. 
                return false; 
            } 

            if( SetControlMaster( m ) ) 
            { 
                m_IsHired = true;
                if (this is Medic) IsBonded= true;
                return true; 
            } 
          
            return false; 
        } 
        #endregion 

        #region [ Payday ] 
        public virtual bool Payday( BaseHire m ) 
        { 
//             m_Pay = (int)m.Skills[SkillName.Anatomy].Value + (int)m.Skills[SkillName.Tactics].Value; 
//             m_Pay += (int)m.Skills[SkillName.Macing].Value + (int)m.Skills[SkillName.Swords].Value; 
//             m_Pay += (int)m.Skills[SkillName.Fencing].Value + (int)m.Skills[SkillName.Archery].Value; 
//             m_Pay += (int)m.Skills[SkillName.MagicResist].Value + (int)m.Skills[SkillName.Healing].Value; 
//             m_Pay += (int)m.Skills[SkillName.Magery].Value + (int)m.Skills[SkillName.Parry].Value;
// 		m_Pay /= 35; 
// 		m_Pay += 1;
		       m_Pay = 5;
            return true; 
        } 
        
        public int Pay 
        { 
            get 
            { 
                return m_Pay; 
            } 
            set 
            { 
                m_Pay = value; 
            } 
        }
        
        #endregion 

        #region [ OnDragDrop ] 
        public override bool OnDragDrop( Mobile from, Item item ) 
        { 
            if( m_Pay != 0 ) 
            { 
                // Is the creature already hired 
                if( Controlled == false ) 
                { 
                    // Is the item the payment in gold 
                    if( item is Gold ) 
                    { 
                        // Is the payment in gold sufficient 
                        if( item.Amount >= m_Pay ) 
                        { 
                            // Check if this mobile already has a hire 
                            BaseHire hire = (BaseHire)m_HireTable[from]; 

                            if( hire != null && !hire.Deleted && hire.GetOwner() == from ) 
                            { 
                                SayTo( from, 500896 ); // I see you already have an escort. 
                                return false; 
                            } 
                            
                            // omezeni na jak dlouho lze npc najmout
                            if( item.Amount > 600 ) 
                            { 
                                SayTo( from, "Muzes si me najmout maximalne na 2 hodiny. Vic nez 600 zlatych neprijmu." );
                                return false; 
                            } 

                            // Try to add the hireling as a follower 
                            if( AddHire(from) == true ) 
                            { 
                                SayTo( from, "Dekuji ze jsi si {0}. Budu pro tebe pracovat {1} minut", 
                                    (from.Female == true)? "vybrala me sluzby Pani":"vybral me sluzby Pane",
                                    string.Format( "{0}", (int)item.Amount / m_Pay ) );//"I thank thee for paying me. I will work for thee for ~1_NUMBER~ days.", (int)item.Amount / m_Pay ); 
                                m_HireTable[from] = this; 
                                m_HoldGold += item.Amount; 
                                m_PayTimer = new PayTimer( this ); 
                                m_PayTimer.Start(); 
                                return true; 
                            } 
                            else 
                                return false; 
                        } 
                        else 
                        { 
                            this.SayHireCost(); 
                        } 
                    } 
                    else 
                    { 
                        SayTo( from, 1043268 ); // Tis crass of me, but I want gold 
                    } 
                } 
                else 
                { 
                    Say( 1042495 );// I have already been hired. 
                } 
            } 
            else 
            { 
                SayTo( from, 500200 ); // I have no need for that. 
            } 

            return base.OnDragDrop( from, item ); 
        } 
        #endregion 


        #region [ OnSpeech ] 
        internal void SayHireCost() 
        { 
            Say( "Muzes si me najmout za {0} zlatych na minutu. Pokud mas zajem, dej mi penize a budu pro tebe pracovat.", m_Pay ); // "I am available for hire for ~1_AMOUNT~ gold coins a day. If thou dost give me gold, I will work for thee." 
        } 

        public override void OnSpeech( SpeechEventArgs e ) 
        {    
            if( !e.Handled && !this.Controlled && e.Mobile.InRange( this, 6 ) ) 
            { 
                int[] keywords = e.Keywords; 
                string speech = e.Speech; 

                // Check for a greeting or 'Hire' 
                if( ( e.HasKeyword( 0x003B ) == true ) || ( e.HasKeyword( 0x0162 ) == true ) ) 
                { 
                    e.Handled = Payday( this ); 
                    this.SayHireCost(); 
                } 
            } 

            base.OnSpeech( e ); 
        } 
        #endregion    
        
        #region [ GetContextMenuEntries ] 
	public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
	{
		if ( this.Deleted )
			return;

		if ( CanPaperdollBeOpenedBy( from ) )
			list.Add( new PaperdollEntry( this ) );

		if ( from == this && Backpack != null && CanSee( Backpack ) && CheckAlive( false ) )
			list.Add( new OpenBackpackEntry( this ) );
			
		if ( from.Alive && Controlled && from == ControlMaster )
		{
			list.Add( new ReleaseEntry( from, this ) );
			list.Add( new TimeEntry( from, this ) );
      }
			
		if ( from.Alive && !Controlled )
			list.Add( new HireEntry( from, this ) );
	}
        
		private class ReleaseEntry : ContextMenuEntry
		{
			private Mobile m_From;
			private BaseHire m_BaseHire;

			public ReleaseEntry( Mobile from, BaseHire basehire ) : base( 6118, 10 )
			{
				m_From = from;
				m_BaseHire = basehire;
			}

			public override void OnClick()
			{
				if ( !m_BaseHire.Deleted && m_BaseHire.Controlled && m_From == m_BaseHire.ControlMaster && m_From.CheckAlive() )
               m_From.SendGump( new Gumps.ConfirmReleaseGump( m_From, m_BaseHire ) );
			}
		}
        
        
        
        #endregion 
        
        #region [ Class PayTimer ] 
        private class PayTimer : Timer 
        { 
            private BaseHire m_Hire; 
          
            public PayTimer( BaseHire vend ) : base( TimeSpan.FromMinutes( 1.0 ), TimeSpan.FromMinutes( 1.0 ) ) 
            { 
                m_Hire = vend; 
                Priority = TimerPriority.OneMinute; 
            } 
          
            protected override void OnTick() 
            { 
                int m_Pay = m_Hire.m_Pay; 
                if( m_Hire.m_HoldGold <= m_Pay ) 
                { 
                    // Get the current owner, if any (updates HireTable) 
                    Mobile owner = m_Hire.GetOwner();
                    
                    if ( owner != null )
                     BaseHire.HireTable.Remove( owner );
                     
                    m_Hire.Say( "Je mi lito, ale musime se rozloucit." ); // I regret nothing!postal 
                    m_Hire.Delete(); 
                } 
                else 
                { 
                    m_Hire.m_HoldGold -= m_Pay;
                    int JesteMinut = m_Hire.m_HoldGold/m_Pay;
                    if (JesteMinut == 2)
                        m_Hire.Say( "Jiz zbyvaji pouze 2 minuty a budu muset odejit." );
                    if (JesteMinut == 5)
                        m_Hire.Say( "Za 5 minut te jiz budu muset opustit." );
                } 
            } 
        } 
        #endregion 

        #region [ Class HireEntry ] 
        private class HireEntry : ContextMenuEntry 
        { 
            private Mobile m_Mobile; 
            private BaseHire m_Hire; 

            public HireEntry( Mobile from, BaseHire hire ) : base( 6120, 3 )    
            { 
                m_Hire = hire; 
                m_Mobile = from; 
            } 
          
            public override void OnClick()    
            {    
                m_Hire.Payday(m_Hire); 
                m_Hire.SayHireCost(); 
            } 
        } 
        
		private class TimeEntry : ContextMenuEntry
		{
			private Mobile m_From;
			private BaseHire m_BaseHire;

			public TimeEntry( Mobile from, BaseHire basehire ) : base( 6121, 10 )
			{
				m_From = from;
				m_BaseHire = basehire;
			}

			public override void OnClick()
			{
				if ( !m_BaseHire.Deleted && m_BaseHire.Controlled && m_From == m_BaseHire.ControlMaster && m_From.CheckAlive() )
				{
               m_BaseHire.Say( "Jeste pro tebe budu pracovat {0} minut.", m_BaseHire.HoldGold / m_BaseHire.Pay );
            }
			}
		}
        #endregion 
    }    
} 
