using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;

using System.Threading;
using System.Net;
using System.IO;
using Tftp.Net;

using LFP_Manager.Utils;
using LFP_Manager.DataStructure;

namespace LFP_Manager.Controls
{
    public delegate void ResetEvent(object sender, int mode, UInt16 value);

    public partial class ucTftpClientcs : DevExpress.XtraEditors.XtraUserControl
    {
        #region CONST

        const string BMCB_FILE_NAME = "App.bin";
        const string mBMS_FILE_NAME = "mBMS_APP_DL.bin";

        #endregion

        #region VARIABLES

        int ID = 0;
        string hostIP = "";
        byte[] RbmsVersion;
        string TarGetFileName = "";

        int transferedBytes = 0;

        public event ResetEvent OnReset = null;

        #endregion

        #region CONSTRUCTOR

        public ucTftpClientcs()
        {
            InitializeComponent();

            TarGetFileName = "APP.BIN";
        }

        #endregion

        #region RESET EVENT

        private void OnResetEvent(object sender, int mode, UInt16 value)
        {
            if (OnReset != null)
            {
                OnReset(sender, mode, value);
            }
        }
        
        #endregion

        #region INFORMATION UPDATE

        public void UpdateInfor(int sid, string IpAddr, byte[] fwVersion)
        {
            ID = sid;
            hostIP = IpAddr;
            RbmsVersion = fwVersion;

            lbDeviceInfo.Text = String.Format("  RBMS ID: {0}      IP: {1}"
                , sid + 1
                , hostIP
                );
        }

        #endregion

        #region TFTP FUNCTION

        public void FwDownload(string host, string filename)
        {
            //Setup a TftpClient instance
            TftpClient client = new TftpClient(host);
            ITftpTransfer transfer = client.Upload(TarGetFileName);

            transfer.RetryTimeout = TimeSpan.FromMilliseconds(500);
            transfer.RetryCount = 3;
            transfer.TransferMode = TftpTransferMode.octet;

            //Capture the events that may happen during the transfer
            transfer.OnProgress += new TftpProgressHandler(transfer_OnProgress);
            transfer.OnFinished += new TftpEventHandler(transfer_OnFinshed);
            transfer.OnError += new TftpErrorHandler(transfer_OnError);

            //Start the transfer and write the data that we're downloading into a memory stream
            FileStream upLoadFile = new FileStream(teFilename.Text, FileMode.Open);
            progressDownload.Properties.Maximum = (int)(upLoadFile.Length / 1024);
            transfer.Start(upLoadFile);
        }

        void transfer_OnProgress(ITftpTransfer transfer, TftpTransferProgress progress)
        {
            string msg = String.Format("Transfer running. Progress: " + progress);
            transferedBytes = progress.TransferredBytes / 1024;

            TftpMsgProcess(msg, 0);
        }

        void transfer_OnError(ITftpTransfer transfer, TftpTransferError error)
        {
            string msg = String.Format("Transfer failed: " + error);

            TftpMsgProcess(msg, 2);
        }

        void transfer_OnFinshed(ITftpTransfer transfer)
        {
            string msg = String.Format("Transfer succeeded.");

            TftpMsgProcess(msg, 1);
        }

        private void TftpMsgProcess(string msg, int msgType)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    lbDownloadStatus.Text = msg;
                    if (msgType == 0)
                    {
                        // transfer progress
                        progressDownload.Position = transferedBytes;
                    }
                    else if (msgType == 1)
                    {
                        progressDownload.Position = transferedBytes;
                        MessageBox.Show(msg, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else if (msgType == 2)
                    {
                        MessageBox.Show(msg, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }));
            }
            else
            {
                lbDownloadStatus.Text = msg;
                if (msgType == 0)
                {
                    // transfer progress
                    progressDownload.Position = transferedBytes;
                }
                else if (msgType == 1)
                {
                    progressDownload.Position = transferedBytes;
                    MessageBox.Show(msg, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else if (msgType == 2)
                {
                    MessageBox.Show(msg, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        #endregion

        #region BUTTON EVENT

        private void btnFindFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog fwOpenFile;

            fwOpenFile = new OpenFileDialog();

            if (fwOpenFile.ShowDialog() == DialogResult.OK)
            {
                teFilename.Text = fwOpenFile.FileName;

                byte[] bName = csUtils.StringToByte(Path.GetFileName(teFilename.Text));
                if ((bName[0] == (byte)'B')
                    && (bName[1] == (byte)'M')
                    && (bName[2] == (byte)'C')
                    && (bName[3] == (byte)'B')
                    )
                {
                    TarGetFileName = BMCB_FILE_NAME;
                }
                else if ((bName[0] == (byte)'m')
                    && (bName[1] == (byte)'B')
                    && (bName[2] == (byte)'M')
                    && (bName[3] == (byte)'S')
                    )
                {
                    TarGetFileName = mBMS_FILE_NAME;
                }

                if (TarGetFileName != "")
                    lbDownloadStatus.Text = TarGetFileName;

                btnDownload.Enabled = true;
            }
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            if ((hostIP != "")&&(teFilename.Text != ""))
            {
                FwDownload(hostIP, teFilename.Text);
            }
        }
        
        #endregion

        #region RBMS RESET EVENT

        private void btnReset_Click(object sender, EventArgs e)
        {
            OnResetEvent(this, 6, csConstData.ResetFlag.SystemReset);
        }

        private void btnLcdHistoryDelete_Click(object sender, EventArgs e)
        {
            OnResetEvent(this, 6, csConstData.ResetFlag.LcdHistoryDelete);
        }

        public void Reset_Result(string result, bool error)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    if (error)
                        MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    else
                        MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }));
            }
            else
            {
                if (error)
                    MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        #endregion
    }
}
