namespace CtrEditor.ObjetosSim
{
    public static class VMMotorBitPacker
    {
        // Bit positions for StatusWord (bits 16-31)
        private const int STATUS_VFD_READY_BIT = 16;
        private const int MOTOR_RUNNING_BIT = 17;
        private const int STATUS_VFD_TRIP_BIT = 18;
        private const int STATUS_VFD_WARNING_BIT = 19;
        private const int STATUS_VFD_COASTING_BIT = 20;
        // Bits 21-31 reserved for future use
        // Bits 0-15 used for STATUS_VFD_ACT_Speed_Hz (16 bits)

        // Bit positions for ControlWord (bits 16-31)
        private const int OUT_RUN_BIT = 16;
        private const int OUT_STOP_BIT = 17;
        private const int OUT_RESET_ALARM_BIT = 18;
        private const int OUT_REVERSAL_BIT = 19;
        // Bits 20-31 reserved for future use
        // Bits 0-15 used for OUT_VFD_REQ_Speed_Hz (16 bits)

        public static int PackStatusWord(bool vfdReady, bool motorRunning, bool vfdTrip,
            bool vfdWarning, bool vfdCoasting, short actSpeedHz)
        {
            int result = actSpeedHz & 0xFFFF;  // Speed in lower 16 bits
            result |= (vfdReady ? 1 : 0) << STATUS_VFD_READY_BIT;
            result |= (motorRunning ? 1 : 0) << MOTOR_RUNNING_BIT;
            result |= (vfdTrip ? 1 : 0) << STATUS_VFD_TRIP_BIT;
            result |= (vfdWarning ? 1 : 0) << STATUS_VFD_WARNING_BIT;
            result |= (vfdCoasting ? 1 : 0) << STATUS_VFD_COASTING_BIT;
            return result;
        }

        public static int PackControlWord(bool run, bool stop, bool resetAlarm,
            bool reversal, short reqSpeedHz)
        {
            int result = reqSpeedHz & 0xFFFF;  // Speed in lower 16 bits
            result |= (run ? 1 : 0) << OUT_RUN_BIT;
            result |= (stop ? 1 : 0) << OUT_STOP_BIT;
            result |= (resetAlarm ? 1 : 0) << OUT_RESET_ALARM_BIT;
            result |= (reversal ? 1 : 0) << OUT_REVERSAL_BIT;
            return result;
        }

        public static (bool vfdReady, bool motorRunning, bool vfdTrip, bool vfdWarning,
            bool vfdCoasting, short actSpeedHz) UnpackStatusWord(int statusWord)
        {
            return (
                ((statusWord >> STATUS_VFD_READY_BIT) & 1) == 1,
                ((statusWord >> MOTOR_RUNNING_BIT) & 1) == 1,
                ((statusWord >> STATUS_VFD_TRIP_BIT) & 1) == 1,
                ((statusWord >> STATUS_VFD_WARNING_BIT) & 1) == 1,
                ((statusWord >> STATUS_VFD_COASTING_BIT) & 1) == 1,
                (short)(statusWord & 0xFFFF)
            );
        }

        public static (bool run, bool stop, bool resetAlarm, bool reversal, short reqSpeedHz)
            UnpackControlWord(int controlWord)
        {
            return (
                ((controlWord >> OUT_RUN_BIT) & 1) == 1,
                ((controlWord >> OUT_STOP_BIT) & 1) == 1,
                ((controlWord >> OUT_RESET_ALARM_BIT) & 1) == 1,
                ((controlWord >> OUT_REVERSAL_BIT) & 1) == 1,
                (short)(controlWord & 0xFFFF)
            );
        }
    }
}
