# FocusDisplay.py : Panel for focusing the microscope
#
# Distributed under the terms described in the LICENCE file.
#
# Developed by akuchlin@mems-exchange.org
#
# Currently doesn't really do anything; I don't know what the user interface
# for focusing should look like.

__revision__ = "$Id: FocusDisplay.py,v 1.20.2.1 2002/02/26 17:34:50 akuchlin Exp $"

from java import awt
import gui_util
from java import lang
import SimpleBorder

import time, string

class FocusThread(lang.Thread):
    def __init__ (self, focus_disp):
        self.focus_disp = focus_disp
        
    def run (self):
        while 1:
            lang.Thread.sleep(1000)
            if time.time() - self.focus_disp.timestamp > 1:
                # There's been no activity for an entire second, so
                # proceed with the Z movement.
                fd = self.focus_disp
                fd.client.move(z = fd.z_delta)
                self.focus_disp.af_button.setEnabled(1)
                self.focus_disp.set_subthread(None)
                break
        
class FocusDisplay (SimpleBorder, awt.event.AdjustmentListener,
                    awt.event.ActionListener):
    def __init__ (self, client = None):
	awt.Panel.__init__(self)

        self.client = client

        self.set_subthread(None)
        self.timestamp = 0
        
	self.setLayout(awt.GridBagLayout())
        self.z_delta = 0   # Currently set displacement in microns
        self.unit = 1      # Map microns to ticks on the slider 
        self.last_mag = -1 # Last magnification setting
        
        # Create autofocus status label
        self.af_status = awt.Label('Autofocus is On')
        gui_util.constrain(self, self.af_status, 0,0, 1,1)
        
        # Create the scrollbar for setting the height of the stage
        sb = self.scrollbar = awt.Scrollbar( awt.Scrollbar.VERTICAL,
                                         0, 2, -50, 50)
        gui_util.constrain(self, sb, 1,2, 1,4,
                  awt.GridBagConstraints.VERTICAL)
        sb.addAdjustmentListener(self)
        
        # Create labels that will go next to the scrollbar
        self.top_label = awt.Label("+50um") 
        gui_util.constrain(self, self.top_label, 0,2, 1,1)

        gui_util.constrain(self, awt.Label("Current:"), 0,3, 1,1)
        self.text_label = awt.Label("  0um")
        gui_util.constrain(self, self.text_label, 0,4, 1,1)

        self.bottom_label = awt.Label("-50um")
        gui_util.constrain(self, self.bottom_label, 0,5, 1,1)

        # Create button for enabling the autofocus 
        self.af_button = awt.Button('Use Autofocus')
        self.af_button.addActionListener(self)
        self.af_button.setActionCommand("autofocus")
        gui_util.constrain(self, self.af_button, 0,6, 2,1)
        
    def close (self):
        global _created
        self.hide()
        self.dispose()
        _created = None

    def set_subthread (self, subt):
        # XXX to avoid a race condition, this should be a
        # synchronized method!
        self.subt = subt

    def get_subthread (self):
        return self.subt 

    def set_value (self, value):
        val = int(value)
        self.z_delta = val * self.unit
        s = str(round(self.z_delta,2))
        self.text_label.setText(string.rjust(s,3) + "um")
        
    def update_status (self):
        # Update the current setting of the Z-axis display; this is *only*
        # ever called from the cmd_scope() handler.
        
        mag = self.client.image_disp.mag
        if mag != self.last_mag:
            if mag == 5: self.unit = 1.0
            elif mag == 10: self.unit = 1.0
            elif mag == 20: self.unit = .5
            elif mag == 50: self.unit = .1
            elif mag == 100: self.unit = .1
            top = string.rjust(str(50*self.unit),2) + "um"
            self.top_label.setText(top)
            self.bottom_label.setText('-' + top)
                
        z_autofocus = self.client.image_disp.z_autofocus
        z_current = self.client.image_disp.zpos
        delta = z_current
        delta = delta / self.unit
        delta = round(delta)
        if delta<-50: delta=-50
        elif delta>50: delta=50
        delta = int(delta)
        self.set_value(delta)
        self.scrollbar.setValue(-delta) 
        
    def cmd_autofocus (self, sock, value):
        if value == 'on':
            self.af_button.setEnabled(0)
            self.af_status.setText('Autofocus is On')
        elif value == 'off':
            # Autofocus is off 
            self.af_button.setEnabled(1)
            self.af_status.setText('Autofocus is Off')
            
    def actionPerformed (self, ev):
        if ev.getActionCommand() == "autofocus":
            self.client.send_message("autofocus")
            
    def adjustmentValueChanged (self, ev):
        v = ev.getValue()
        self.set_value(-v)
        self.timestamp = time.time()
        if self.get_subthread() == None:
            # Fire off subthread
            st = FocusThread(self)
            self.set_subthread(st)
            st.setPriority(lang.Thread.MIN_PRIORITY)
            st.start()

