import ctypes

ICD1553_DL_POSITION_METERS_LSB = float(1/32767)
SCALER = 32767

class TargetPosition(ctypes.Structure):
    _fields_ = [("raw", ctypes.c_int16)]

    def get(self):
        """Return meters by default (preserves compatibility with callers that
        expect a physical value). Use `get_raw()` to obtain raw stored word.
        """
        return float(self.raw) * ICD1553_DL_POSITION_METERS_LSB

    def set(self, value):
        """Set position.

        - If `value` is an `int` it is treated as the raw 16-bit stored word.
        - Otherwise it is treated as meters and converted to the raw representation
          using the ICD LSB.

        The stored value is clamped to signed 16-bit range.
        """
        if isinstance(value, int):
            raw = int(value)
        else:
            # treat value as meters
            raw = int(round(float(value) / ICD1553_DL_POSITION_METERS_LSB))

        # clamp
        if raw < -32768:
            raw = -32768
        if raw > 32767:
            raw = 32767

        self.raw = ctypes.c_int16(raw).value

    def get_raw(self):
        """Return raw 16-bit stored value."""
        return int(self.raw)