//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.IO;
using System.Threading;
using Revisor.VMS;
using Revisor.VMS.ClientSDK;
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace ReceiveRealtimeExample
{
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /// <summary>
    /// This example demonstrates:
    ///   * how to connect to server remotely
    ///   * how to load camera list
    ///   * how to receive realtime video stream from camera
    ///   * how to decompress, transform and save frame to file
    /// </summary>
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
    class Program
    {
        static void Main(string[] args)
        {
            using (var connection = new ConnectionWrapper())
            {
                connection.Connect("localhost", 11012, "admin", "");
                Console.WriteLine("Connected.");

                var configuration = connection.GetConfiguration();
                Console.WriteLine("Got server configuration. Camera count: " + configuration.Cameras.Count);

                var camera = configuration.Cameras.Find(c => !c.Disabled);

                if (camera == null)
                {
                    Console.WriteLine("Cannot find any enabled cameras. Disconnecting..");
                }
                else
                {
                    Console.WriteLine("Found camera: " + camera.Name);
                    ReceiveRealtimeVideo(connection, camera);
                }
            }

            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }

        private static void ReceiveRealtimeVideo(ConnectionWrapper connection, Camera camera)
        {
            using (var lifeView = connection.CreateLifeView(camera, true, 30, false))
            {
                Console.WriteLine("Trying to receive frames. Press any key to terminate..");

                int frameCount = 0;
                bool isFirstFrame = true;

                while (!Console.KeyAvailable)
                {
                    var frame = lifeView.GetFrame();

                    if (frame == null)
                    {
                        Thread.Sleep(20);
                        continue;
                    }

                    Console.WriteLine("Received frame. Format: " + frame.Format.ToString() + ", size=" + frame.GetLength());
                    frameCount++;

                    if (isFirstFrame && TryExportFrame(frame))
                    {
                        isFirstFrame = false;
                        Console.WriteLine("The first full-picture frame is saved.");
                    }
                }

                Console.WriteLine("Total frames received: " + frameCount);
            }
        }

        private static bool TryExportFrame(Frame frame)
        {
            if (frame.CanInitializeSequence)
            {
                using (var decoder = new VideoDecoderWrapper())
                {
                    using (var decodedFrame = decoder.Decode(frame))
                    {
                        if (decodedFrame != null)
                        {
                            using (var renderer = new VideoRendererWrapper())
                            {
                                if (renderer.Render(decodedFrame, decodedFrame.Size, true))
                                {
                                    var jpegData = renderer.CompressRenderedToJpeg();
                                    File.WriteAllBytes("first_frame.jpeg", jpegData);

                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            return false;
        }
    }
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
