using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NetClient;
using System.Diagnostics;
using System.IO;

namespace PlayBackAndDownLoadDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// playback client to communication with device.
        /// </summary>
        private PlayBackClient m_Client;
        /// <summary>
        /// current playback handle.
        /// </summary>
        private IntPtr m_PlayHandle;
        /// <summary>
        /// current speed.
        /// </summary>
        private double m_CurrentSpeed;
        /// <summary>
        /// max speed.
        /// </summary>
        private const double MAXSPEED = 16;
        /// <summary>
        /// mix speed.
        /// </summary>
        private const double MINSPEED = 0.0625; //1 / 16


        public MainWindow()
        {
            LoadLanguage();
            InitializeComponent();
            try
            {
                //instance playbakc client.add try catch for check depend library is right.
                m_Client = new PlayBackClient();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Process.GetCurrentProcess().Kill();
            }
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        /// <summary>
        /// check language,and load resource.
        /// </summary>
        private void LoadLanguage()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "Language";
            string fileNamePath = string.Empty;
            ResourceDictionary resourceDictionary = new ResourceDictionary();
            switch (System.Globalization.CultureInfo.CurrentCulture.LCID)
            {
                case 0x00804:
                    fileNamePath = path + "\\zh-cn.xaml";
                    if (!File.Exists(fileNamePath))
                    {
                        resourceDictionary.Source = new Uri("pack://application:,,,/language/zh-cn.xaml");
                    }
                    else
                    {
                        resourceDictionary.Source = new Uri(fileNamePath, UriKind.RelativeOrAbsolute);
                    }
                    break;
                default:
                    fileNamePath = path + "\\en-us.xaml";
                    if (!File.Exists(fileNamePath))
                    {
                        resourceDictionary.Source = new Uri("pack://application:,,,/language/en-us.xaml");
                    }
                    else
                    {
                        resourceDictionary.Source = new Uri(fileNamePath, UriKind.RelativeOrAbsolute);
                    }
                    break;
            }
            App.Current.Resources.MergedDictionaries.Add(resourceDictionary);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //subscribe playback progress event.
            m_Client.PlayBackPosReceived += new DownloadHandler(m_Client_PlayBackPosReceived);
            m_Client.DownloadPosReceived += new DownloadHandler(m_Client_DownloadPosReceived);
            logout_btn.IsEnabled = false;
            play_bt.IsEnabled = false;
            pause_bt.IsEnabled = false;
            stop_bt.IsEnabled = false;
            slow_bt.IsEnabled = false;
            fast_bt.IsEnabled = false;
            normal_bt.IsEnabled = false;
            playback_channel_combox.IsEnabled = false;
            playback_type_combox.IsEnabled = false;
            playback_streamtype_combox.IsEnabled = false;
            playback_starttime_dp.Enabled = false;
            playback_endtime_dp.Enabled = false;
            playback_bt.IsEnabled = false;
            download_channel_combox.IsEnabled = false;
            download_streamtype_combox.IsEnabled = false;
            download_starttime_dp.Enabled = false;
            download_endtime_dp.Enabled = false;
            downlaodstart_bt.IsEnabled = false;
            downlaodstop_bt.IsEnabled = false;
        }

        /// <summary>
        /// just can put number.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Port_TextInput(object sender, TextCompositionEventArgs e)
        {
            try
            {
                Convert.ToUInt32(e.Text);
                e.Handled = false;
            }
            catch
            {
                e.Handled = true;
            }
        }

        /// <summary>
        /// login device.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void login_btn_Click(object sender, RoutedEventArgs e)
        {
            string ip = ip_textbox.Text.Trim();
            if (ip == "" || ip == null)
            {
                MessageBox.Show((string)App.Current.Resources["ID_IP_ERROR"]);
                return;
            }
            ushort port = 0;
            string portString = port_textbox.Text.Trim();
            if (portString == null || portString == "")
            {
                MessageBox.Show((string)App.Current.Resources["ID_PORT_ERROR1"]);
                return;
            }
            try
            {
                port = Convert.ToUInt16(port_textbox.Text.Trim());
            }
            catch
            {
                MessageBox.Show((string)App.Current.Resources["ID_PORT_ERROR2"]);
                return;
            }
            string username = username_textbox.Text.Trim();
            if (username == null || username == "")
            {
                MessageBox.Show((string)App.Current.Resources["ID_USERNAME_ERROR"]);
                return;
            }
            string password = password_textbox.Password.Trim();
            try
            {
                m_Client.Login(ip, port, username, password);
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            login_btn.IsEnabled = false;
            logout_btn.IsEnabled = true;
            playback_channel_combox.IsEnabled = true;
            playback_type_combox.IsEnabled = true;
            playback_streamtype_combox.IsEnabled = true;
            playback_starttime_dp.Enabled = true;
            playback_endtime_dp.Enabled = true;
            download_channel_combox.IsEnabled = true;
            download_streamtype_combox.IsEnabled = true;
            download_starttime_dp.Enabled = true;
            download_endtime_dp.Enabled = true;
            downlaodstart_bt.IsEnabled = true;
            downlaodstop_bt.IsEnabled = false;
            for (int i = 0; i < m_Client.DeviceInfo.nChanNum; i++)
            {
                playback_channel_combox.Items.Add(i+1);
                download_channel_combox.Items.Add(i+1);
            }
            playback_type_combox.Items.Add((string)App.Current.TryFindResource("ID_AllTYPE"));
            playback_type_combox.Items.Add((string)App.Current.TryFindResource("ID_ALARMTYPE"));
            playback_type_combox.Items.Add((string)App.Current.TryFindResource("ID_MOTIONTYPE"));
            playback_streamtype_combox.Items.Add((string)App.Current.TryFindResource("ID_MAINSTREAM"));
            playback_streamtype_combox.Items.Add((string)App.Current.TryFindResource("ID_SUBSTREAM"));
            playback_bt.IsEnabled = true;
            download_streamtype_combox.Items.Add((string)App.Current.TryFindResource("ID_MAINSTREAM"));
            download_streamtype_combox.Items.Add((string)App.Current.TryFindResource("ID_SUBSTREAM"));
            playback_channel_combox.SelectedIndex = 0;
            playback_type_combox.SelectedIndex = 0;
            playback_streamtype_combox.SelectedIndex = 0;
            download_channel_combox.SelectedIndex = 0;
            download_streamtype_combox.SelectedIndex = 0;
        }

        /// <summary>
        /// logout device.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void logout_btn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.Logout();
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            login_btn.IsEnabled = true;
            logout_btn.IsEnabled = false;
            playback_channel_combox.Items.Clear();
            playback_type_combox.Items.Clear();
            playback_streamtype_combox.Items.Clear();
            playback_channel_combox.IsEnabled = false;
            playback_type_combox.IsEnabled = false;
            playback_streamtype_combox.IsEnabled = false;
            playback_starttime_dp.Enabled = false;
            playback_endtime_dp.Enabled = false;
            playback_bt.IsEnabled = false;
            download_channel_combox.Items.Clear();
            download_streamtype_combox.Items.Clear();
            download_channel_combox.IsEnabled = false;
            download_streamtype_combox.IsEnabled = false;
            download_starttime_dp.Enabled = false;
            download_endtime_dp.Enabled = false;
            downlaodstart_bt.IsEnabled = false;
            downlaodstop_bt.IsEnabled = false;
            pause_bt.Visibility = Visibility.Visible;
            pause_bt.IsEnabled = false;
            play_bt.Visibility = Visibility.Collapsed;
            play_bt.IsEnabled = false;
            stop_bt.IsEnabled = false;
            slow_bt.IsEnabled = false;
            fast_bt.IsEnabled = false;
            normal_bt.IsEnabled = false;
            speed_tb.Text = "";
            picBox.Refresh();
        }

        /// <summary>
        /// playback function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void playback_bt_Click(object sender, RoutedEventArgs e)
        {
            picBox.Refresh();
            DateTime start = new DateTime(playback_starttime_dp.Value.Year, playback_starttime_dp.Value.Month, playback_starttime_dp.Value.Day, playback_starttime_dp.Value.Hour, playback_starttime_dp.Value.Minute, playback_starttime_dp.Value.Second);
            DateTime end = new DateTime(playback_endtime_dp.Value.Year, playback_endtime_dp.Value.Month, playback_endtime_dp.Value.Day, playback_endtime_dp.Value.Hour, playback_endtime_dp.Value.Minute, playback_endtime_dp.Value.Second);
            if (start == end)
            {
                MessageBox.Show((string)App.Current.Resources["ID_TIME_ERROR1"]);
                return;
            }
            if (start > end)
            {
                MessageBox.Show((string)App.Current.Resources["ID_TIME_ERROR2"]);
                return;
            }
            switch (playback_type_combox.SelectedIndex)
            {
                case 0:
                    m_Client.RecordType = EM_RECORD_TYPE.ALL;
                    break;
                case 1:
                    m_Client.RecordType = EM_RECORD_TYPE.ALARM;
                    break;
                case 2:
                    m_Client.RecordType = EM_RECORD_TYPE.MOTION;
                    break;
                default:
                    m_Client.RecordType = EM_RECORD_TYPE.ALL;
                    break;
            }
            m_Client.StreamType = (EM_STREAM_TYPE)playback_streamtype_combox.SelectedIndex + 1;
            
            try
            {
                m_Client.StartPlayBack(start, end, playback_channel_combox.SelectedIndex, picBox.Handle);
                foreach (var item in m_Client.PlayHandleList)
                {
                    m_PlayHandle = item;
                    break;
                }
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            playback_bt.IsEnabled = false;
            pause_bt.IsEnabled = true;
            play_bt.IsEnabled = true;
            stop_bt.IsEnabled = true;
            slow_bt.IsEnabled = true;
            fast_bt.IsEnabled = true;
            normal_bt.IsEnabled = true;
            
            ShowSpeed(PlayBackType.Normal);
        }

        /// <summary>
        /// process playback progress information function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void m_Client_PlayBackPosReceived(object sender, DownloadEventArgs args)
        {
            if (args.DownloadSize == args.TotalSize)
            {
                playback_bt.IsEnabled = true;
                pause_bt.IsEnabled = false;
                play_bt.IsEnabled = false;
                stop_bt.IsEnabled = false;
                slow_bt.IsEnabled = false;
                fast_bt.IsEnabled = false;
                normal_bt.IsEnabled = false;
                speed_tb.Text = "";
            }
        }

        /// <summary>
        /// show current speed.
        /// </summary>
        /// <param name="mode"></param>
        private void ShowSpeed(PlayBackType mode)
        {
            switch (mode)
            {
                case PlayBackType.Slow:
                    m_CurrentSpeed /= 2;
                    break;
                case PlayBackType.Stop:
                    m_CurrentSpeed = 0;
                    break;
                case PlayBackType.Normal:
                    m_CurrentSpeed = 1;
                    break;
                case PlayBackType.Fast:
                    m_CurrentSpeed *= 2;
                    break;
                default:
                    break;
            }
            if (mode == PlayBackType.Pause || m_CurrentSpeed == 0)
            {
                speed_tb.Text = "";
                return;
            }
            if (m_CurrentSpeed < 1 && m_CurrentSpeed > 0)
            {
                int i = (int)(1 / m_CurrentSpeed);
                speed_tb.Text = string.Format("1/{0}X", i);
            }
            else
            {
                speed_tb.Text = m_CurrentSpeed.ToString() + "X";
            }
        }

        /// <summary>
        /// playback pause control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pause_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.PlayBackControl(m_PlayHandle, PlayBackType.Pause);
                pause_bt.Visibility = Visibility.Collapsed;
                play_bt.Visibility = Visibility.Visible;
                slow_bt.IsEnabled = false;
                fast_bt.IsEnabled = false;
                normal_bt.IsEnabled = false;
                ShowSpeed(PlayBackType.Pause);
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// playback play control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void play_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.PlayBackControl(m_PlayHandle, PlayBackType.Play);
                pause_bt.Visibility = Visibility.Visible;
                play_bt.Visibility = Visibility.Collapsed;
                if (m_CurrentSpeed == MAXSPEED)
                {
                    fast_bt.IsEnabled = false;
                }
                else
                {
                    fast_bt.IsEnabled = true;
                }
                if (m_CurrentSpeed == MINSPEED)
                {
                    slow_bt.IsEnabled = false;
                }
                else
                {
                    slow_bt.IsEnabled = true;
                }
                normal_bt.IsEnabled = true;
                ShowSpeed(PlayBackType.Play);
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// playback stop control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stop_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.StopPlayBack(m_PlayHandle);
                pause_bt.Visibility = Visibility.Visible;
                play_bt.Visibility = Visibility.Collapsed;
                playback_bt.IsEnabled = true;
                pause_bt.IsEnabled = false;
                play_bt.IsEnabled = false;
                stop_bt.IsEnabled = false;
                slow_bt.IsEnabled = false;
                fast_bt.IsEnabled = false;
                normal_bt.IsEnabled = false;
                m_PlayHandle = IntPtr.Zero;
                picBox.Refresh();
                ShowSpeed(PlayBackType.Stop);
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// playback slowplay control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void slow_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.PlayBackControl(m_PlayHandle, PlayBackType.Slow);
                ShowSpeed(PlayBackType.Slow);
                if (m_CurrentSpeed == MINSPEED)
                {
                    slow_bt.IsEnabled = false;
                }
                else
                {
                    fast_bt.IsEnabled = true;
                }
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// playback fastplay control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fast_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.PlayBackControl(m_PlayHandle, PlayBackType.Fast);
                ShowSpeed(PlayBackType.Fast);
                if (m_CurrentSpeed == MAXSPEED)
                {
                    fast_bt.IsEnabled = false;
                }
                else
                {
                    slow_bt.IsEnabled = true;
                }
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// playback normalplay control function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void normal_bt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_Client.PlayBackControl(m_PlayHandle, PlayBackType.Normal);
                fast_bt.IsEnabled = true;
                slow_bt.IsEnabled = true;
                ShowSpeed(PlayBackType.Normal);
            }
            catch (NETClientExcetion ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// download function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void downlaodstart_bt_Click(object sender, RoutedEventArgs e)
        {
            DateTime start = new DateTime(download_starttime_dp.Value.Year, download_starttime_dp.Value.Month, download_starttime_dp.Value.Day, download_starttime_dp.Value.Hour, download_starttime_dp.Value.Minute, download_starttime_dp.Value.Second);
            DateTime end = new DateTime(download_endtime_dp.Value.Year, download_endtime_dp.Value.Month, download_endtime_dp.Value.Day, download_endtime_dp.Value.Hour, download_endtime_dp.Value.Minute, download_endtime_dp.Value.Second);
            if (start == end)
            {
                MessageBox.Show((string)App.Current.Resources["ID_TIME_ERROR1"]);
                return;
            }
            if (start > end)
            {
                MessageBox.Show((string)App.Current.Resources["ID_TIME_ERROR2"]);
                return;
            }
            m_Client.StreamType = (EM_STREAM_TYPE)download_streamtype_combox.SelectedIndex + 1;
            m_Client.RecordType = EM_RECORD_TYPE.ALL;

            System.Windows.Forms.SaveFileDialog saveFileDialog = new System.Windows.Forms.SaveFileDialog();
            saveFileDialog.FileName = "data";
            saveFileDialog.Filter = "|*.dav";
            string path = AppDomain.CurrentDomain.BaseDirectory + "savedata";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            saveFileDialog.InitialDirectory = path;
            var res = saveFileDialog.ShowDialog();
            if (res == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    m_Client.StartDownload(start, end, download_channel_combox.SelectedIndex, saveFileDialog.FileName);
                    downlaodstart_bt.IsEnabled = false;
                    downlaodstop_bt.IsEnabled = true;
                    download_processBar.Value = 0;
                }
                catch (NETClientExcetion ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            
        }
        
        /// <summary>
        /// process download progress information.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void m_Client_DownloadPosReceived(object sender, DownloadEventArgs args)
        {
            download_processBar.Value = args.DownloadSize * 100 / args.TotalSize;
            if (args.DownloadSize == args.TotalSize)
            {
                downlaodstop_bt.IsEnabled = false;
                MessageBoxResult res = MessageBox.Show((string)App.Current.Resources["ID_DOWNLOADSUCCESS"]);
                if (res == MessageBoxResult.OK)
                {
                    downlaodstart_bt.IsEnabled = true;
                    download_processBar.Value = 0;
                }
                
            }
            if (args.IsFailed)
            {
                MessageBox.Show((string)App.Current.Resources["ID_DOWNLOADFAILEDERROR"]);
            }
            
        }

        /// <summary>
        /// stop download function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void downlaodstop_bt_Click(object sender, RoutedEventArgs e)
        {
            m_Client.StopDownloadAll();
            downlaodstart_bt.IsEnabled = true;
            downlaodstop_bt.IsEnabled = false;
            download_processBar.Value = 0;
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            m_Client.Dispose();
        }
        
    }
}