from .modbus import Modbus, Command, DataType
from enum import auto, Enum, IntEnum

class AXES(Enum):
    RADOME = auto()
    ELEVATION = auto()
    AZIMUTH = auto()
    POLARIZATION = auto()
    
class POSITION_REGISTER_ADRESS(IntEnum):
    RADOME = 40021
    ELEVATION = 40067
    AZIMUTH = 40065
    POLARIZATION = 40019


class Srts200:
    def __init__(self, ip:str='10.0.0.238', port:int=4001, id:int=1):
        self.mbus = Modbus(ip, port, id)

    def close(self):
        self.mbus.close()

    def stop(self, axis:AXES=None) -> None:
        """Stop axis or all axis

        Parameters
        ----------
        axis : AXES
            Enumarated values with following assignments: AXES.RADOME=1, AXES.ELEVATION=2, AXES.AZIMUTH=3, AXES.POLARIZATION=4
        """
        if axis:
            command = None
            if axis == AXES.RADOME:
                command = Command.MOTOR_STOP_RAD
            elif axis == AXES.ELEVATION:
                command = Command.MOTOR_STOP_EL
            elif axis == AXES.AZIMUTH:
                command = Command.MOTOR_STOP_AZ
            elif axis == AXES.POLARIZATION:
                command = Command.MOTOR_STOP_POL
            else:
                raise Exception(ValueError, 'Axis index should be valid within range 1<->4')
            self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T) 
        else:
            command = Command.MOTOR_STOP_RAD
            self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T) 
            command = Command.MOTOR_STOP_EL
            self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T) 
            command = Command.MOTOR_STOP_AZ
            self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T) 
            command = Command.MOTOR_STOP_POL
            self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T) 
        self.mbus.write_holding_registers(40083, 100, DataType.INT32T) # '100' value obtained from manufacturer examples

    def position(self, axis: AXES) -> float:
        """Gets axis postion

        Parameters
        ----------
        axis : AXES
            Enumarated values with following assignments: AXES.RADOME=1, AXES.ELEVATION=2, AXES.AZIMUTH=3, AXES.POLARIZATION=4

        Returns
        -------
        float
            Current position value
        """
        pos = self.mbus.read_holding_register_s32(POSITION_REGISTER_ADRESS[axis.name])/1000
        if axis in [AXES.RADOME, AXES.ELEVATION, AXES.AZIMUTH]:
            return round(pos, 2)
        elif axis in [AXES.POLARIZATION]:
            return round(pos, 3)
        else:
            return pos

    def move(self, axis: AXES, target: float) -> None:
        """Move axis to desired position

        Parameters
        ----------
        axis : AXES
            Enumarated values with following assignments: AXES.RADOME=1, AXES.ELEVATION=2, AXES.AZIMUTH=3, AXES.POLARIZATION=4
        """
        self.mbus.write_holding_registers(40048, int(target*1000), DataType.INT32T)
        command = None
        if axis == AXES.RADOME:
            command = Command.MOTOR_GOTO_ANGLE_POS_RAD
        elif axis == AXES.ELEVATION:
            command = Command.MOTOR_GOTO_ANGLE_POS_EL
        elif axis == AXES.AZIMUTH:
            command = Command.MOTOR_GOTO_ANGLE_POS_AZ
        elif axis == AXES.POLARIZATION:
            command = Command.MOTOR_GOTO_ANGLE_POS_POL
        else:
            raise Exception(ValueError, 'Axis index should be valid within range 1<->4')
        self.mbus.write_holding_registers(40064, command.value, DataType.UINT16T)