﻿namespace CookieHell
{
    using System.Diagnostics;

    public abstract class Person
    {
        /// <summary>
        /// Gets the Id number of this Person
        /// </summary>
        protected readonly int Id;

        /// <summary>
        /// Initializes a new instance of the <see cref="Person"/> class. 
        /// </summary>
        /// <param name="name">
        /// This person's name
        /// </param>
        /// <param name="id">
        /// This person's Id number
        /// </param>
        protected Person(string name, int id)
        {
            Name = name;
            Id = id;
            RegisterWithAuthories();
        }

        /// <summary>
        /// Gets the acting rate of the individual.
        /// </summary>
        public abstract int ActingRate
        {
            get;
            internal set;
        }
        
        /// <summary>
        /// Gets or sets the name of the Person
        /// </summary>
        public string Name
        {
            get;
            set; 
        }

        /// <summary>
        /// Gets or sets the location of this Person
        /// </summary>
        public virtual ILocation CurrentLocation
        {
            get;
            set;
        }

        /// <summary>
        /// The threadable method for the Person. Only allows acting inside Police Station if this is a Police Officer
        /// </summary>
        public virtual void Run()
        {
            var timer = new Stopwatch();
            timer.Start();
            while (Application.Running)
            {
                if (timer.ElapsedMilliseconds < ActingRate)
                {
                    continue;
                }

                timer.Restart();
                if (CurrentLocation == PoliceStation.Instance)
                {
                    if (!(this is PoliceOfficer))
                    {
                        continue;
                    }
                }

                Act();
            }
        }

        /// <summary>
        /// Reports a heinous individual for eating a cookie this Patron ate.
        /// </summary>
        /// <param name="person">The cookie stealing individual to report</param>
        public void CallEmergencyPhone(Person person)
        {
            PoliceStation.Instance.SuspectList.Enqueue(person);
            ConsoleWriter.Instance().AddMessageToQueue(Name + " called emergency services on " + person.Name + " for stealing their cookie");
        }

        /// <summary>
        /// How the individual is supposed to act.
        /// </summary>
        public abstract void Act();

        /// <summary>
        /// Registers with the Application authorities to assist with threading this person.
        /// </summary>
        private void RegisterWithAuthories()
        {
            Application.Register(this);
        }
    }
}
