//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using Revisor.VMS;
using Revisor.VMS.ClientSDK;
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace ViewArchiveExample
{
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
    public partial class TestForm : Form
    {
        //----------------------------------------------------------------------------------------------------------------------------------------------------------------
        #region Properties

        private ConnectionStatus _status;
        private ConnectionWrapper _connection;
        private List<CameraSequence> _sequences = new List<CameraSequence>();

        private enum ConnectionStatus
        {
            Disconnected,
            Connecting,
            Connected
        }

        #endregion
        //----------------------------------------------------------------------------------------------------------------------------------------------------------------
        #region Methods

        /// <summary>
        /// Creates an instance of the TestForm class.
        /// </summary>
        public TestForm()
        {
            InitializeComponent();
            SetStatus(ConnectionStatus.Disconnected);

            // Hide controls if you need
            //videoControl.ShowToolBar = false;
            //videoControl.ShowDiagram = false;
        }

        private async void StartConnect(string serverName, string user, string password)
        {
            SetStatus(ConnectionStatus.Connecting);

            try
            {
                _connection = new ConnectionWrapper();
                await _connection.ConnectAsync(serverName, 11012, user, password);
                FinishConnect(null);
            }
            catch (Exception ex)
            {
                FinishConnect(ex);
            }
        }

        private void FinishConnect(Exception ex)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<Exception>(FinishConnect), ex);
                return;
            }

            if (_connection != null && _connection.Connected)
            {
                SetStatus(ConnectionStatus.Connected);
                InitiatePlayback();
            }
            else
            {
                CancelConnect();

                if (ex != null)
                {
                    MessageBox.Show("ERROR: " + GetFullExceptionText(ex));
                }
            }
        }

        private void InitiatePlayback()
        {
            if (_connection != null)
            {
                var configuration = _connection.GetConfiguration();
                var cameras = configuration.Cameras;
                var camera = cameras.Find(c => !c.Disabled);

                videoControl.InitNow(camera.ID);
            }
        }

        private void CancelConnect()
        {
            videoControl.ClearCamera();

            if (_connection != null)
            {
                _connection.Dispose();
                _connection = null;
            }

            SetStatus(ConnectionStatus.Disconnected);
        }

        private void SetStatus(ConnectionStatus status)
        {
            _status = status;

            labelStatus.Text = _status.ToString();
            textServer.Enabled = textUser.Enabled = textPassword.Enabled = (_status == ConnectionStatus.Disconnected);

            buttonConnect.Text = (_status == ConnectionStatus.Disconnected
                ? "Connect"
                : "Disconnect"
            );

            buttonCamera.Enabled = (_status == ConnectionStatus.Connected);
            buttonAudio.Enabled = (_status == ConnectionStatus.Connected);
            buttonAudio.Checked = videoControl.PlayAudio;
            buttonExport.Enabled = (_status == ConnectionStatus.Connected);
            buttonSnapshot.Enabled = (_status == ConnectionStatus.Connected);
        }

        private string GetFullExceptionText(Exception ex)
        {
            var result = ex.Message;
            var innerEx = ex.InnerException;

            while (innerEx != null)
            {
                result += Environment.NewLine + innerEx.Message;
                innerEx = innerEx.InnerException;
            }

            return result;
        }

        private void ShowSequences()
        {
            var sequences = videoControl.Sequences;

            if (!sequences.AreItemsEqual(_sequences))
            {
                listSequences.Items.Clear();

                foreach (var sequence in sequences)
                {
                    listSequences.Items.Add(string.Format("{0} {1} - {2} {3}",
                        sequence.RecordStart.ToShortDateString(),
                        sequence.RecordStart.ToShortTimeString(),
                        sequence.RecordEnd.ToShortTimeString(),
                        sequence.Reason.ToShortUserString()));
                }

                _sequences = sequences;
            }
        }

        private void NavigateToSequence()
        {
            var index = listSequences.SelectedIndex;

            if (index != -1 && index < _sequences.Count)
            {
                var sequence = _sequences[index];
                videoControl.InitTime(videoControl.SelectedCameraID, sequence.RecordStart);
            }
        }

        private void buttonConnect_Click(object sender, EventArgs e)
        {
            if (_status == ConnectionStatus.Disconnected)
            {
                StartConnect(textServer.Text, textUser.Text, textPassword.Text);
            }
            else
            {
                CancelConnect();
            }
        }

        private void buttonCamera_Click(object sender, EventArgs e)
        {
            videoControl.SelectCamera();
        }

        private void buttonAudio_Click(object sender, EventArgs e)
        {
            videoControl.PlayAudio = buttonAudio.Checked;
        }

        private void buttonExport_Click(object sender, EventArgs e)
        {
            videoControl.ExportVideo();
        }

        private void buttonSnapshot_Click(object sender, EventArgs e)
        {
            try
            {
                using (var bitmap = videoControl.GetCurrentImageCopy())
                {
                    if (bitmap == null)
                    {
                        MessageBox.Show("Image is missing");
                        return;
                    }

                    var fileName = Path.Combine(
                        Directory.GetCurrentDirectory(),
                        string.Format("{0}.jpeg",
                            DateTime.Now.ToString("yyyy_MM_dd-HH-mm-ss", CultureInfo.InvariantCulture))
                    );

                    bitmap.Save(fileName, ImageFormat.Jpeg);

                    MessageBox.Show("Saved to " + fileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR: " + GetFullExceptionText(ex));
            }
        }

        private void videoControl_StateChanged(object sender, EventArgs e)
        {
            ShowSequences();
        }

        private void listSequences_DoubleClick(object sender, EventArgs e)
        {
            NavigateToSequence();
        }

        private void listSequences_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                NavigateToSequence();
            }
        }

        #endregion
        //----------------------------------------------------------------------------------------------------------------------------------------------------------------
    }
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
