'''
This script generates a GUI with the different functions supported by the machine (Autofocus, Acquire...)
Each function is associated to parameters/variables that can be adjusted
Once the parameters are chosen, clicking on the button of the function generates the machine command in the log window
This can be repeated to generate the full imaging script (cpoy/paste from the log window then)
'''
#@PrefService prefs
from java.awt.event import ActionListener
from fiji.util.gui  import GenericDialogPlus
from ij             import IJ

# We create an event subclasse for each machine function to associate to a button 
class AutofocusClass(ActionListener): # extends action listener
	
	def actionPerformed(this,event):
		'''Called when 'autofocus' is clicked'''

		# Recover parameters (converting to int and float allows to get rid of leading 0, or turn -0 in 0 for instance)
		nSlice = int(NumField[0].text)
		if nSlice<1 : 
			IJ.log("There should be at least 1 slice") 
			raise Exception("There should be at least 1 slice")
			
		dSlice = float(NumField[1].text)
		if float(dSlice)<0 :
			IJ.log("The distance between slices should be >=0")
			raise Exception("The distance between slices should be >=0")
		
		Bin = Choice[0].getSelectedItem()
		
		PreAF      = str(CheckBox[0].getState())
		DeferAdapt = str(CheckBox[1].getState())
		
		# Formulate Autofocus command
		cmd = "Autofocus({},{},{},'{}','{}')".format(nSlice,dSlice,Bin,PreAF,DeferAdapt)   # see if dSlice should have a given number of digits
		print cmd
		IJ.log(cmd)

		# Save input for persistence
		prefs.put("AF_nSlice",nSlice)
		prefs.put("AF_dSlice",dSlice)
		prefs.put("AF_bin",Bin)
		prefs.put("PreAF",PreAF)
		prefs.put("DeferAdapt",DeferAdapt)


class AcquireClass(ActionListener): # extends action listener
	
	def actionPerformed(this,event):
		'''Called when 'Acquire' is clicked'''
		
		# Recover parameters (converting to int and float allows to get rid of leading 0, or turn -0 in 0 for instance)
		nSlice = int(NumField[2].text)
		if nSlice<1 : 
			IJ.log("There should be at least 1 slice") 
			raise Exception("There should be at least 1 slice")
			
		dSlice = float(NumField[3].text)
		if float(dSlice)<0 :
			IJ.log("The distance between slices should be >=0")
			raise Exception("The distance between slices should be >=0")
		
		Bin = Choice[1].getSelectedItem()
		
		MainPath = StringField[0].text
		UseMeta  = str(CheckBox[2].getState())
		
		# Formulate Autofocus command
		cmd = "Autofocus({},{},{},'{}','{}')".format(nSlice,dSlice,Bin,MainPath,UseMeta)   # see if dSlice should have a given number of digits
		print cmd
		IJ.log(cmd)

		# Save input for persistence
		prefs.put("Acq_nSlice",nSlice)
		prefs.put("Acq_dSlice",dSlice)
		prefs.put("Acq_bin",Bin)
		prefs.put("MainPath",MainPath)
		prefs.put("UseMeta",UseMeta)


class SetLightClass(ActionListener):
	
	def actionPerformed(this,event):
		'''Called when 'SetLight' is clicked'''
		#(channel, intensity, integration time, AF offset)

		# Recover input parameters
		Channel = Choice[2].getSelectedItem()
		
		Power = int(NumField[4].text)
		if Power<=0 or Power>100 :
			IJ.log("Power should be in the range 0-100")
			raise Exception("Power should be in the range 0-100")

		Exposure = int(NumField[5].text)
		if Exposure<=0 :
			IJ.log("Exposure should be positive")
			raise Exception("Exposure should be positive")

		AFoffset = float(NumField[6].text)
		

		# Formulate Autofocus command
		cmd = "SetLight({},{},{},{})".format(Channel,Power,Exposure,AFoffset)   # see if dSlice should have a given number of digits
		print cmd
		IJ.log(cmd)

		# Save input for persistence
		prefs.put("Channel",Channel)
		prefs.put("Power",Power)
		prefs.put("Exposure",Exposure)
		prefs.put("AFoffset",AFoffset)	
		
		

# Create class instances associated to GUI Button
Autofocus = AutofocusClass()    # create an instance of the EventListener class
Acquire   = AcquireClass()      # create an instance of the EventListener class
SetLight  = SetLightClass()

'''
# Initialise counter for index - Maybe in the future
N_Box    = 0
N_String = 0
N_Num    = 0
'''
 
# Generate GUI
Win = GenericDialogPlus('Generate Imaging Machine Script File IMSF')


# Autofocus(nSlice,dSlice,Bin,PreAF,DeferAdapt)
# Get input fron persistence
AF_nSlice  = prefs.getInt("AF_nSlice",1)
AF_dSlice  = prefs.getInt("AF_dSlice",0)
AF_bin     = prefs.get("AF_bin",'1')
PreAF      = prefs.getBoolean("PreAF",True)
DeferAdapt = prefs.getBoolean("DeferAdapt",True)

Win.addButton('Autofocus',Autofocus) # add our event listener to the button. Button clicked -> event -> call actionPerformed(MyEvent)
Win.addToSameRow()
Win.addNumericField('Number of slices',AF_nSlice,0) 				  # Num[0]=Autofocus>N_Slice 
Win.addToSameRow()
Win.addNumericField('-   Distance between slices (um)',AF_dSlice,3)  # Num[1]=Autofocus>d_Slice 
Win.addToSameRow()                           
Win.addChoice('Binning',['1','2','4'],AF_bin)                    # Choices[0]=Autofocus>Binning
Win.addToSameRow()
Win.addCheckbox('PreAutofocus',PreAF)                          # Bool[0]=Autofocus>PreAutofocus
Win.addToSameRow()
Win.addCheckbox('Defer Adaptative',DeferAdapt)                 # Bool[1]=Autofocus>DeferAdaptative


# Acquire (nSlice,dSlice,Bin,path of main directory, Use meta information for filename)
# Get input fron persistence		
Acq_nSlice  = prefs.getInt("Acq_nSlice",1)
Acq_dSlice  = prefs.getInt("Acq_dSlice",0)
Acq_bin     = prefs.get("Acq_bin",'1')
MainPath    = prefs.get("MainPath",r'D:\IMAGING-DATA\IMAGES\SCRIPTS')
UseMeta     = prefs.getBoolean("UseMeta",True)

Win.addButton('Acquire',Acquire) # add our event listener to the button. Button clicked -> event -> call actionPerformed(MyEvent)
Win.addToSameRow()
Win.addNumericField('Number of slices',Acq_nSlice,0) 				  # Num[2]=Acquire>N_Slice 
Win.addToSameRow()
Win.addNumericField('-   Distance between slices (um)',Acq_dSlice,3)  # Num[3]=Acquire>d_Slice 
Win.addToSameRow()
Win.addChoice('Binning',['1','2','4'],Acq_bin)                    # Choices[1]=Acquire>Binning
Win.addToSameRow()
Win.addStringField("-   Main folder",MainPath) # String[0]=Acquire>MainPath
Win.addToSameRow()
Win.addCheckbox("Use metadata for filename",UseMeta)			 # Bool[2]=Acquire>Use metadata


# SetLight(channel, intensity,exposure, AF offset)
# Recover input from persistence
Channel  = prefs.get("Channel",'6')
Power    = prefs.getInt("Power",50)
Exposure = prefs.getInt("Exposure",100)
AFoffset = prefs.getFloat("AFoffset",0.000)

Win.addButton('Set Light',SetLight)
Win.addToSameRow()
Win.addChoice('Channel',['1','2','3','4','5','6'],Channel)                   # Choices[2]=SetLightChannel
Win.addToSameRow()
Win.addNumericField('Power(%)',Power,0) 				                     # Num[4]=SetLight>Power
Win.addToSameRow()
Win.addNumericField('Exposure(ms)',Exposure,0) 				                 # Num[5]=SetLight>Exposure
Win.addToSameRow()
Win.addNumericField('AF offset(um)',AFoffset,3)								 # Num[6]=SetLight>AF offset




# Recover vector objects from dialog
NumField    = Win.getNumericFields()
CheckBox    = Win.getCheckboxes()
StringField = Win.getStringFields()
Choice      = Win.getChoices()

# Display after the vector objects were created
Win.showDialog()