using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Ionic.Zip;

namespace winform1
{
    public partial class Form1 : Form
    {
        private Point m_mousePos;
        private bool m_isMouseDown;
        //要下载的文件的url
        private const string m_url = "https://codechina.csdn.net/linxinfa/winform-download-demo/-/raw/master/winform1/res/guitar.zip";
        //下载到本地的文件名
        private const string m_saveFile = "./download.zip";
        //加压目录
        private const string m_unzipFile = "./unzip";


        public Form1()
        {
            InitializeComponent();

            InitUi();

            StartDownload();
        }

        private void InitUi()
        {
            //隐藏标题栏
            this.FormBorderStyle = FormBorderStyle.None;

            //背景图
            pictureBg.SizeMode = PictureBoxSizeMode.StretchImage;
            //窗口移动控制
            pictureBg.MouseDown += OnMouseDown;
            pictureBg.MouseUp += OnMouseUp;
            pictureBg.MouseMove += OnMouseMove;
            progressBar.MouseDown += OnMouseDown;
            progressBar.MouseUp += OnMouseUp;
            progressBar.MouseMove += OnMouseMove;
            //提示语
            tipsLbl.Parent = pictureBg;
            processLbl.Parent = pictureBg;
            processLbl.Text = "0%";

            //进度条
            progressBar.Minimum = 0;
            progressBar.Maximum = 100;
        }

        #region 隐藏标题栏后支持移动窗口
        /// <summary>
        /// 鼠标按下，开启移动
        /// </summary>
        /// <param name="e"></param>
        protected void OnMouseDown(object sender, MouseEventArgs e)
        {
            m_mousePos = Cursor.Position;
            m_isMouseDown = true;
        }

        /// <summary>
        /// 鼠标抬起，关闭移动
        /// </summary>
        /// <param name="e"></param>
        protected void OnMouseUp(object sender, MouseEventArgs e)
        {
            m_isMouseDown = false;
            this.Focus();
        }

        /// <summary>
        /// 移动窗口
        /// </summary>
        /// <param name="e"></param>
        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (m_isMouseDown)
            {
                Point tempPos = Cursor.Position;
                this.Location = new Point(Location.X + (tempPos.X - m_mousePos.X), Location.Y + (tempPos.Y - m_mousePos.Y));
                m_mousePos = Cursor.Position;
            }
        }
        #endregion

        #region 更新进度条
        /// <summary>
        /// 被委托调用,专门设置进度条最大值
        /// </summary>
        /// <param name="maxValue"></param>
        public void SetMax(int maxValue)
        {
            progressBar.Maximum = maxValue;
        }

        /// <summary>
        /// 被委托调用,专门设置进度条当前值
        /// </summary>
        /// <param name="nowValue"></param>
        private void SetNow(int nowValue)
        {
            progressBar.Value = nowValue;
            string nowValueStr = string.Format("{0:F}", (float)nowValue / this.progressBar.Maximum * 100);
            processLbl.Text = nowValueStr + "%";
        }
        #endregion

        private void StartDownload()
        {
            DownloadThread method = new DownloadThread();
            //先订阅一下事件
            method.threadStartEvent += new EventHandler(DownloadThreadStartEvent);
            method.threadEvent += new EventHandler(DownloadThreadIngEvent);
            method.threadEndEvent += new EventHandler(DownloadThreadEndEvent);

            //开启一个线程进行下载
            Task task = new Task(() => { method.RunMethod(m_url, m_saveFile); });
            task.Start();
        }

        private void UnZipFile(string file)
        {
            using (ZipFile zip = new ZipFile(file))
            {
                zip.ExtractAll(m_unzipFile);
            }
        }

        /// <summary>
        /// 线程开始事件,设置进度条最大值
        /// 但是我不能直接操作进度条,需要一个委托来替我完成
        /// </summary>
        /// <param name="sender">ThreadMethod函数中传过来的最大值</param>
        /// <param name="e"></param>
        void DownloadThreadStartEvent(object sender, EventArgs e)
        {
            int maxValue = Convert.ToInt32(sender);
            Invoke(new Action<int>(SetMax), maxValue);
        }

        /// <summary>
        /// 线程执行中的事件,设置进度条当前进度
        /// 但是我不能直接操作进度条,需要一个委托来替我完成
        /// </summary>
        /// <param name="sender">ThreadMethod函数中传过来的当前值</param>
        /// <param name="e"></param>
        void DownloadThreadIngEvent(object sender, EventArgs e)
        {
            int nowValue = Convert.ToInt32(sender);
            Invoke(new Action<int>(SetNow), nowValue);
        }

        /// <summary>
        /// 线程完成事件
        /// </summary>
        void DownloadThreadEndEvent(object sender, EventArgs e)
        {
            MessageBox.Show("下载完成完成，点击确定执行解压");
            UnZipFile(m_saveFile);
        }
    }
}
