# CellTracking.py
# By MW, Jun 2013
# GPLv3+
#
# Class representing a player state. 
import logging, cv2, imp, numpy
# Loading filters
Contrast = imp.load_source('contrast', './bin/Movies/Filters/Contrast.py')
contrast = Contrast.Contrast()
[docs]class Player_state :
    """Class containing all parameters required to run a player
    This class should only be instanciated inside a Player class"""
    def __init__(self, state) :
        self.state = state
        self.play = False
        self.current_frame_index = 0
        self.current_pos = (0,0)    # Position of the image inside the window.
        self.current_window = (0,0)    # Dimensions of the window
        self.current_channel = None
        self.current_zoom = 1
        self.current_speed = 1
        self.current_manual_mode = False
        self.speeds = (0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50)
        self.zooms = (0.1, 0.25, 0.5, 1, 2, 5, 10, 25)
        self.slow_play_index = 0
        self.current_click = None
        self.current_frame = None
        self.locked = False
        self.raw_frame = None # The image just coming from the file
        # Cell relative data (to move to a specific state)
        self.reference_size = 20
    #def set_current_channel(self, channel_name) :
    #    self.current_channel = channel_name
[docs]    def set_lock(self, lock) :
        self.locked = lock 
[docs]    def set_current_channel(self, ch_name) :
        """Replace the current channel. The input should be a channel name"""
        self.current_channel = ch_name 
[docs]    def get_current_channel(self) :
        return self.current_channel
 
[docs]    def set_current_speed(self, s) :
        """Input is a speed index"""
        if s in self.speeds :
            self.current_speed = s
        else :
            logging.error("Requested speed is not in the allowed speeds")
 
[docs]    def get_current_index(self) :
        return self.current_frame_index 
    def set_current_frame(self, im) :
        #if not self.locked :
        self.current_frame = im
        #else :
        #   logging.warning("Playing is locked, cannot change frame")
[docs]    def get_raw_frame(self) :
        """Read a frame from buffer"""
        if self.raw_frame != None :
            return self.raw_frame
        else :
            return self.read_raw_frame()
 
[docs]    def read_raw_frame(self, zoom=1) :
        """zoom parameter unused for the moment"""
        f = self.state.movie.get_frame(self.current_frame_index, self.current_channel)
        return cv2.resize(f, dsize=(int(f.shape[0]*self.current_zoom), int(f.shape[1]*self.current_zoom)))
        """Read a frame from file""" 
[docs]    def get_current_frame(self, zoom=1,depth=8) :
        if self.current_frame != None :
            f = self.current_frame
        else :
            f = self.read_raw_frame()
        #if zoom != 1 :
        #    f = cv2.resize(f, dsize=(int(f.shape[0]*self.current_zoom), int(f.shape[1]*self.current_zoom)))
        #    print f.shape
        if depth==8 :
            f=cv2.convertScaleAbs(f, alpha=0.4)
            f = f-numpy.min(f)#, beta=-1*numpy.min(f)) ### EXPERIMENTAL
        return f
 
[docs]    def set_current_frame(self, f) :
        self.current_frame = f
 
[docs]    def process_frame(self) :
        f = self.get_current_frame()
        #try : # Contrast
        c = self.state.get_subclass('contrast')
        f = contrast.overlay(f, contrast=c.current_contrast, auto=c.auto_contrast)
        #except :
        #    logging.error("An error occured in State_player when dealing with contrast")
        self.current_frame = f
        return f
 
[docs]    def set_pos(self, pos) :
        """Set the position of the image in the window
        The tuple gives the coordinates of the TOP-LEFT corner"""
        self.current_pos = (int(pos[0]), int(pos[1])) 
[docs]    def set_window(self, win) :
        """Sets the dimension of the display window (in px)"""
        self.current_window = (int(win[0]), int(win[1]))
 
[docs]    def change_playing(self, dest=None) :
        """Set the player to dest if specified, switch if not"""
        # Should check the type of dest...
        if dest == None :
            self.play = not self.play
        else :
            self.play = dest
        return self.play
 
[docs]    def switch_manual(self, dest=None) :
        """Function that swiches between automatic and manual playing"""
        if dest == None :
            self.current_manual_mode = not self.current_manual_mode
        else :
            self.current_manual_mode = dest
        return self.current_manual_mode
 
[docs]    def set_current_zoom(self, z) :
        if z in self.zooms :
            self.current_zoom = z
        else :
            logging.error("The specified zoom level is invalid")
 
[docs]    def get_current_zoom(self) :
        return self.current_zoom
 
[docs]    def set_current_frame_index(self, i) :
        """Sets the current frame"""
        if (i >= 0) and (i<self.state.get_frame_nb()) :
            if not self.locked:
                self.current_frame_index = i
            else :
                logging.warning('Playing is locked, cannot change frame')
        else :
            logging.error("set_current_frame_index() requested an invalid frame index: %s.", str(i)) 
[docs]    def set_image_click(self, tup) :
        """Event called when the image is clicked"""
        self.current_click = tup