using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using AForge.Video.DirectShow;
using TwoCamWPF.Helpers;
using System.Reflection;


namespace TwoCamWPF.Settings
{
    /// <summary>
    /// Логика взаимодействия для CamSettingsPage.xaml
    /// </summary>
    public partial class CamSettingsPage : UserControl
    {
        

        public CamSettingsPage()
        {
            InitializeComponent();
            Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Инициализация панели CameraSettingsModel");
      
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            ClassSettings settings=  Program.settings;
            settings.ReloadCamList();
            Log.LogClass.Enqueue(MethodBase.GetCurrentMethod(), "Установка настроек CameraSettingsModel");
            (this.DataContext as CameraSettingsModel).Update();
            
        }

    }




    class CameraSettingsModel : BaseViewModel<CamerasSettings>, ISavedBasedViewModel
    {

        public List<OneCameraSettingsModel> camerasModel
        {
            get;
            private set;

        }
        public CameraSettingsModel(CamerasSettings settings)
            : base(settings)
        {
            Update();
            settings.OnSave += (_) => Save();
            _bufSize = _settings.bufferSize;
       //     camerasModel = settings.Where(p => p.device != null).Select(p => new OneCameraSettingsModel(p)).ToList();
        }

        public void Update()
        {
            if (camerasModel != null)
                camerasModel.ForEach(p => p.Dispose());
            camerasModel = base._settings.Where(p => p.device != null).Select(p => new OneCameraSettingsModel(p)).ToList();
            
            RaisePropertyChanged("camerasModel");
        }

        public void Dispose()
        {
            if (camerasModel != null)
                camerasModel.ForEach(p => p.Dispose());
        }

        int _bufSize;

        void Save()
        {
            _settings.bufferSize = _bufSize;
        }

        public int bufSize
        {
            get
            {
                return _bufSize;
            }
            set
            {
                _bufSize = value;
                RaisePropertyChanged("bufSize");
            }

        }
    }


    class OneCameraSettingsModel : BaseViewModel<OneCameraSettings>, ISavedBasedViewModel
    {
 
        public OneCameraSettingsModel(OneCameraSettings settings): base(settings)
        {
            _IsUsing = _settings.IsUsing;
           
            if (_settings.IsUsing)
            {
                _settings.device.Subscribe(this, (bmp) =>
                {
                    Image = bmp.ToImageSource();
                });
                _Capability = _settings.Capability;
            }
            _StreamName = _settings.StreamName;
            _Codec = _settings.Codec;
            settings.OnSave += (_) => Save();
        }

        //Bitmap bmp1;
        bool _IsUsing;
        public bool IsUsing
        {
            get { return _IsUsing; }
            set
            {
                _IsUsing = value;
                if (value)
                    _settings.device.Subscribe(this, (bmp) => { 
                        //System.Windows.Media.ImageSource tmp = Image;
                       Image = bmp.ToImageSource(); 
                      //  if (tmp != null)
                        //    GC.Collect(GC.GetGeneration(tmp)+2); 
                    });
                    //_settings.device.Subscribe(this, (bmp) => {
                    //    if (bmp1 != null)
                    //    {
                    //        bmp1.Dispose();
                    //    }
                    //    bmp1 = (Bitmap)bmp.Clone();
                    //});
          //       _settings.device.Subscribe(this, (bmp) => {return;});
                else
                    _settings.device.Unsubscribe(this);
                RaisePropertyChanged("IsUsing");
            }
        }

        public string Name
        {
            get { return _settings.device.Name; }
        }


        string _StreamName;
        public string StreamName
        {
            get { return _StreamName; }
            set
            {
                _StreamName = value;
                RaisePropertyChanged("StreamName");
            }
        }

        public VideoCapabilities[] Capabilites
        {
            get
            {
                return _settings.Capabilites;
            }
        }


        VideoCapabilities _Capability;
        public VideoCapabilities Capability
        {
            get
            {
                return _Capability;
            }
            set
            {
                _Capability = value;
                RaisePropertyChanged("Capability");

            }
        }


        public string fps
        {
            get
            {
                return _settings.device.fps.ToString("#.00") + " fps";
            }

        }
        System.Windows.Media.ImageSource _Image;

        public System.Windows.Media.ImageSource Image
        {
            get
            {
                return _Image;
            }
            set
            {
                _Image = value;
                _Image.Freeze();
                RaisePropertyChanged("Image");
                RaisePropertyChanged("fps");
            }
        }


        public Helpers.CodecInfo[] Codecs
        {
            get
            {
                return Helpers.CodecInfo.CodecList;
            }
        }
        Helpers.CodecInfo _Codec;
        public Helpers.CodecInfo Codec
        {
            get { return _Codec; }
            set
            {
                _Codec = value;
                RaisePropertyChanged("Codec");
            }

        }

        void Save()
        {
            _settings.IsUsing = _IsUsing ;
            if (_Capability != null)
                _settings.Capability = _Capability;
            _settings.StreamName = _StreamName;
            _settings.Codec = _Codec;
        }

        public void Dispose()
        {
            _settings.device.Unsubscribe(this);
        //    _settings = null;
        }
    }
    
   
     

    

}
