using System;
using System.Threading;
using System.Windows.Forms;

namespace CNAS_DBSync
{
    public partial class frmPrBar : Form
    {
        /// <summary>
        /// 显示百分比(例:30%)或完成数(例:138/2000)
        /// </summary>
        private static bool _ShowPercentage;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="title">窗体标题</param>
        /// <param name="customText">滚动条上方显示的文字提示</param>
        /// <param name="taskCount">总任务数</param>
        /// <param name="showPercentage">显示百分比(例:30%)或完成数(例:138/2000)</param>
        /// <param name="showClose">是否显示关闭按钮</param>
        /// <param name="showCustomButton">是否显示开始/暂停/继续/停止按钮</param>
        public frmPrBar(string title, string customText, int taskCount, bool showPercentage, bool showClose, bool showCustomButton)
        {
            InitializeComponent();
            this.Text = title;
            SetText(customText);
            //pictureBoxCancel.Visible = showCustomClose;
            _ShowPercentage = showPercentage;
            this.ControlBox = showClose;
            btnStart.Visible = showCustomButton;
            btnPause.Visible = showCustomButton;
            btnGoon.Visible = showCustomButton;
            btnStop.Visible = showCustomButton;
            ProgressBarService.Status = ProgressBarRunStatus.None;

            this.progressBar1.Maximum = taskCount;
            this.progressBar1.Value = 0;
        }

        protected override void WndProc(ref Message m)
        {
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_CLOSE = 0xF060;
            if (m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)
            {
                //Application.ExitThread();
                //ProgressBarService.CloseBarForm();
                ProgressBarService.Status = ProgressBarRunStatus.Close;
                return;
            }
            base.WndProc(ref m);
        }

        /// <summary>
        /// 委托修改等待窗显示的文字
        /// </summary>
        /// <param name="text"></param>
        private delegate void SetTextHandler(string text);

        public void SetText(string text)
        {
            if (lblMsg.InvokeRequired)
                this.Invoke(new SetTextHandler(SetText), text);
            else
            {
                if (text.ToUpper() == "CLOSE")
                {
                    this.Close();
                    this.Dispose();
                }
                else
                    lblMsg.Text = text;
            }
        }

        private delegate void UpdateUI(int step);

        /// <summary>
        /// 更新UI
        /// </summary>
        /// <param name="step"></param>
        public void UpdataUIStatus(int step)
        {
            try
            {
                if (this.IsDisposed || !this.IsHandleCreated)
                    return;
                if (InvokeRequired)
                {
                    this.Invoke(new UpdateUI(delegate (int s)
                    {
                        this.progressBar1.Value = s;
                        //this.progressBar1.Value += s;
                        if (_ShowPercentage)
                            this.lblCount.Text = (this.progressBar1.Value * 100 / this.progressBar1.Maximum).ToString() + "%";
                        else
                            this.lblCount.Text = this.progressBar1.Value.ToString() + "/" + this.progressBar1.Maximum.ToString();
                        if (this.progressBar1.Value == this.progressBar1.Maximum)
                            this.Close();
                    }), step);
                }
                else
                {
                    if (this.progressBar1.Value >= this.progressBar1.Maximum)
                        this.progressBar1.Value = 0;
                    this.progressBar1.Value = step;
                    //this.progressBar1.Value += step;
                    if (_ShowPercentage)
                        this.lblCount.Text = (this.progressBar1.Value * 100 / this.progressBar1.Maximum).ToString() + "%";
                    else
                        this.lblCount.Text = this.progressBar1.Value.ToString() + "/" + this.progressBar1.Maximum.ToString();
                }
            }
            catch (Exception ex) { }
        }

        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            ProgressBarService.Status = ProgressBarRunStatus.Start;
            btnStart.Enabled = false;
            btnPause.Enabled = true;
            btnGoon.Enabled = true;
            btnStop.Enabled = true;
            this.ControlBox = false;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPause_Click(object sender, EventArgs e)
        {
            //ProgressBarService.PauseProgress();
            ProgressBarService.Status = ProgressBarRunStatus.Pause;
            btnStart.Enabled = false;
            btnPause.Enabled = false;
            btnGoon.Enabled = true;
            btnStop.Enabled = true;
            this.ControlBox = false;
        }

        /// <summary>
        /// 继续
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGoon_Click(object sender, EventArgs e)
        {
            ProgressBarService.Status = ProgressBarRunStatus.GoOn;
            btnStart.Enabled = false;
            btnPause.Enabled = true;
            btnGoon.Enabled = false;
            btnStop.Enabled = true;
            this.ControlBox = false;
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            ProgressBarService.Status = ProgressBarRunStatus.Stop;
            btnStart.Enabled = true;
            btnPause.Enabled = false;
            btnGoon.Enabled = false;
            btnStop.Enabled = false;
            this.ControlBox = true;
        }
    }

    public class ProgressBarService
    {
        private Thread thred = null;
        private frmPrBar bar = null;

        public ProgressBarService() { }

        private static ProgressBarService _instance;
        private static readonly Object syncLock = new Object();
        public static ProgressBarService Instance
        {
            get
            {
                if (ProgressBarService._instance == null)
                {
                    lock (syncLock)
                    {
                        if (ProgressBarService._instance == null)
                        {
                            ProgressBarService._instance = new ProgressBarService();
                        }
                    }
                }
                return ProgressBarService._instance;
            }
        }

        #region 创建等待窗口
        /// <summary>
        /// 创建等待窗口并写入提示文字
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="str">提示文字</param>
        /// <param name="Count">步长</param>
        /// <param name="showPercentage">显示百分比(例:30%)或完成数(例:138/2000).默认false显示完成数</param>
        /// <param name="showClose">是否显示关闭窗口按钮(true显示;false隐藏)，不传值默认fasle</param>
        /// <param name="showCustomButton">是否显示开始/暂停/继续/停止按钮(true显示;false隐藏)，不传值默认fasle</param>
        public static void CreateBarForm(string title, string text, int Count, bool showPercentage = false, bool showClose = false, bool showCustomButton = false)
        {
            ProgressBarService.Instance.CreateForm(title, text, Count, showPercentage, showClose, showCustomButton);
        }

        int tid1 = 0;
        private void CreateForm(string title, string text, int Count, bool showPercentage, bool showClose, bool showCustomButton)
        {
            int tid2 = Thread.CurrentThread.ManagedThreadId;
            if (tid1 == tid2)
                return;
            tid1 = tid2;
            if (thred != null)
            {
                try
                {
                    thred = null;
                    bar = null;
                }
                catch (Exception)
                {
                }
            }

            thred = new Thread(new ThreadStart(delegate ()
            {
                bar = new frmPrBar(title, text, Count, showPercentage, showClose, showCustomButton);
                System.Windows.Forms.Application.Run(bar);
            }));
            thred.Start();

        }
        #endregion

        #region 关闭等待窗口
        /// <summary>
        /// 关闭窗口
        /// </summary>
        public static void CloseBarForm()
        {
            ProgressBarService.Instance.CloseForm();
        }

        private void CloseForm()
        {
            tid1 = 0;
            if (thred != null)
            {
                try
                {
                    bar.SetText("CLOSE");
                    thred = null;
                    bar = null;
                }
                catch (Exception) { }
            }
        }
        #endregion

        #region 修改等待窗体的提示文字
        /// <summary>
        /// 修改提示文字
        /// </summary>
        /// <param name="text">提示文字</param>
        public static void SetBarFormCaption(string text)
        {
            ProgressBarService.Instance.SetFormCaption(text);
        }

        private void SetFormCaption(string text)
        {
            if (bar != null)
            {
                try
                {
                    bar.SetText(text);
                }
                catch (Exception) { }
            }
        }
        #endregion

        #region 更新进度条
        /// <summary>
        /// 更新进度
        /// </summary>
        /// <param name="step"></param>
        public static void UpdateProgress(int step)
        {
            ProgressBarService.Instance.SetProgress(step);
        }

        private void SetProgress(int step)
        {
            if (bar != null)
            {
                try
                {
                    bar.UpdataUIStatus(step);
                }
                catch (Exception) { }
            }
        }
        #endregion

        #region 进度条运行状态
        public static ProgressBarRunStatus Status { get; set; }
        #endregion
    }

    public enum ProgressBarRunStatus
    {
        /// <summary>
        /// 无操作
        /// </summary>
        None,
        /// <summary>
        /// 开始
        /// </summary>
        Start,
        /// <summary>
        /// 暂停
        /// </summary>
        Pause,
        /// <summary>
        /// 继续
        /// </summary>
        GoOn,
        /// <summary>
        /// 停止
        /// </summary>
        Stop,
        /// <summary>
        /// 关闭
        /// </summary>
        Close
    }
}
