using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace COMM
{
    public class Flag
    {
        public Boolean IsInit; //H/W설정이 안된경우에만 FALSE로 한다
        public string errorMessage;

        public int PortCount;
        private UInt64 _value;
        private UInt64 _changed;
        public string[] Name;

        public UInt64 Value { get { return _value; } }

        public event EventHandler<ValueEventArgs> ValueChanged;
        public class ValueEventArgs : EventArgs
        {
            private int _arridx;
            private Boolean _oldvalue;
            private Boolean _newvalue;

            public int ArrIDX { get { return _arridx; } }
            public Boolean OldValue { get { return _oldvalue; } }
            public Boolean NewValue { get { return _newvalue; } }

            public ValueEventArgs(int arridx, Boolean oldvalue, Boolean newvalue)
            {
                _arridx = arridx;
                _oldvalue = oldvalue;
                _newvalue = newvalue;
            }
        }

        public Flag(int pcnt)
        {
            if (pcnt > 64) throw new Exception("Max count is 64");
            PortCount = pcnt;
            IsInit = true;
            errorMessage = string.Empty;
            _value = 0;
            _changed = 0;
            Name = new string[PortCount];
            for (int i = 0; i < Name.Length; i++)
            {
                Name[i] = string.Empty;
            }
        }

        public void writeValue(Int16 val)
        {
            var NewValue = (ulong)val;
            _changed = this._value ^ NewValue;
            this._value = NewValue;
        }

        //private Boolean readValue(ref UInt64 value, int idx)
        //{
        //    var offset = (UInt64)(1 << idx);
        //    return ((value & offset) != 0);
        //}

        public Boolean Get(int idx)
        {
            var offset = (UInt64)(1 << idx);
            return (_value & offset) != 0;
        }

        /// <summary>
        /// 변경여부를 확인 합니다
        /// </summary>
        /// <param name="idx"></param>
        /// <returns></returns>
        public Boolean GetChanged(int idx)
        {
            var offset = (UInt64)(1 << idx);
            return (this._changed & offset) != 0;
        }

        public void Set(int idx, Boolean value)
        {
            var oldvalue = Get(idx);

            if (value)
            {
                var offset = (UInt64)(1 << idx);
                _value = _value | offset;
            }
            else
            {
                var offset = (UInt64)(~(1 << idx));
                _value = _value & offset;
            }

            if (oldvalue != value)
            {
                if (ValueChanged != null)
                    ValueChanged(this, new ValueEventArgs(idx, oldvalue, value));
            }
        }


    }
}
