from types import SimpleNamespace
from time import sleep
import numpy as np

from slic.core.adjustable import Adjustable, PVAdjustable, PVEnumAdjustable
from slic.core.adjustable.pvchangemon import PVChangeMonitor
from slic.core.device import Device
from slic.utils.hastyepics import get_pv as PV
from slic.devices.general.motor import Motor
from slic.devices.cameras import CameraCA

class CristallinaMono(Device):
    """Cristallina mono SAROP31-ODCC110"""
    def __init__(self, ID, name="Cristallina double-channel-cut monochromator", **kwargs):
        super().__init__(ID, name=name, **kwargs)

        self.TX             = Motor(ID + ":MOT_TX1")
        self.bragg1         = Motor(ID + ":MOT_RX1")
        self.bragg2         = Motor(ID + ":MOT_RX2")
        self.energy         = Motor(ID + ":MOT_ENY")
        self.energy_offset  = Motor(ID + ":MOT_OFS")
        self.screen = CristallinaMonoScreen("SAROP31-PSCR110", name='SAROP31-PSCR110')

class CristallinaMonoScreen(Device):

    def __init__(self, ID, name="Profile Monitor", **kwargs):
        super().__init__(ID, name=name, **kwargs)

        self.cam = CameraCA(ID)

        self.target = PVEnumAdjustable(ID + ":SCR_SP", name="target")
        self.target_pos = Motor(ID + ":MOT_TY1", name="target position")
        self.target_in_position = PVEnumAdjustable(ID + ":IN_POS",name="target in valid position")

    def move_mono(self):
        return self.target.set_target_value(1)
    
    def move_pink(self):
        return self.target.set_target_value(2)

    def move_out(self):
        return self.target.set_target_value(0)
    
    


# class DoubleCrystalMonoEnergy(Adjustable):

#     def __init__(self, ID, name=None):
#         self.wait_time = 0.1

#         pvname_setvalue = "SAROP21-ARAMIS:ENERGY_SP"
#         pvname_readback = "SAROP21-ARAMIS:ENERGY"
#         pvname_moving   = "SAROP21-ODCM098:MOVING"
#         pvname_stop     = "SAROP21-ODCM098:STOP.PROC"

#         pv_setvalue = PV(pvname_setvalue)
#         pv_readback = PV(pvname_readback)
#         pv_moving   = PV(pvname_moving)
#         pv_stop     = PV(pvname_stop)

#         units = pv_readback.units
#         super().__init__(ID, name=name, units=units)

#         self.pvnames = SimpleNamespace(
#             setvalue = pvname_setvalue,
#             readback = pvname_readback,
#             moving   = pvname_moving,
#             stop     = pvname_stop
#         )

#         self.pvs = SimpleNamespace(
#             setvalue = pv_setvalue,
#             readback = pv_readback,
#             moving   = pv_moving,
#             stop     = pv_stop
#         )


#     def get_current_value(self):
#         return self.pvs.readback.get()

#     def set_current_value(self, value):
#         self.pvs.setvalue.put(value)
#         sleep(3)

#     def set_target_value(self, value):
#         self.set_current_value(value)
# #        while abs(self.wait_for_valid_value() - value) > accuracy:
#         while self.is_moving():
#             sleep(self.wait_time)


#     def wait_for_valid_value(self):
#         val = np.nan
#         while not np.isfinite(val):
#             val = self.get_current_value()
#         return val

#     def is_moving(self):
#         moving = self.pvs.moving.get()
#         return bool(moving)

#     def stop(self):
#         self.pvs.stop.put(1)