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

namespace KMotion_dotNet
{
    public struct KM_MainStatus
    {
        #region Fields
        private int _VersionAndSize;
        private int[] _ADC;
        private int[] _DAC;
        private int[] _PWM;
        private double[] _Position;
        private double[] _Destination;
        private int[] _OutputChan0;

        private int _InputModes;
        private int _InputModes2;
        private int _OutputModes;
        private int _OutputModes2;
        private int _Enables;
        private int _AxisDone;

        private int[] _BitsDirection;
        private int[] _BitsState;

        private int _SnapBitsDirection0;
        private int _SnapBitsDirection1;

        private int _SnapBitsState0;
        private int _SnapBitsState1;

        private int _KanalogBitsStateInputs;
        private int _KanalogBitsStateOutputs;

        private int _RunOnStartUp;

        private int _ThreadActive;

        private int _StopImmediateState;

        private double _TimeStamp;

        private int[] _PC_comm;

        private int _VirtualBits;
        private int _VirtualBitsEx0; 



        private int _TicksAtUpdate; 
        #endregion

        #region Properties
        public int VersionAndSize
        {
            get
            {
                return _VersionAndSize;
            }
        }

        public int[] ADC
        {
            get
            {
                return _ADC;
            }
        }
        public int[] DAC
        {
            get
            {
                return _DAC;
            }
        }
        public int[] PWM
        {
            get
            {
                return _PWM;
            }
        }
        public double[] Position
        {
            get
            {
                return _Position;
            }
        }
        public double[] Destination
        {
            get
            {
                return _Destination;
            }
        }

        public int[] OutputChan0
        {
            get
            {
                return _OutputChan0;
            }
        }

        public int InputModes
        {
            get
            {
                return _InputModes;
            }
        }

        public int InputModes2
        {
            get
            {
                return _InputModes2;
            }
        }

        public int OutputModes
        {
            get
            {
                return _OutputModes;
            }
        }

        public int OutputModes2
        {
            get
            {
                return _OutputModes2;
            }
        }

        public int Enables
        {
            get
            {
                return _Enables;
            }
        }

        public int AxisDone
        {
            get
            {
                return _AxisDone;
            }
        }

        public int[] BitsDirection
        {
            get
            {
                return _BitsDirection;
            }
        }
        public int[] BitsState
        {
            get
            {
                return _BitsState;
            }
        }

        public int SnapBitsDirection0
        {
            get
            {
                return _SnapBitsDirection0;
            }
        }
        public int SnapBitsDirection1
        {
            get
            {
                return _SnapBitsDirection1;
            }
        }

        public int SnapBitsState0
        {
            get
            {
                return _SnapBitsState0;
            }
        }
        public int SnapBitsState1
        {
            get
            {
                return _SnapBitsState1;
            }
        }


        public int KanalogBitsStateInputs
        {
            get
            {
                return _KanalogBitsStateInputs;
            }
        }
        public int KanalogBitsStateOutputs
        {
            get
            {
                return _KanalogBitsStateOutputs;
            }
        }


        public int RunOnStartUp
        {
            get
            {
                return _RunOnStartUp;
            }
        }

        public int ThreadActive
        {
            get
            {
                return _ThreadActive;
            }
        }

        public int StopImmediateState
        {
            get
            {
                return _StopImmediateState;
            }
        }


        public double TimeStamp
        {
            get
            {
                return _TimeStamp;
            }
        }

        public int[] PC_comm
        {
            get
            {
                return _PC_comm;
            }
        }


        public int VirtualBits
        {
            get
            {
                return _VirtualBits;
            }
        }
        public int VirtualBitsEx0
        {
            get
            {
                return _VirtualBitsEx0;
            }
        } 

        public int TicksAtUpdate
        {
            get
            {
                return _TicksAtUpdate;
            }
        } 
        #endregion


        public int GetADC(int index)
        {
            if (index < _ADC.Length)
            {
                return _ADC[index];
            }
            else
            {
                return 0;
            }
        }
        public int GetDAC(int index)
        {
            if (index < _DAC.Length)
            {
                return _DAC[index];
            }
            else
            {
                return 0;
            }
        }
        public int GetPWM(int index)
        {
            if (index < _PWM.Length)
            {
                return _PWM[index];
            }
            else
            {
                return 0;
            }
        }


        public double GetPosition(int index)
        {
            if (index < _Position.Length)
            {
                return _Position[index];
            }
            else
            {
                return 0;
            }
        }
        public double GetDestination(int index)
        {
            if (index < _Destination.Length)
            {
                return _Destination[index];
            }
            else
            {
                return 0;
            }
        }

        public double GetOutputChannel0(int index)
        {
            if (index < _OutputChan0.Length)
            {
                return _OutputChan0[index];
            }
            else
            {
                return 0;
            }
        }


        public int GetInputMode(int axischannel)
        {
            int channel = FourBitAxisIndex(axischannel);
            if (axischannel > 3)
            {
                return GetValue(_InputModes, channel, 4);
            }
            else
            {
                return GetValue(_InputModes2, channel, 4);
            }
        } 
        public int GetOutputMode(int axischannel)
        {
            int channel = FourBitAxisIndex(axischannel);
            if (axischannel > 3)
            {
                return GetValue(_OutputModes, channel, 4);
            }
            else
            {
                return GetValue(_OutputModes2, channel, 4);
            }
        }
   
        public int GetAxisEnabled(int axischannel)
        {
            return GetValue(_Enables, axischannel, 1);
        }
        public int GetAxisComplete(int axischannel)
        {
            return GetValue(_AxisDone, axischannel, 1);
        }

        public int GetKFlopBitDirection(int index)
        {
            if (index > 31)
            {
                return GetValue(_BitsDirection[1], index - 31, 1);
            }
            else
            {
                return GetValue(_BitsDirection[0], index, 1);
            } 
        }

        public int GetKFlopBitState(int index)
        {
            if (index > 31)
            {
                return GetValue(_BitsState[1], index - 32, 1);
            }
            else
            {
                return GetValue(_BitsState[0], index, 1);
            }
        }


        public int GetSnapBitsDirection0(int index)
        {
            return GetValue(_SnapBitsDirection0, index, 1);
        }
        public int GetSnapBitsDirection1(int index)
        {
            return GetValue(_SnapBitsDirection1, index, 1);
        }

        public int GetSnapBitsState0(int index)
        {
            return GetValue(_SnapBitsState0, index, 1);
        }
        public int GetSnapBitsState1(int index)
        {
            return GetValue(_SnapBitsState1, index, 1);
        }



        public int GetKanalogBitsStateInputs(int index)
        {
            return GetValue(_KanalogBitsStateInputs, index, 1);
        }
        public int GetKanalogBitsStateOutputs(int index)
        {
            return GetValue(_KanalogBitsStateOutputs, index, 1);
        }

        public int GetRunOnStartUp(int index)
        {
            return GetValue(_RunOnStartUp, index, 1);
        }

        public int GetThreadActive(int index)
        {
            return GetValue(_ThreadActive, index, 1);
        }

   

        public int GetPC_comm(int index)
        {
            if (PC_comm.Length > index)
            {
                return PC_comm[index];
            }
            else
            {
                return 0;
            }
        }

        public int GetVirtualBits(int index)
        {
            return GetValue(_VirtualBits, index, 1);
        }
        public int GetVirtualBitsEx0(int index)
        {
            return GetValue(_VirtualBitsEx0, index, 1);
        }


        private int FourBitAxisIndex(int axischannel)
        {
            switch (axischannel)
            { 
                case 1:
                    return 4;
                case 2:
                    return 8;
                case 3:
                    return 12;
                case 4:
                    return 0;
                case 5:
                    return 4;
                case 6:
                    return 8;
                case 7:
                    return 12;
                default:
                    return 0;
            }
        }
        private int GetValue(int source, int start, int length)
        {
            return ((source >> start) & length);
        }

        #region Static Methods
        public static KM_MainStatus GetStatus
    (
    int versionandsize,
    int[] adc,
    int[] dac,
    int[] pwm,
    double[] position,
    double[] destination,
    int[] outputchan0,
    int inputmodes,
    int inputmodes2,
    int outputmodes,
    int outputmodes2,
    int enables,
    int axisdone,
    int[] bitsdirection,
    int[] bitsstate,
    int snapbitsdirection0,
    int snapbitsdirection1,
    int snapbitsstate0,
    int snapbitsstate1,
    int kanalgobitsstateinputs,
    int kanalogbitsstateoutputs,
    int runonstartup,
    int threadactive,
    int stopimmediatestate,
    double timestamp,
    int[] pccomm,
    int virtualbits,
    int virtualbitsex0
    )
        {
            KM_MainStatus retval = new KM_MainStatus();
            retval._VersionAndSize = versionandsize;
            retval._ADC = adc;
            retval._DAC = dac;
            retval._PWM = pwm;
            retval._Position = position;
            retval._Destination = destination;
            retval._OutputChan0 = outputchan0;
            retval._InputModes = inputmodes;
            retval._InputModes2 = inputmodes2;
            retval._OutputModes = outputmodes;
            retval._OutputModes2 = outputmodes2;
            retval._Enables = enables;
            retval._AxisDone = axisdone;
            retval._BitsDirection = bitsdirection;
            retval._BitsState = bitsstate;
            retval._SnapBitsDirection0 = snapbitsdirection0;
            retval._SnapBitsDirection1 = snapbitsdirection1;
            retval._SnapBitsState0 = snapbitsstate0;
            retval._SnapBitsState1 = snapbitsstate1;
            retval._KanalogBitsStateInputs = kanalgobitsstateinputs;
            retval._KanalogBitsStateOutputs = kanalogbitsstateoutputs;
            retval._RunOnStartUp = runonstartup;
            retval._ThreadActive = threadactive;
            retval._StopImmediateState = stopimmediatestate;
            retval._TimeStamp = timestamp;
            retval._PC_comm = pccomm;
            retval._VirtualBits = virtualbits;
            retval._VirtualBitsEx0 = virtualbitsex0;

            retval._TicksAtUpdate = Environment.TickCount;
            return retval;
        } 
        #endregion

        
    }
}
