using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;

namespace HttpFtpDemoNet
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox textBoxUrl;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox textBoxSavePath;
        private System.Windows.Forms.TextBox textBoxFileName;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnStop;
        private System.Windows.Forms.Button btnSetting;
        private System.Windows.Forms.TextBox textBoxInfo;
        private System.Windows.Forms.TextBox textBoxMirrorUrl;
        private System.Windows.Forms.TextBox textBoxDetail;
        private System.ComponentModel.IContainer components;
        private System.Windows.Forms.Timer timerRefresh;

        public int m_downloaderID = 0;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//

            //  Start HttpFtp kernel
            if (!HttpFtp.HttpFtp_Startup ())
            {
                MessageBox.Show("Start HttpFtp failed, check!");
                return;
            }

            // Setting callback function of detailed log
            HttpFtp.HttpFtp_RECEIVELOG_CALLBACK callback = new HttpFtp.HttpFtp_RECEIVELOG_CALLBACK (this.OnReceiveDetailLog);
            HttpFtp.HttpFtp_SetReceiveLogFunc (callback, (IntPtr)0);

            timerRefresh.Enabled = true;
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            this.label1 = new System.Windows.Forms.Label();
            this.textBoxUrl = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.textBoxSavePath = new System.Windows.Forms.TextBox();
            this.textBoxFileName = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.textBoxMirrorUrl = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.btnStart = new System.Windows.Forms.Button();
            this.btnStop = new System.Windows.Forms.Button();
            this.btnSetting = new System.Windows.Forms.Button();
            this.textBoxInfo = new System.Windows.Forms.TextBox();
            this.textBoxDetail = new System.Windows.Forms.TextBox();
            this.timerRefresh = new System.Windows.Forms.Timer(this.components);
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(56, 32);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(88, 16);
            this.label1.TabIndex = 0;
            this.label1.Text = "file URL:";
            // 
            // textBoxUrl
            // 
            this.textBoxUrl.Location = new System.Drawing.Point(160, 24);
            this.textBoxUrl.Name = "textBoxUrl";
            this.textBoxUrl.Size = new System.Drawing.Size(400, 21);
            this.textBoxUrl.TabIndex = 1;
            this.textBoxUrl.Text = "http://download.microsoft.com/download/8/b/8/8b8ea37d-44b2-469f-bda7-610fd173cb25" +
                "/dxsdk_oct2006.exe";
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(56, 72);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(88, 16);
            this.label2.TabIndex = 0;
            this.label2.Text = "save path:";
            // 
            // textBoxSavePath
            // 
            this.textBoxSavePath.Location = new System.Drawing.Point(160, 64);
            this.textBoxSavePath.Name = "textBoxSavePath";
            this.textBoxSavePath.Size = new System.Drawing.Size(400, 21);
            this.textBoxSavePath.TabIndex = 1;
            this.textBoxSavePath.Text = "D:\\HttpTest";
            // 
            // textBoxFileName
            // 
            this.textBoxFileName.Location = new System.Drawing.Point(160, 104);
            this.textBoxFileName.Name = "textBoxFileName";
            this.textBoxFileName.Size = new System.Drawing.Size(400, 21);
            this.textBoxFileName.TabIndex = 1;
            this.textBoxFileName.Text = "";
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(56, 112);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(88, 16);
            this.label3.TabIndex = 0;
            this.label3.Text = "file name";
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(56, 152);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(88, 16);
            this.label4.TabIndex = 0;
            this.label4.Text = "mirror URL:";
            // 
            // textBoxMirrorUrl
            // 
            this.textBoxMirrorUrl.Location = new System.Drawing.Point(160, 144);
            this.textBoxMirrorUrl.Name = "textBoxMirrorUrl";
            this.textBoxMirrorUrl.Size = new System.Drawing.Size(400, 21);
            this.textBoxMirrorUrl.TabIndex = 1;
            this.textBoxMirrorUrl.Text = "";
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(160, 176);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(392, 16);
            this.label5.TabIndex = 0;
            this.label5.Text = "options:can download one file from several server";
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(80, 216);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(88, 24);
            this.btnStart.TabIndex = 2;
            this.btnStart.Text = "intialiezed";
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // btnStop
            // 
            this.btnStop.Location = new System.Drawing.Point(216, 216);
            this.btnStop.Name = "btnStop";
            this.btnStop.Size = new System.Drawing.Size(88, 24);
            this.btnStop.TabIndex = 2;
            this.btnStop.Text = "stopped";
            this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
            // 
            // btnSetting
            // 
            this.btnSetting.Location = new System.Drawing.Point(368, 216);
            this.btnSetting.Name = "btnSetting";
            this.btnSetting.Size = new System.Drawing.Size(88, 24);
            this.btnSetting.TabIndex = 2;
            this.btnSetting.Text = "setting";
            this.btnSetting.Click += new System.EventHandler(this.btnSetting_Click);
            // 
            // textBoxInfo
            // 
            this.textBoxInfo.Location = new System.Drawing.Point(40, 264);
            this.textBoxInfo.Multiline = true;
            this.textBoxInfo.Name = "textBoxInfo";
            this.textBoxInfo.Size = new System.Drawing.Size(568, 72);
            this.textBoxInfo.TabIndex = 3;
            this.textBoxInfo.Text = "download information:";
            // 
            // textBoxDetail
            // 
            this.textBoxDetail.Location = new System.Drawing.Point(40, 360);
            this.textBoxDetail.Multiline = true;
            this.textBoxDetail.Name = "textBoxDetail";
            this.textBoxDetail.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBoxDetail.Size = new System.Drawing.Size(568, 200);
            this.textBoxDetail.TabIndex = 3;
            this.textBoxDetail.Text = "download information:";
            // 
            // timerRefresh
            // 
            this.timerRefresh.Tick += new System.EventHandler(this.timerRefresh_Tick);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(640, 590);
            this.Controls.Add(this.textBoxInfo);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.textBoxUrl);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.textBoxSavePath);
            this.Controls.Add(this.textBoxFileName);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.textBoxMirrorUrl);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.btnStop);
            this.Controls.Add(this.btnSetting);
            this.Controls.Add(this.textBoxDetail);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Closed += new System.EventHandler(this.Form1_Closed);
            this.ResumeLayout(false);

        }
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

        private void btnStart_Click(object sender, System.EventArgs e)
        {
            if (textBoxUrl.Text.Trim().Length <= 0 || textBoxSavePath.Text.Trim().Length <= 0)
            {
                MessageBox.Show("please input right content");
                return;
            }

            string url = textBoxUrl.Text.Trim();
            string saveFolder = textBoxSavePath.Text.Trim();
            saveFolder = saveFolder.Replace("/", "\\");
            saveFolder = saveFolder.TrimEnd('\\');
            saveFolder = saveFolder + "\\";

            string statusFile = saveFolder + url.GetHashCode().ToString() + ".resume";

            HttpFtp.HttpFtpDownloaderAdditionalParams additionParam = new HttpFtp.HttpFtpDownloaderAdditionalParams();
            additionParam.Init();
            additionParam.statusFile = statusFile;
            additionParam.referer = "";

            // Download in broken-point connection instability mode for uncompleted download
            if (System.IO.File.Exists(additionParam.statusFile))
            {
                int ret = HttpFtp.HttpFtp_Downloader_Load (ref m_downloaderID, additionParam.statusFile);
                if (ret != 0)   //S_OK:succeed
                {
                    MessageBox.Show("Start failed");
                    return;
                }
            }
            else
            {
                // New download task
                HttpFtp.HttpFtpDownloaderParams httpFtpParam = new HttpFtp.HttpFtpDownloaderParams();
		        httpFtpParam.Init();

                httpFtpParam.url = url;        
                httpFtpParam.saveFolder = saveFolder;
                httpFtpParam.fileName = textBoxFileName.Text.Trim();
                httpFtpParam.bAutoName = true;   //Whether named files By HttpFtp kernel, if it is, then alternative offer is filename

                int ret = HttpFtp.HttpFtp_Downloader_Initialize (httpFtpParam, ref m_downloaderID, ref additionParam);
                if (ret != 0)   //S_OK:succeed
                {
                    MessageBox.Show("Start fialed");
                    return;
                }

                if (textBoxMirrorUrl.Text.Trim().Length > 1)
                    HttpFtp.HttpFtp_Downloader_AddMirrorUrl(m_downloaderID, textBoxMirrorUrl.Text.Trim());
            }

            btnStop.Enabled = true;
            btnStart.Enabled = false;
        }

        public void OnReceiveDetailLog (int downloaderID, string strLog, IntPtr lpParam)
        {
            Debug.Assert (downloaderID >= 1000);

            string str = textBoxDetail.Text;

            str += DateTime.Now.ToString();
            str += strLog;
            str += "\r\n";

            textBoxDetail.Text = str;
        }

        private void btnStop_Click(object sender, System.EventArgs e)
        {
            if (m_downloaderID >= 1000)
            {
                HttpFtp.HttpFtp_Downloader_Release (m_downloaderID, 0);
                m_downloaderID = 0;		
            }

            btnStop.Enabled = false;
            btnStart.Enabled = true;
        }

        private void btnSetting_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("No demo of detailed setting");
        }

        private void Form1_Closed(object sender, System.EventArgs e)
        {
            if (m_downloaderID > 0)
            {
                HttpFtp.HttpFtp_Downloader_Release (m_downloaderID, 0);
                m_downloaderID = 0;		
            }

            HttpFtp.HttpFtp_Shutdown ();
        }

        private void timerRefresh_Tick(object sender, System.EventArgs e)
        {
            if (m_downloaderID >= 1000)
            {
                int dwSpeed = HttpFtp.HttpFtp_Downloader_GetSpeed (m_downloaderID);
                int dwLeftTime = HttpFtp.HttpFtp_Downloader_GetLeftTime (m_downloaderID);
                float percent = HttpFtp.HttpFtp_Downloader_GetPercentDone (m_downloaderID);
                HttpFtp.HttpFtp_DOWNLOADER_STATE state = HttpFtp.HttpFtp_Downloader_GetState (m_downloaderID);

                string fileName = HttpFtp.HttpFtp_Downloader_GetFileName (m_downloaderID);

                string str;
            
                str = "file name: ";
                str += fileName;

                str += " current speed:";
                str += ByteToString (dwSpeed.ToString()) + ("/s");
                str += "\r\n";

                str += "downloaded:";
                str += percent.ToString("F02") + "%";

                str += " status:";
                switch (state)
                {
                    case HttpFtp.HttpFtp_DOWNLOADER_STATE.HttpFtp_DLSTATE_DOWNLOADING:
                        str += "downloading";
                        break;
                    case HttpFtp.HttpFtp_DOWNLOADER_STATE.HttpFtp_DLSTATE_PAUSE:
                        str += "paused";
                        break;
                    case HttpFtp.HttpFtp_DOWNLOADER_STATE.HttpFtp_DLSTATE_STOPPED:
                        str += "stopped";
                        break;
                    case HttpFtp.HttpFtp_DOWNLOADER_STATE.HttpFtp_DLSTATE_FAIL:
                    {
                        str += "error:";
                        str += HttpFtp.HttpFtp_Downloader_GetLastError (m_downloaderID).ToString();
                    }
                        break;
                    case HttpFtp.HttpFtp_DOWNLOADER_STATE.HttpFtp_DLSTATE_DOWNLOADED:
                        str += "finished";
                        break;
                    default:
                        str += "Unknow";
                        break;
                }

                UInt64 size = HttpFtp.HttpFtp_Downloader_GetFileSize (m_downloaderID);
                str += " total size:";
                str += ByteToString (size.ToString());
            
                size = HttpFtp.HttpFtp_Downloader_GetDownloadedSize (m_downloaderID);
                str += " downloaded size:";
                str += ByteToString (size.ToString());

                size = HttpFtp.HttpFtp_Downloader_GetLeftSize (m_downloaderID);
                str += " left size:";
                str += ByteToString (size.ToString());

                textBoxInfo.Text = str;
            }               
        }

        private string ByteToString (string str)
        {
            int len = str.Length;
            int segLen = len % 3;
            int i = 0;
            string ret ="";
            while (i < len)
            {
                if (i > 0)
                    ret += ",";
                ret += str.Substring (i, segLen);
                i += segLen;
                segLen = 3;
            }
            return ret;
        }
	}
}
