from subsystems import Subsystem
import logging
import stardice.qla

class Analysis(Subsystem):
    def _late_config(self):
        self.targets = self.scheduler.mount.targets
        self.sky_model = self.targets.sky_model
        self.fake_instrument = self.targets.fake_instrument
    
    def analyse_image(self, fname, force=False):
        ''' Run the quick look and astrometric match on image fname
        '''
        logging.info('Analysing ' + fname)
        im, self.C2, skylev, skyvar = stardice.qla.reduce_image(fname)
        logging.info('Performing astrometry')
        try:
            self.w = stardice.qla.astrometry(self.C2, radec=[self.scheduler.mount._last_ra, self.scheduler.mount._last_dec])
#            self.w = stardice.qla.astrometry(self.C2)
        except:
            logging.warning('Fast astrometry failed, attempting exhaustive search')
            self.w = None
        if self.w is None:
            try:
                self.w = stardice.qla.astrometry(self.C2)
            except:
                logging.warning('exhaustive astrometry failed, using mount wcs')
                self.w = None
        if self.w is None:
            #try:
            logging.warning('calling mount wcs')
            self.w = self.scheduler.mount.get_wcs()
            #except Exception as e:
            #    logging.warning(e)
        print((self.w))
        self.fra, self.fdec = stardice.qla.field_center(self.w)
        logging.info('Center of field in %f, %f' % (self.fra, self.fdec))
        if len(self.C2.secat):
            self.ra, self.dec = stardice.qla.radec_catalog(self.w, self.C2)
            self.index = stardice.qla.assoc_calspec(self.ra, self.dec)
        dra, ddec = self.scheduler.mount._last_ra - self.fra, self.scheduler.mount._last_dec - self.fdec
#        logging.info('Offset between mount and sky: %f, %f' % (dra, ddec))
        return self.fra, self.fdec, dra, ddec

    def star_list(self):
        cat = self.sky_model.get_source_list(self.scheduler.mount._last_ra, self.scheduler.mount._last_dec)
        flux = self.fake_instrument.compute_flux(cat)
        return cat, flux

    def target_plots(self):
        ''' Plot airmass trajectory of readily observables target of interest
        ''' 
        return 'Readily observable: ' + ', '.join(self.scheduler.mount.targets.trajectory_plots(self.scheduler.mount.observer))
        
    def status(self):
        return {}

    def post_proc(self, exposure, filename, imager):
        if exposure['ANALYSIS'] == 'Acquisition':
            fra, fdec, dra, ddec = 0,0,0,0

            #- If target is a known calspec, tells us about the pointing offset
            target_name = exposure["TARGET"]
            target_ra = 0
            target_dec = 0
            self.scheduler.mount.sync_obs()
            #try:
            fra, fdec, dra, ddec = self.analyse_image(filename)
            #except:
            #logging.warning('astrometric resolution of the image failed')
            #logging.warning('Automatic offset not available')
            w = self.w
            imager.d.set('wcs append', w.to_header_string())

            target_offset_ra = 0
            target_offset_dec = 0
            
            if target_name in stardice.qla.calspecs["CALSPEC_NAME"]:
                i_ok = stardice.qla.calspecs["CALSPEC_NAME"] == target_name
                nt_tmp = stardice.qla.calspecs[i_ok]
                
                if len(nt_tmp) > 0:
                    target_ra = nt_tmp["RA"][0]
                    target_dec = nt_tmp["DEC"][0]
                    logging.info("Calspec target at %f, %f" % (target_ra, target_dec))            
                    field_ra = 0.26 #- degrees
                    field_dec = 0.39
                    target_offset_ra = target_ra-fra
                    target_offset_dec = target_dec-fdec
                    logging.info("Offset between target and center of field is  %f deg, %f deg" % (target_offset_ra, target_offset_dec))
                    logging.info("Field size is %f deg x %f deg" % (field_ra, field_dec))
                    #- Plot the coordinates of the center of the field and the target
                    #            w = self.scheduler.mount.get_wcs() #+ SZF: this wcs is from the mount, and has nothing to do with the image we just observed
            

                    imager.d.set('regions', "fk5;global color=red; boxcircle point %f %f" % (target_ra, target_dec))
                    imager.d.set('regions', "fk5;global color=green; boxcircle point %f %f" % (fra, fdec))                                        
            #try:
            #    tra, tdec, talt, taz = self.targets.get_target_radec(exposure['TARGET'], self.scheduler.mount.observer)
            #except KeyError:
            #    try:
            #        tra, tdec, talt, taz = float(exposure['RADEG']), float(exposure['DECDEG']), 0, 0
            #    except ValueError:
            #        tra, tdec, talt, taz = 0, 0, 0, 0

            #+if tra:
            #+    imager.d.set('regions', "fk5;global color=red; boxcircle point %f %f" % (tra, tdec))
            #+ SZF end: fin du bloc cherchant localiser le target
            confirm = ask('Accept image (y/n)?')
            if confirm == 'y':
                logging.info('Acquisition image accepted.')
                return True
            else:
                #+ SZF: I think that the offset to apply should be the one between the field center and the target coordinates
                dra = target_offset_ra
                ddec = target_offset_dec
                confirm = ask('Apply the automatic (%f, %f) offset or select a manual offset ((A)uto/(M)anual/(N)o)?' % (dra, ddec),
                              answers=['A', 'M', 'N'])
                if confirm == 'A':
                    logging.info('Applying the automatic (%f, %f) offset' % (dra, ddec))
                    #self.scheduler.mount.goto_radec(self.scheduler.mount._last_ra + dra, self.scheduler.mount._last_dec + ddec)
                    self.scheduler.mount.delta_ha += dra
                    self.scheduler.mount.delta_dec += ddec
                    #exposure['RADEG'] = 'IDLE'
                elif confirm == 'M':
                    logging.info('Selecting a manual offset')
                    ra, dec = imager.select_center()
                    rac, decc = stardice.qla.field_center(self.w)
                    #delta_ra = (ra - rac) * 3600
                    #delta_dec = (dec - decc) * 3600
                    delta_ra = (ra - rac)
                    delta_dec = (dec - decc)
                    self.scheduler.mount.delta_ha += delta_ra
                    self.scheduler.mount.delta_dec += delta_dec
                    #self.scheduler.mount.relative_move_radec(delta_ra, delta_dec)
                    #exposure['RADEG'] = 'IDLE'
                confirm = ask('Change focus ? (y/n)')
                if confirm == 'y':
                    #print '\a'
                    confirm = eval(input('Current focus offset is %s, enter new offset (invalid int to cancel):' % str(exposure['FOCOFFSET'])))
                    try:
                        exposure['FOCOFFSET'] = int(confirm)
                        logging.info('New offset %d' % int(confirm))
                    except:
                        logging.info('Improper value. Keep current offset %s.' % str(exposure['FOCOFFSET']))
                
                return False
        elif exposure['ANALYSIS'] == 'None':
            return True
