using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using InputDevices;
using AForge.Video.DirectShow;
using TwoCamWPF.Helpers;
using System.Reflection;

namespace TwoCamWPF.Settings
{
    class CamerasSettings: List<OneCameraSettings> ,  ISubSettings
    {
        public int bufferSize
        {
            get;
            set;

        }


        public void Write(XmlWriter output)
        {

            Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Сохранение настроек камер");
      
            output.WriteStartElement("CamerasSettings", "");
            foreach (OneCameraSettings item in this)
            {
                if (!item.IsUsing)
                    continue;
                Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Сохранение настроек камеры " + item.device.Name);
             
                item.Write(output);

            }
            output.WriteElementString("bufferSize", bufferSize.ToString());
            
            output.WriteEndElement();
        }

        public void Load(XmlNode node)
        {
            Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Загрузка настроек камер");
            foreach (XmlNode child in node.ChildNodes)
            {
                if (child.Name == "Camera")
                {

                    OneCameraSettings camera = new OneCameraSettings(child.FirstChild.InnerText);// CamerasList.FirstOrDefault(p => p.MonikerString == child.FirstChild.InnerText);
                    camera.Load(child);
                    Add(camera);
                }
                else if (child.Name == "bufferSize") {
                    try
                    {
                        bufferSize = Convert.ToInt32(child.InnerText);
                    }
                    catch
                    {
                        Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Ошибка в размере буфера, неопознанная секция  " + child.InnerText);
                   
                    }
                } else 
                {
                    Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Ошибка в файле настроек, неопознанная секция  " + child.Name);
                    continue;
                }
                
            }
        }

        public void Save()
        {
            if (OnSave != null)
                OnSave(this);
            this.ForEach(p => p.Save());
        }

        public event Action<ISubSettings> OnSave;

        public CamerasSettings()
        {
            bufferSize = 20;
        }
    }

    class OneCameraSettings: ISubSettings
    {
        public string MonikerString
        {
            get;
            private set;
        }

        public string StreamName
        {
            get;
            set;

        }
        
        string _Capability;
        public VideoCapabilities Capability
        {
            get
            {
                return device.Capability;//.ToString();
            }
            set {
                device.Capability = value;// 
            }
        }

        public bool IsUsing
        {
            get;
            set;
        }

        VideoCapabilities GetCapability(string value)
        {
            VideoCapabilities result = device.VideoCapabilities.FirstOrDefault(p => p.ToString() == value, device.VideoCapabilities.FirstOrDefault());
           return result;
        }

        public VideoDeviceWatcher device  { get; private set; }
      
        public VideoCapabilities[] Capabilites
        {
            get { return device.VideoCapabilities; }
        }

        public Helpers.CodecInfo Codec
        {
            get;
            set;
        }

        public OneCameraSettings(string MonikerString)
        {
            this.MonikerString = MonikerString;
            IsUsing = false;
            Codec = Helpers.CodecInfo.CodecList.First();
        }

        public OneCameraSettings(VideoDeviceWatcher device): this(device.MonikerString)
        {
            AssignDevice(device);
            IsUsing = false;
        }

        public void AssignDevice(VideoDeviceWatcher device)
        {
            if (device.MonikerString != MonikerString)
                throw new Exception("Fail");
            this.device = device;
            device.Capability = GetCapability(_Capability);
            IsUsing = true;
            _Capability = device.Capability.ToString();
            if (StreamName == null)
                StreamName = device.Name;
        }

        public void Load(XmlNode node)
        {
            foreach (XmlNode onecamera in node.ChildNodes)
            {
                switch (onecamera.Name)
                {
                    case "Camera":
                        //if (StreamName == null)
                        //    StreamName = onecamera.InnerText;
                        break;
                    case "Capability":
                        _Capability = onecamera.InnerText;
                        break;
                    case "StreamName":
                        StreamName = onecamera.InnerText;
                        break;
                    case "Codec":
                        Codec = Helpers.CodecInfo.FromFCC(onecamera.InnerText);
                        break;
                }          
            }
        }

        public void Write(XmlWriter output)
        {
            output.WriteStartElement("Camera");
            output.WriteString(MonikerString);
          //  output.WriteElementString("Name", device.Name);
            output.WriteElementString("Capability", device.Capability.ToString());
            output.WriteElementString("StreamName", StreamName);
            if (Codec != null)
                output.WriteElementString("Codec", Codec.Fcc);
            output.WriteEndElement();
        }

        public void Save()
        {
            if (OnSave != null)
                OnSave(this);
        }

        public event Action<ISubSettings> OnSave;
    }
}
