""" DilSc prototype with Edwin's EPICS panels
"""

from slic.core.adjustable import Adjustable, PVAdjustable, Collection
from slic.core.device import Device, SimpleDevice
import time
import numpy as np

class Dilution(Device):
    def __init__(self, ID_DilSc_LakeShore, ID_DilSc_MagnetPSU, **kwargs):
        
        super().__init__(ID_DilSc_LakeShore,ID_DilSc_MagnetPSU, **kwargs)
        
        self.name = 'DilSc'
        self.ID_DilSc_LakeShore = ID_DilSc_LakeShore
        
        self.x = MagnetCoil(ID_DilSc_MagnetPSU, 'X', limit_low=-0.6, limit_high=0.6)
        self.y = MagnetCoil(ID_DilSc_MagnetPSU, 'Y', limit_low=-0.6, limit_high=0.6)
        self.z = MagnetCoil(ID_DilSc_MagnetPSU, 'Z', limit_low=-5.2, limit_high=5.2)
        
        self.T_CHA   = PVAdjustable(ID_DilSc_LakeShore + ":A_KELVIN")
        self.T_CH7   = PVAdjustable(ID_DilSc_LakeShore + ":7_KELVIN")
        self.T_CH8   = PVAdjustable(ID_DilSc_LakeShore + ":8_KELVIN")

        self.T_reg_setpoint  = PVAdjustable(ID_DilSc_LakeShore + ':H0_SETP_SET')

        self.heater = SimpleDevice('DilSc sample heater', p = PVAdjustable(ID_DilSc_LakeShore + ':H0_PID_P'),
                                    i = PVAdjustable(ID_DilSc_LakeShore + ':H0_PID_I'),
                                    d = PVAdjustable(ID_DilSc_LakeShore + ':H0_PID_D'),
        )

    def set_pids(self,P,I,D):
        self.heater.p.set_target_value(P)
        self.heater.i.set_target_value(I)
        self.heater.d.set_target_value(D)

        PVAdjustable(self.ID_DilSc_LakeShore +':H0_01_SEND.PROC').set_target_value(1)


class MagnetCoil(Adjustable):
    def __init__(self, ID, direction, limit_low, limit_high):
        
        super().__init__(ID, limit_low=limit_low, limit_high=limit_high)
        
        self.direction = direction    
        self.ID = self.name + '-' + self.direction

        if self.direction not in ["X", "Y", "Z"]:
            raise ValueError("Direction must be either X, Y or Z.")
        
        self.target    = PVAdjustable(self.ID+':SET_FSET')
        self.target_readback    = PVAdjustable(self.ID+':SIG_FSET')
        self.ramp_rate = PVAdjustable(self.ID+':SIG_RFST')
        self.done = PVAdjustable(self.ID+':FSET_FLAG')
        self.field_target_tolerance = 1e-3

    def set_target_value(self, value):
        self.target.set_target_value(value)
        PVAdjustable(self.ID+':ACTN_RTOS.PROC').set_target_value(1)

    def get_current_value(self):
        return PVAdjustable(self.ID+':SIG_FLD').get_current_value()
    
    def hold(self):
        return PVAdjustable(self.ID+':ACTN_HOLD.PROC').set_target_value(1)

    def press_to_setpoint(self):
        return PVAdjustable(self.ID+':ACTN_RTOS.PROC').set_target_value(1)

    #TODO: Bodge. There must be a better way..
    def is_moving(self):
        time.sleep(0.1)
        return abs( self.target.get_current_value() - self.get_current_value() ) > self.field_target_tolerance

    