//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using

using Framefield.Core;
using Framefield.Core.Inputs;


namespace Framefield.Core.ID5efe8985_1194_4dc2_aff0_7b904c04ba43
{
    public class Class_HidInput : OperatorPart.Function, Framefield.Core.OperatorPartTraits.IAsyncDependend
    {
        public bool AsyncChanged { get { return _asyncChanged; } }

        //>>> _inputids
        private enum InputId
        {
            TeachTrigger = 0,
            ElementID = 1
        }
        //<<< _inputids 

        public Class_HidInput()
        {
            Input.Hid.HidInputEvent += HandleHidInputEvent;
        }
        public override void Dispose()
        {
            Input.Hid.HidInputEvent -= HandleHidInputEvent;
        }

        void HandleHidInputEvent(object o, HidInput.HidEventArgs e)
        {
            _lastEventArgs = e;
            _asyncChanged = true;
        }
         
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)
        {
            //>>> _params
            var TeachTrigger = inputs[(int)InputId.TeachTrigger].Eval(context).Value;
            var ElementID = inputs[(int)InputId.ElementID].Eval(context).Text;
            //<<< _params

            _asyncChanged = false;

            bool teachTriggerFlankUp = _oldTeachTrigger < 0.5f && TeachTrigger > 0.5f;
            _oldTeachTrigger = TeachTrigger;
            if (teachTriggerFlankUp)
            {
                Logger.Info(this, "teaching mode active");
                _teachingActive = true;
                _lastEventArgs = null;
                _dataIDHistory.Clear();
            }

            if (_lastEventArgs == null)
            {
                context.Value = 0;
                return context;
            }

            long receivedDataID = ConvertByteArrayToLong(_lastEventArgs.RawData);

            if (_teachingActive)
            {
                if (!_dataIDHistory.Contains(receivedDataID))
                    _dataIDHistory.Add(receivedDataID);
                if (_dataIDHistory.Count == 2)
                {
                    long pressID = _dataIDHistory[0];
                    long noPressID = _dataIDHistory[1];
                    long valID = pressID & ~noPressID;

                    String valIDAsString = String.Format("{0:X}", valID);
                    inputs[(int)InputId.ElementID].Func = Utilities.CreateValueFunction(new Text(valIDAsString));
                    context.Value = 0;
                    Logger.Info(this, "teached finished with {0:X}", valID);
                    _dataIDHistory.Clear();
                    _teachingActive = false;
                }
            }
            else
            {
                long elementIDLong = ConvertHexStringToLong(ElementID);
                context.Value = (receivedDataID & elementIDLong) != 0 ? 1 : 0;
            }

            return context;
        }

        long ConvertByteArrayToLong(byte[] data)
        {
            if (data == null)
                return 0;

            String hexStr = BitConverter.ToString(data).Replace("-", "");
            return long.Parse(hexStr, System.Globalization.NumberStyles.AllowHexSpecifier);
        }

        long ConvertHexStringToLong(String hexStr)
        {
            if (String.IsNullOrEmpty(hexStr))
                return 0;

            return long.Parse(hexStr, System.Globalization.NumberStyles.AllowHexSpecifier);
        }


        bool _asyncChanged = false;
        float _oldTeachTrigger;
        bool _teachingActive;
        HidInput.HidEventArgs _lastEventArgs = null;
        List<long> _dataIDHistory = new List<long>();
    }

}

