using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace TSDome
{
    partial class PlayBack : Form
    {
        public int m_playback_dechandle=-1;
        public int m_playback_dowload_handle=-1;
        public int m_playback_playhandle = -1;
        public int m_lUserID = 0;
        public int KPort__ = 80;
        public bool m_bPause = false;
        public int KFastType__ = 0;
        public int kSlowType__ = 0;
        public NetSDK.NET_SDK_DEVICEINFO m_DeviceInfo;
        private NetSDK.fNetDownLoadPosCallBack m_DownData = null;
        private NetSDK.fNetRealDataCallBack_EX m_RealData = null;
        public string m_path;
        public Int64 m_startTime=-1;
        public Int64 m_endTime = -1;
        public int m_lenght = -1;
        public Thread t = null;
        public PlayBack()
        {
            InitializeComponent();
        }
        ~PlayBack()
        {
            if (m_playback_dowload_handle > 0)
            {
                NetSDK.NET_SDK_StopGetFile(m_playback_dowload_handle);
                m_playback_dowload_handle = -1;
            }
        }
        public void Init()
        {
            listView1.Items.Clear();
            stop();
            comboBoxChannel.Items.Clear();
            string strChannel = "Channel";
            for (int i = 0; i < (m_DeviceInfo.byChanNum + m_DeviceInfo.iDigChannel); i++)
            {
                comboBoxChannel.Items.Insert(i, strChannel + (i + 1).ToString());
            }
            comboBoxChannel.SelectedIndex = 0;
            comboBoxRecord.Items.Insert(0, "All");
            comboBoxRecord.Items.Insert(1, "Alarm");
            comboBoxRecord.Items.Insert(2, "Motion");
            comboBoxRecord.Items.Insert(3, "Normal");
            comboBoxRecord.Items.Insert(4, "Hand");
            comboBoxRecord.Items.Insert(5, "PICAll");
            comboBoxRecord.Items.Insert(6, "PICAlarm");
            comboBoxRecord.Items.Insert(7, "PICMotion");
            comboBoxRecord.Items.Insert(8, "PICNormal");
            comboBoxRecord.Items.Insert(9, "PICHand");
            comboBoxRecord.SelectedIndex = 0;
            comboBoxStream.Items.Insert(0, "Main Stream");
            comboBoxStream.Items.Insert(1, "Sub Stream");
            comboBoxStream.SelectedIndex = 0;
            DateTime nowtime = DateTime.Now;
            dateTimePicker1.Value = new DateTime(nowtime.Year, nowtime.Month, nowtime.Day, 0, 0, 0);
            dateTimePicker2.Value = new DateTime(nowtime.Year, nowtime.Month, nowtime.Day, 23, 59, 59); ;
        }
        #region 程序集属性访问器

        public string AssemblyTitle
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                if (attributes.Length > 0)
                {
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    if (titleAttribute.Title != "")
                    {
                        return titleAttribute.Title;
                    }
                }
                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        public string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        public string AssemblyDescription
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyDescriptionAttribute)attributes[0]).Description;
            }
        }

        public string AssemblyProduct
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyProductAttribute)attributes[0]).Product;
            }
        }

        public string AssemblyCopyright
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
            }
        }

        public string AssemblyCompany
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyCompanyAttribute)attributes[0]).Company;
            }
        }
        #endregion

        private void buttonSearch_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            int nChannel = comboBoxChannel.SelectedIndex;
            int nFileType = comboBoxRecord.SelectedIndex;
            int nStream = comboBoxStream.SelectedIndex;
            if (nFileType > 4)
            {
                nFileType = 10 + nFileType - 5;
            }
            NetSDK.NET_SDK_TIME StartTime;
            NetSDK.NET_SDK_TIME StopTime;

            StartTime.dwYear = dateTimePicker1.Value.Year;
            StartTime.dwMonth = dateTimePicker1.Value.Month;
            StartTime.dwDay = dateTimePicker1.Value.Day;
            StartTime.dwHour = dateTimePicker1.Value.Hour;
            StartTime.dwMinute = dateTimePicker1.Value.Minute;
            StartTime.dwSecond = dateTimePicker1.Value.Second;
            StopTime.dwYear = dateTimePicker2.Value.Year;
            StopTime.dwMonth = dateTimePicker2.Value.Month;
            StopTime.dwDay = dateTimePicker2.Value.Day;
            StopTime.dwHour = dateTimePicker2.Value.Hour;
            StopTime.dwMinute = dateTimePicker2.Value.Minute;
            StopTime.dwSecond = dateTimePicker2.Value.Second;

            NetSDK.NET_SDK_FILE_DATA[] filedatabuf = new NetSDK.NET_SDK_FILE_DATA[100];
            for (int i = 0; i < filedatabuf.Length; i++)
            {
                filedatabuf[i] = new NetSDK.NET_SDK_FILE_DATA();
            }
            IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NetSDK.NET_SDK_FILE_DATA)) * 100);
	        if (filedatabuf == null)
	        {
		        return;
	        }

             int nNum = new int();
             nNum= 0;
		     int nRet = 0;
             buttonSearch.Enabled = false;
		
		    NetSDK.NET_SDK_FINDINFO searchInfo=new NetSDK.NET_SDK_FINDINFO();
		    searchInfo.nChannelN0 = nChannel;
		    searchInfo.nFileType = nFileType;
		    searchInfo.nStream = nStream;
		    searchInfo.startTime=StartTime;
		    searchInfo.endTime=StopTime;
		    nRet=NetSDK.NET_SDK_FindFileByName(m_lUserID,ref searchInfo,pt,100,ref nNum,5000);
            if(nRet!=0&&nNum>0)
            {
                for (int i = 0; i < nNum; i++)
                {
                    IntPtr ptr = (IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(NetSDK.NET_SDK_FILE_DATA)));
                    filedatabuf[i] = (NetSDK.NET_SDK_FILE_DATA)Marshal.PtrToStructure(ptr, typeof(NetSDK.NET_SDK_FILE_DATA));
                    if (filedatabuf[i].nstream == 0 || filedatabuf[i].nstream == 1 && new string(filedatabuf[i].sFileName)!= "")
                    {
                        listView1.Items.Add(new ListViewItem(new string[] {(i+1).ToString(),new string( filedatabuf[i].sFileName)}));//将查找的录像文件添加到列表中
                        listView1.Items[listView1.Items.Count-1].SubItems[1].Tag = filedatabuf[i];
                    }
                    else
                    {
                        break;
                    }
                }
                listView1.Items[0].Selected = true;
            }
            else
            {
                MessageBox.Show("No Record!");
            }
            buttonSearch.Enabled = true;
        }

        private void buttonPlay_Click(object sender, EventArgs e)
        {
            Play();
        }
        public delegate void SetDownPos(int lTotalSize, int lDownLoadSize);
        private void SetDownloadPos(int lTotalSize, int lDownLoadSize)
        {
            string i = lTotalSize.ToString() + "/" + lDownLoadSize.ToString();
            //判断该方法是否被主线程调用，也就是创建labMessage1控件的线程，当控件的InvokeRequired属性为ture时，说明是被主线程以外的线程调用。如果不加判断，会造成异常
            if (this.InvokeRequired)
            {
                SetDownPos setpos = new SetDownPos(SetDownloadPos);
                //this指窗体，在这调用窗体的Invoke方法，也就是用窗体的创建线程来执行mainThread对象委托的方法，再加上需要的参数(i)
                this.Invoke(setpos, new object[] { lTotalSize,lDownLoadSize });
            }
            else
            {
                labDownloadPos.Text = i;
                if (lDownLoadSize != 0&&lTotalSize>0)
                {
                    if ((lTotalSize*1000/ lDownLoadSize) <= 999)
                    {
                        progressDown.Value = lTotalSize *1000 / lDownLoadSize;
                    }
                }
                else if(lTotalSize==-1)
                {
                    i = lDownLoadSize.ToString() + "/" + lDownLoadSize.ToString();
                    labDownloadPos.Text = i;
                    progressDown.Value = 0;
                    MessageBox.Show("Download completed");
                }
            }
        }
        public void DownLoadRecordPosCallback (int lPlayHandle, int lTotalSize, int lDownLoadSize, int dwUser)
        {   	
            if (lDownLoadSize == 0)
	        {
                MessageBox.Show("Download completed");
                //已完成 completed
	        } 
            else
	        {
                if (lPlayHandle == m_playback_dowload_handle)
                {
                    SetDownloadPos(lDownLoadSize,lTotalSize);
                }
        		//可以在这里计算下载进度,但是此demo用NET_SDK_GetDownloadPos来获取进度, 因此这里不做相关操作
                //You can calculate the download progress here, but this demo uses NET_SDK_GetDownloadPos to get the progress, so do not do related operations here.
	        }
        }
        public int PlaybackNetDataCallBack_EX(int lRealHandle, ref NetSDK.NET_SDK_PACKET_INFO_EX pFrame, IntPtr dwUser)
        {
            if (m_playback_dechandle >= 0)
            {
                Int64 bRet = PlaySDK.PLAY_SDK_GetCurTimeStamp(m_playback_dechandle);
                return PlaySDK.PLAY_SDK_InputData(m_playback_dechandle ,pFrame.pPacketBuffer, pFrame.dwPacketSize);
            }
            return 1;
        }
        public void getPlayPos() //获取现在播放的时间戳 Gets the timestamp for the current playback    1970 to the present 
        {
            while(m_playback_dechandle >= 0)
            {
                SetPlayBackPos(PlaySDK.PLAY_SDK_GetCurTimeStamp(m_playback_dechandle));
                Thread.Sleep(1000);
            }
        }
        public delegate void SetPlayPos(Int64 time);
        private void SetPlayBackPos(Int64 time)
        {
            //判断该方法是否被主线程调用，也就是创建labMessage1控件的线程，当控件的InvokeRequired属性为ture时，说明是被主线程以外的线程调用。如果不加判断，会造成异常
            if (this.InvokeRequired)
            {
                SetPlayPos setpos = new SetPlayPos(SetPlayBackPos);
                //this指窗体，在这调用窗体的Invoke方法，也就是用窗体的创建线程来执行mainThread对象委托的方法，再加上需要的参数(i)
                this.Invoke(setpos, new object[] {time});
            }
            else
            {
                if (m_endTime>m_startTime&&time>m_startTime&&time<m_endTime)
                {
                    progressPlay.Value = (int)((time - m_startTime) * ((Int64)10000) / (m_endTime - m_startTime));
                }
            }
        }
        public void Play()
        {
            if(listView1.Items.Count==0)
            {
                return;
            }
            if (m_playback_playhandle == -1 || m_playback_playhandle == 0)
            {
                NetSDK.NET_SDK_FILE_DATA RecordFile = (NetSDK.NET_SDK_FILE_DATA)listView1.SelectedItems[0].SubItems[1].Tag;
                if (m_playback_dechandle == -1)
                {
                    if (PlaySDK.PLAY_SDK_OpenStream(KPort__, IntPtr.Zero, 1, PlaySDK.PLAY_SDK_SOURCE_BUF_MIN * 200)!=0)
                    {
                        PlaySDK.PLAY_SDK_SetStreamOpenMode(KPort__, PlaySDK.PLAY_SDK_STREAME_FILE);
                        PlaySDK.PLAY_SDK_Play(KPort__, pictureBox1.Handle);

                        m_playback_dechandle = KPort__;
                    }
                }
                m_DownData = new NetSDK.fNetDownLoadPosCallBack(DownLoadRecordPosCallback);
                m_RealData = new NetSDK.fNetRealDataCallBack_EX(PlaybackNetDataCallBack_EX);
                m_playback_playhandle = NetSDK.NET_SDK_PlayBackByName_Ex(m_lUserID,ref RecordFile, m_DownData, m_RealData, 1);
                if (m_playback_playhandle <= 0)
                {
                    MessageBox.Show("Playback error");
                    return;
                }
                else
                {
                    DateTime Date= new DateTime(1970,1,1,8,0,0);
                    DateTime Datestart= new DateTime(RecordFile.stBeginTime.year,RecordFile.stBeginTime.month,RecordFile.stBeginTime.day,RecordFile.stBeginTime.hour,RecordFile.stBeginTime.minute,RecordFile.stBeginTime.second); 
                    DateTime Dateend= new DateTime(RecordFile.stEndTime.year,RecordFile.stEndTime.month,RecordFile.stEndTime.day,RecordFile.stEndTime.hour,RecordFile.stEndTime.minute,RecordFile.stEndTime.second);
                    m_startTime = Convert.ToInt64((Datestart - Date).TotalSeconds);
                    m_endTime = Convert.ToInt64((Dateend - Date).TotalSeconds);
                    m_lenght = RecordFile.size;
                    t = new Thread(new ThreadStart(getPlayPos));
                    t.Name = "PosThread";
                    t.Start();
                }
            }
            else
            {
                if (m_bPause)
                {
                    NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle,(int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_CONTINUE, 0);
                    PlaySDK.PLAY_SDK_Pause(m_playback_dechandle,!m_bPause?1:0);
                    m_bPause = !m_bPause;
                }
                NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle, (int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_FAST, 0);
                PlaySDK.PLAY_SDK_Play(m_playback_dechandle, pictureBox1.Handle);
                KFastType__ = 0;
                kSlowType__ = 0;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            stop();
        }
        public void stop()
        {
            if (m_playback_playhandle >= 0)
            {
                NetSDK.NET_SDK_StopPlayBack(m_playback_playhandle);
                m_playback_playhandle = -1;
                m_startTime = -1;
                m_endTime = -1;
                m_lenght = -1;
                progressPlay.Value = 0;
            }
            if (m_playback_dechandle > 0)
            {
                PlaySDK.PLAY_SDK_Stop(m_playback_dechandle);
                PlaySDK.PLAY_SDK_CloseStream(m_playback_dechandle);
                m_playback_dechandle = -1;
            }
        }

        private void buttonPause_Click(object sender, EventArgs e)
        {
            if (!m_bPause)
                NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle,(int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_PAUSE, 0);
            else
                NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle, (int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_CONTINUE, 0);
            PlaySDK.PLAY_SDK_Pause(m_playback_dechandle, !m_bPause?1:0);
            m_bPause = !m_bPause;
        }

        private void buttonFast_Click(object sender, EventArgs e)
        {
            if (++KFastType__ > 4)
            {
                KFastType__ = 1;
            }
            kSlowType__ = 0;
            NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle,(int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_FAST, KFastType__);
            PlaySDK.PLAY_SDK_Fast(m_playback_dechandle);
        }

        private void buttonSlow_Click(object sender, EventArgs e)
        {
            if (++kSlowType__ > 4)
            {
                kSlowType__ = 1;
            }
            KFastType__ = 0;
            NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle, (int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_SLOW, kSlowType__);
            PlaySDK.PLAY_SDK_Slow(m_playback_dechandle);
        }

        private void buttonDownload_Click(object sender, EventArgs e)
        {
           /* if (listView1.Items.Count == 0)
            {
                return;
            }
            if (m_playback_dowload_handle > 0)
            {
                NetSDK.NET_SDK_StopGetFile(m_playback_dowload_handle);
                m_playback_dowload_handle = -1;
                MessageBox.Show("Stop Down");
                return;
            }
            NetSDK.NET_SDK_FILE_DATA RecordFile = (NetSDK.NET_SDK_FILE_DATA)listView1.SelectedItems[0].SubItems[1].Tag;
            string filename = RecordFile.stBeginTime.year.ToString() + RecordFile.stBeginTime.month.ToString() + RecordFile.stBeginTime.day.ToString()
                + RecordFile.stBeginTime.hour.ToString() + RecordFile.stBeginTime.minute.ToString() + RecordFile.stBeginTime.second.ToString()
                + RecordFile.stEndTime.year.ToString() + RecordFile.stEndTime.month.ToString() + RecordFile.stEndTime.day.ToString()
                + RecordFile.stEndTime.hour.ToString() + RecordFile.stEndTime.minute.ToString() + RecordFile.stEndTime.second.ToString()
                + ".h264";
            string strSaveName = m_path+filename;
            m_DownData = new NetSDK.fNetDownLoadPosCallBack(DownLoadRecordPosCallback);
            m_playback_dowload_handle = NetSDK.NET_SDK_GetFileByName(m_lUserID, ref RecordFile, strSaveName, m_DownData, 1);
            if (m_playback_dowload_handle >= 0)
            {
                MessageBox.Show("Statr Down");        
            }
            else
            {
                MessageBox.Show("Down error");
            }*/
            if (m_playback_dowload_handle > 0)
            {
                NetSDK.NET_SDK_StopGetFile(m_playback_dowload_handle);
                m_playback_dowload_handle = -1;
                MessageBox.Show("Stop Down");
                return;
            }
            int nChannel = comboBoxChannel.SelectedIndex;
            int nFileType = comboBoxRecord.SelectedIndex;
            int nStream = comboBoxStream.SelectedIndex;
            if (nFileType > 4)
            {
                nFileType = 10 + nFileType - 5;
            }
            NetSDK.NET_SDK_TIME StartTime;
            NetSDK.NET_SDK_TIME StopTime;

            StartTime.dwYear = dateTimePicker1.Value.Year;
            StartTime.dwMonth = dateTimePicker1.Value.Month;
            StartTime.dwDay = dateTimePicker1.Value.Day;
            StartTime.dwHour = dateTimePicker1.Value.Hour;
            StartTime.dwMinute = dateTimePicker1.Value.Minute;
            StartTime.dwSecond = dateTimePicker1.Value.Second;
            StopTime.dwYear = dateTimePicker2.Value.Year;
            StopTime.dwMonth = dateTimePicker2.Value.Month;
            StopTime.dwDay = dateTimePicker2.Value.Day;
            StopTime.dwHour = dateTimePicker2.Value.Hour;
            StopTime.dwMinute = dateTimePicker2.Value.Minute;
            StopTime.dwSecond = dateTimePicker2.Value.Second;
            NetSDK.NET_SDK_FINDINFO FindInfo = new NetSDK.NET_SDK_FINDINFO();
            FindInfo.nChannelN0 = nChannel;
            FindInfo.nFileType = nFileType;
            FindInfo.nStream = nStream;
            FindInfo.startTime = StartTime;
            FindInfo.endTime = StopTime;
            m_DownData = new NetSDK.fNetDownLoadPosCallBack(DownLoadRecordPosCallback);
            char bMerge = (char)1;
            m_playback_dowload_handle = NetSDK.NET_SDK_GetFileByTime_V4(m_lUserID, ref FindInfo, m_path,bMerge, m_DownData, 1,0);
            if (m_playback_dowload_handle > 0)
            {
                MessageBox.Show("Statr Down");        
            }
            else
            {
                MessageBox.Show("Down error");
            }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void PlayBack_Load(object sender, EventArgs e)
        {

        }
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            
            this.Hide();
            e.Cancel = true;
        }

        private void Snap_Click(object sender, EventArgs e)
        {
            if (m_playback_playhandle >= 0)
            {
                string filename = textBoxFile.Text + DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString()
                    + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + ".jpg";
                int bRet = PlaySDK.PLAY_SDK_CatchPic(m_playback_dechandle, filename, 0);
                if (bRet > 0)
                {
                    MessageBox.Show("Successful capture");
                }
                else
                {
                    MessageBox.Show("Failed to capture the map");
                }
            }
        }

        private void progressPlay_Click(object sender, EventArgs e)
        {
            if(m_playback_playhandle>0)
            {
                int right = progressPlay.Right;
                int left = progressPlay.Left;
                int clickx = this.PointToClient(Control.MousePosition).X;
                if (clickx > left)
                {
                    int pos = 100* (clickx - left) / (right - left);
                    NetSDK.NET_SDK_PlayBackControl(m_playback_playhandle, (int)NetSDK.NET_SDK_PlayBackAction.NET_SDK_PLAY_BACK_SEEK_PERCENT, pos);//Seek setting is not accurate and the delay is long. It is recommended to close and reopen and set the starting time
                }
            }
        }
    }
}
