using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;

using MVVM;

using sdkdef = YoseenPTZ.SDKDef;
using YoseenPTZ.ConfigDef;
using YoseenPTZ.CoreDef;
using System.Windows.Controls.Primitives;

namespace YoseenPTZ.ViewDef
{
    public partial class PTZView : UserControl
    {
        readonly PTZViewModel _vm;
        DeviceView _deviceView;
        public PTZView()
        {
            InitializeComponent();
            _vm = new PTZViewModel();

            //
            ptz_sliderSpeed.Value = _vm.ptzSpeed;
            ptz_sliderSpeed.ValueChanged += ptz_sliderSpeed_ValueChanged;
            this.DataContext = _vm;
        }

        public void SetDeviceView(DeviceView deviceView)
        {
            _deviceView = deviceView;
        }

        private void ptz_sliderSpeed_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _vm.ptzSpeed = (byte)ptz_sliderSpeed.Value;
        }

        private void ptz_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            int ret;
            int act = 0;
            int arg = _vm.ptzSpeed;
            Button btn = (sender as Button);
            string ptz = btn.Tag as string;
            switch (ptz)
            {
                case "Left":
                    act = (int)sdkdef.EPtzAction.MoveLeft;
                    break;
                case "Right":
                    act = (int)sdkdef.EPtzAction.MoveRight;
                    break;
                case "Up":
                    act = (int)sdkdef.EPtzAction.MoveUp;
                    break;
                case "Down":
                    act = (int)sdkdef.EPtzAction.MoveDown;
                    break;
                case "LeftUp":
                    act = (int)sdkdef.EPtzAction.MoveLeftUp;
                    break;
                case "RightUp":
                    act = (int)sdkdef.EPtzAction.MoveRightUp;
                    break;
                case "LeftDown":
                    act = (int)sdkdef.EPtzAction.MoveLeftDown;
                    break;
                case "RightDown":
                    act = (int)sdkdef.EPtzAction.MoveRightDown;
                    break;


                //
                case "ZoomOut":
                    act = (int)sdkdef.EPtzAction.ZoomOut;
                    break;
                case "ZoomIn":
                    act = (int)sdkdef.EPtzAction.ZoomIn;
                    break;

                case "FocusNear":
                    act = (int)sdkdef.EPtzAction.FocusNear;
                    break;
                case "FocusFar":
                    act = (int)sdkdef.EPtzAction.FocusFar;
                    break;

                case "IrisClose":
                    act = (int)sdkdef.EPtzAction.IrisClose;
                    break;
                case "IrisOpen":
                    act = (int)sdkdef.EPtzAction.IrisOpen;
                    break;

                //
                case "B160_Backlight":
                    act = (int)sdkdef.EPtzAction.PtzAction_B160_Backlight;
                    arg = _vm.backlight;
                    break;

                default:
                    goto error_handled;
            }

            //
            ret = _deviceView.PTZControlStart(act, arg);
            error_handled:
            e.Handled = true;
        }

        private void ptz_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            int ret;
            int act = 0;
            int arg = _vm.ptzSpeed;
            Button btn = (sender as Button);
            string ptz = btn.Tag as string;
            switch (ptz)
            {
                case "Left":
                    act = (int)sdkdef.EPtzAction.MoveLeft;
                    break;
                case "Right":
                    act = (int)sdkdef.EPtzAction.MoveRight;
                    break;
                case "Up":
                    act = (int)sdkdef.EPtzAction.MoveUp;
                    break;
                case "Down":
                    act = (int)sdkdef.EPtzAction.MoveDown;
                    break;
                case "LeftUp":
                    act = (int)sdkdef.EPtzAction.MoveLeftUp;
                    break;
                case "RightUp":
                    act = (int)sdkdef.EPtzAction.MoveRightUp;
                    break;
                case "LeftDown":
                    act = (int)sdkdef.EPtzAction.MoveLeftDown;
                    break;
                case "RightDown":
                    act = (int)sdkdef.EPtzAction.MoveRightDown;
                    break;


                //
                case "ZoomOut":
                    act = (int)sdkdef.EPtzAction.ZoomOut;
                    break;
                case "ZoomIn":
                    act = (int)sdkdef.EPtzAction.ZoomIn;
                    break;

                case "FocusNear":
                    act = (int)sdkdef.EPtzAction.FocusNear;
                    break;
                case "FocusFar":
                    act = (int)sdkdef.EPtzAction.FocusFar;
                    break;

                case "IrisClose":
                    act = (int)sdkdef.EPtzAction.IrisClose;
                    break;
                case "IrisOpen":
                    act = (int)sdkdef.EPtzAction.IrisOpen;
                    break;

                //
                default:
                    goto error_handled;
            }
            //
            ret = _deviceView.PTZControlStop(act, arg);
            error_handled:
            e.Handled = true;
        }

        private void ptzPower_Click(object sender, RoutedEventArgs e)
        {
            int ret;
            ToggleButton tb = e.OriginalSource as ToggleButton;
            string func = tb.Tag as string;
            int act = 0, arg = 0;
            bool on = tb.IsChecked.HasValue && tb.IsChecked.Value;
            switch (func)
            {
                //
                case "LightPower":
                    act = on ? (int)sdkdef.EPtzAction.SwitchLightPowerOn : (int)sdkdef.EPtzAction.SwitchLightPowerOff;
                    break;
                case "WiperPower":
                    act = on ? (int)sdkdef.EPtzAction.SwitchWiperPowerOn : (int)sdkdef.EPtzAction.SwitchWiperPowerOff;
                    break;

                //
                default:
                    return;
            }
            //
            ret = _deviceView.PTZControlStart(act, arg);
        }

        private void btnGetPtz_Click(object sender, RoutedEventArgs e)
        {
            //
            int p = 0, t = 0, z = 0;

            //
            grid.IsEnabled = false;
            Task task = Task.Factory.StartNew(() =>
            {
                int ret;
                ret = _deviceView.GetPTZ(ref p, ref t, ref z);
                return ret;
            }).ContinueWith(x =>
            {
                grid.IsEnabled = true;
                int ret = x.Result;
                sdkdef.PTZFlags flags = (sdkdef.PTZFlags)ret;
                if (flags.HasFlag(sdkdef.PTZFlags.PTZFlags_Pan))
                {
                    _vm.curP = p;
                }
                if (flags.HasFlag(sdkdef.PTZFlags.PTZFlags_Tilt))
                {
                    _vm.curT = t;
                }
                if (flags.HasFlag(sdkdef.PTZFlags.PTZFlags_Zoom))
                {
                    _vm.curZ = z;
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }

        private void btnSetPtz_Click(object sender, RoutedEventArgs e)
        {
            //
            int arg = _vm.ptzSpeed;
            int p, t, z;
            p = _vm.toP;
            t = _vm.toT;
            z = _vm.toZ;

            //
            grid.IsEnabled = false;
            Task task = Task.Factory.StartNew(() =>
            {
                int ret;
                ret = _deviceView.SetPTZ(p, t, z);
                return ret;
            }).ContinueWith(x =>
            {
                grid.IsEnabled = true;
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }

        private void btnPTZDebug_Click(object sender, RoutedEventArgs e)
        {
            DebugView.ShowView(_deviceView);
        }
        private void btnPreset_Click(object sender, RoutedEventArgs e)
        {
            PresetView.ShowView(_deviceView);
        }
        private void btnPresetRaw_Click(object sender, RoutedEventArgs e)
        {
            PresetRawView.ShowView(_deviceView);
        }
    }

    class PTZViewModel : BaseModel
    {
        int _curP;
        public int curP
        {
            get
            {
                return _curP;
            }
            set
            {
                if (value != _curP)
                {
                    _curP = value;
                    OnPropertyChanged("curP");
                }
            }
        }

        int _curT;
        public int curT
        {
            get
            {
                return _curT;
            }
            set
            {
                if (value != _curT)
                {
                    _curT = value;
                    OnPropertyChanged("curT");
                }
            }
        }

        int _curZ;
        public int curZ
        {
            get
            {
                return _curZ;
            }
            set
            {
                if (value != _curZ)
                {
                    _curZ = value;
                    OnPropertyChanged("curZ");
                }
            }
        }

        int _toP;
        public int toP
        {
            get
            {
                return _toP;
            }
            set
            {
                if (value != _toP)
                {
                    _toP = value;
                    OnPropertyChanged("toP");
                }
            }
        }

        int _toT;
        public int toT
        {
            get
            {
                return _toT;
            }
            set
            {
                if (value != _toT)
                {
                    _toT = value;
                    OnPropertyChanged("toT");
                }
            }
        }

        int _toZ;
        public int toZ
        {
            get
            {
                return _toZ;
            }
            set
            {
                if (value != _toZ)
                {
                    _toZ = value;
                    OnPropertyChanged("toZ");
                }
            }
        }

        int _ptzSpeed;
        public int ptzSpeed
        {
            get
            {
                return _ptzSpeed;
            }
            set
            {
                if (value != _ptzSpeed && value >= 0 && value <= 255)
                {
                    _ptzSpeed = value;
                    OnPropertyChanged("ptzSpeed");
                }
            }
        }


        int _backlight;
        public int backlight
        {
            get
            {
                return _backlight;
            }
            set
            {
                if (value != _backlight && value >= 0 && value <= 100)
                {
                    _backlight = value;
                    OnPropertyChanged("backlight");
                }
            }
        }


        public PTZViewModel()
        {
            _ptzSpeed = 50;
            _backlight = 50;
        }
    }
}
