from subsystems import Subsystem, decode
import logging
import time

#class Camera(Subsystem):
#    expected_params = {'SHUTTER': 'Open',
#                       'FILTER': 'IDLE',
#                       'EXPTIME': 0.1}
#    def _config(self):
#        self.band_names = {}
#        self.filter_wait = self.config.FILTER_CHANGE_DELAY
#        for i in range(1,6):
#            self.band_names[i] = getattr(self.config,'POS_%d' % (i-1))
#        self.band_pos = dict(list(zip(list(self.band_names.values()), list(self.band_names.keys()))))
#        self.field_center = 382,  255
#        self.set_filter('Bi')
#        
#    def set_filter(self, band_name):
#        try:
#            band_pos = self.band_pos[band_name]
#        except KeyError:
#            logging.error('Unknown band name. Available filters: ' + str(list(self.band_pos.keys())))
#            return
#
#        logging.info("Setting filter to : " + band_name + "[" + str(band_pos) + "]")
#
#        if(self.server.set_filter(band_pos) != True):
#            logging.error("Could not set filter")
#        else:
#            self._filt_pos = band_pos
#        time.sleep(self.filter_wait)
#        
#    def get_filter(self, check=False):
#        if check:
#            self._filt_pos = self.server.get_filter()
#
#        if(self._filt_pos == -1):
#            return "unknown"
#        else:
#            try:
#                return self.band_names[self._filt_pos]
#            except KeyError:
#                return "outbound"
#
#    
#    def image(self, texp, auto_freeze=True, open_shutter=True):
#        """
#        Take an image on the sbig camera. 
#        """
#        logging.info("Taking image for " + str(texp) + "s")
#        I = self.server.exposure(texp, open_shutter, auto_freeze)
#                    
#        # decode the binary data 
#        I=decode(I)
#        I['FILTPOS'] = self.server.get_filter()    
#        I['FILTER'] = self.band_names[I['FILTPOS']]
#        return I
#
#    def freeze_cooling_power(self):
#        if(self.server.set_temperature(6, 0) != True):
#            logging.error("Could not disable autofreeze")
#        if(self.server.set_temperature(3, 0) != True):
#            logging.error("Could not freeze cooling power")
#        return True
#    
#    def unfreeze_cooling_power(self):
#        if(self.server.set_temperature(4, 0) != True):
#            logging.error("Could not freeze cooling power")
#        if(self.server.set_temperature(5, 0) != True):
#            logging.error("Could not reenable autofreeze")
#        return True
#    
#    def take_patch(self, texp, frame=[0, 0, 0, 0], mode=0):
#        """
#        Take an image on the sbig camera. 
#        """
#        #try:
#        #logging.info("Taking framed image for " + str(texp) + "s")
#        self.freeze_cooling_power()
#        I = self.server.take_patch(frame[0], frame[1], frame[2], frame[3], texp, mode)
#        self.unfreeze_cooling_power()
#        I = decode(I)
#        I['FILTPOS'] = self.server.get_filter()
#        I['FILTER'] = self.band_names[I['FILTPOS']]
#        return I
#
#    # Highest level functions
#    def before_exposure(self, exposure, fitsbuilder):
#        band = exposure['sbig.FILTER']
#        if band == 'IDLE':
#            band = self.get_filter()
#        fitsbuilder.append({'FILTER': band})
#        self.set_filter(band)
#
#    def exposure(self, exposure, fitsbuilder):
#        #servers.camera.freeze_cooling_power()
#        open_shutter =  exposure['sbig.SHUTTER'] == 'Open'
#        if exposure['sbig.EXPTIME'] == 'BULK':
#            self.server.start_exposure(300, auto_freeze=True, open_shutter=open_shutter)
#        else:
#            image = self.image(
#                float(exposure['sbig.EXPTIME']),
#                auto_freeze=True, open_shutter=open_shutter)
#            fitsbuilder.add_image(image)
#            
#    def after_exposure(self, exposure, fitsbuilder):
#        if exposure['sbig.EXPTIME'] == 'BULK':
#            I=decode(self.server.stop_exposure(I))
#            I['FILTPOS'] = self.server.get_filter()    
#            I['FILTER'] = self.band_names[I['FILTPOS']]
#            fitsbuilder.add_image(I)
#            
#    def status(self):
#        return {
#            'FILTER': self.get_filter(),
#        }
#
class SBIG(Subsystem):
    expected_params = {'SHUTTER': 'Open',
                       'EXPTIME': 0.1,
                       'filter': 'IDLE'}
    tracked_properties = ['filter']
    
    def _config(self):
        self.field_center = 382,  255
        self.band_names = {}
        self.filter_wait = self.config.FILTER_CHANGE_DELAY
        for i in range(1,6):
            self.band_names[i] = getattr(self.config,'POS_%d' % (i-1))
        self.band_pos = dict(list(zip(list(self.band_names.values()), list(self.band_names.keys()))))

    def sync_tracked_properties(self):
        filt_pos = self.server.get_filter()
        if filt_pos == -1:
            self.set_filter(self.band_names[1])
            return self.band_names[1]
        self._filter = self.band_names[self.server.get_filter()]
        
    def set_filter(self, band_name):
        if band_name == 'IDLE':
            return self._filter
        try:
            band_pos = self.band_pos[band_name]
        except KeyError:
            logging.error('Unknown band name. Available filters: ' + str(list(self.band_pos.keys())))
            return

        logging.info("Setting filter to : " + band_name + "[" + str(band_pos) + "]")

        if(self.server.set_filter(band_pos) != True):
            logging.error("Could not set filter")
        else:
            self._filter = band_name
        time.sleep(self.filter_wait)
        return self._filter
    
    def image(self, texp, auto_freeze=True, open_shutter=True):
        """
        Take an image on the sbig camera. 
        """
        logging.info("Taking image for " + str(texp) + "s")
        I = self.server.exposure(texp, open_shutter, auto_freeze)
                    
        # decode the binary data 
        I=decode(I)
        return I

    def photodiode(self, texp):
        i = self.image(texp)
        return i['pixels'].sum()
    
    def freeze_cooling_power(self):
        if(self.server.set_temperature(6, 0) != True):
            logging.error("Could not disable autofreeze")
        if(self.server.set_temperature(3, 0) != True):
            logging.error("Could not freeze cooling power")
        return True
    
    def unfreeze_cooling_power(self):
        if(self.server.set_temperature(4, 0) != True):
            logging.error("Could not freeze cooling power")
        if(self.server.set_temperature(5, 0) != True):
            logging.error("Could not reenable autofreeze")
        return True
    
    def take_patch(self, texp, frame=[0, 0, 0, 0], mode=0):
        """
        Take an image on the sbig camera. 
        """
        #try:
        #logging.info("Taking framed image for " + str(texp) + "s")
        I = self.server.take_patch(frame[0], frame[1], frame[2], frame[3], texp, mode)
        I = decode(I)
        return I

    # Highest level functions
    #def before_exposure(self, exposure, fitsbuilder):
    #    fitsbuilder.append({'FILTER': 'EMPTY'})

    def exposure(self, exposure, fitsbuilder):
        #servers.camera.freeze_cooling_power()
        open_shutter =  exposure['sbig.SHUTTER'] == 'Open'
        if exposure['sbig.EXPTIME'] == 'BULK':
            self.server.start_exposure(300, open_shutter, True)
        else:
            image = self.image(
                float(exposure['sbig.EXPTIME']),
                auto_freeze=True, open_shutter=open_shutter)
            fitsbuilder.add_image(image)

    def after_exposure(self, exposure, fitsbuilder):
        if exposure['sbig.EXPTIME'] == 'BULK':
            I=decode(self.server.stop_exposure())
            I['FILTPOS'] = self.server.get_filter()    
            I['FILTER'] = self.band_names[I['FILTPOS']]
            fitsbuilder.add_image(I)
    #def status(self):
    #    return {
    #        'FILTER': 'EMPTY',
    #    }
