using System;
using System.Threading;

namespace ZionFoundation.Threading
{
    public class Thread : IDisposable
    {
        public bool isAsync=true;

        public delegate void dgEventRaiser();
        #region Private constants
        protected int interval = 2000;
        #endregion
        #region Private properties
        private System.Threading.Thread main;
        private bool terminate;

        public Thread()
        {
            OnChanged += Thread_OnChanged;
        }

        private void Thread_OnChanged()
        {
        }
        #endregion
        #region Public properties
        public event dgEventRaiser OnChanged;
        public bool Terminate { get => terminate; set => terminate = value; }
        public bool isRunning { get => main.IsAlive; }
        #endregion
        #region Interface implementations
        public void Dispose()
        {
            if (main.IsAlive)
            {
                main.Abort();
            }
        }
        #endregion
        #region Private functions
        private void PerformLoop()
        {
            while (!terminate)
            {
                Execute();
                System.Threading.Thread.Sleep(interval);
            }
        }
        #endregion
        #region Virtual functions
        public virtual void Execute() { }
        #endregion
        #region Public functions
        public void Initilize(bool execute = true)
        {
            if (main is null)
            {
                main = new System.Threading.Thread(() =>
                {
                    System.Threading.Thread.CurrentThread.IsBackground = isAsync;
                    PerformLoop();
                });
            }
            if (execute)
            {
                Start();
            }
        }
        public void Start()
        {
            if (!main.IsAlive)
            {
                terminate = false;

                if (main.ThreadState == System.Threading.ThreadState.Unstarted)
                {
                    main.Start();
                    return;
                }

                main = null;
                Initilize();
            }
        }

        public void Stop()
        {
            terminate = true;
        }
        #endregion
    }
}
