#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#
# ABOUT   : This script checks in which wheel and in which
#           position a filter, a slit or a grism is located.
#           It can also be used to move this wheel to the right
#           position with an optional argument "-m". Filters
#           are searched by their ID numbers, but slits and grisms
#           are searched by a user defined string. With a single command
#           as many as three wheels can be turned at the same time
.
#
# USAGE   : alfosc.optics [-e] [-m] [-s] [-g] [-f] [-d] [-v] [-a] [-p] [-o] <search pattern>
#           where:
#           [-e] echo script on stdout, does not execute 
#           [-m] moves the wheel(s)
#           [-s] searches the aperture wheel for the string that follows 
#           [-g] searches the grism wheel and
 the filter wheel for the string that follows
#           [-f] searches the filter wheel, FASUa and FASUb for the filter ID number that follows 
#           [-d] displays the content of the given (filter, fasua, fasub, grism, slit) wheel
#           [-v] verbose mode, prints extra information for debugging
#           [-a] prints out the status of alignment tag in the output
#           [-p] prints out the position (x and y) of the slit. Can only be used with -s flag
#           [-o] prints out the Open positions for all wheels
#           [-h] help
#           <search pattern> must be given after the wheel parameter -s/-g/-f
#
# EXITSTA : 0: No errors
#           1: A problem with command line arguments
#           2: Search returned more than one solution
#           3: Search returned a solution in at least two wheels
#           4: Search did not return any solutions
#           5: One or more of the .def files cannot be accessed
#           6: Searched filter and grism are both located in filter wheel
#
# DEPENDS : alfoscinst.filter
#           alfoscinst.fasua
#           alfoscinst.fasub
#           alfoscinst.grism
#           alfoscinst.aperture
#           WheelLoader (python module in fileloader)
#          
# PROVIDES: alfosc.optics
#
# TFUNCT  : If used for searching: about 0.1s
#                   for turning wheels: up to 25.0s
#
# AUTHOR  : Sami-Matias Niemi
#
# HISTORY : 06/06/2008 Development version alpha 0.1 (SMN)
#           09/06/2008 Release Candidate 1, version 0.2 (SMN)
#           16/06/2008 Release Candidate 2, version 0.9 (SMN)
#           23/06/2008 Release Candidate 2, version 1.0 (SMN)
#           25/11/2008 Added alignment tag functionality, version 1.1 (SMN)
#           28/11/2008 Fixed a small bug, version 1.11 (SMN):
#                      (grisms in the filter wheel do not have alignment status, return "Maybe")
#           04/12/2008 Added slit position (x,y) and open position (wheel pos) functionality, version 1.2 (SMN)

__author__ = 'Sami-Matias Niemi'
__version__ = '1.2'

#Definition of the command line arguments:
def process_args(just_print_help = False):
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-g", "--grism", dest="grism",
                      help="Searches the grism and the filter wheel", metavar="string")     
    parser.add_option("-s", "--slit", dest="slit",
                      help="Searches the aperture wheel", metavar="string")
    parser.add_option("-f", "--filter", dest="filter",
                      help="Searches the filter, FASUa and FASUb wheels", metavar='"ID number"')
    parser.add_option("-m", "--move", action="store_true", dest="movement",
                      help="Moves the wheel(s) in")
    parser.add_option("-d", "--display", dest="display",
                      help="Displays the content of the wheel, where string = filter/fasua/fasub/grism/slit", metavar="string")    
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                      help="Verbose mode on")
    parser.add_option("-e", "--echo", action="store_true", dest="echo",
                      help="Echoes the commands on stdout, does not execute the script")
    parser.add_option("-a", "--alignment", action="store_true", dest="alignm",
                      help = "Prints out the alignment tag (Y/N) in the output")
    parser.add_option("-p", "--position", action="store_true", dest="slitpos",
                      help = "Prints out the slit position (x, y) in the output")
    parser.add_option("-o", "--opens", action="store_true", dest="opens",
                      help = "Prints out the Open positions for every wheel")
    if just_print_help:
        parser.print_help()
    else:
        return parser.parse_args()

#Redefines subprocess.call -function
def call(command, echo = False, wait = False):
    import subprocess
    if echo:
        print command
    else:
        #return subprocess.call(arg.split())
        #Shell = True --> no arg.split()
        #return subprocess.call(command, shell=True)
        #call will do Popen().wait() so it will wait to be ready!
        if wait:
            return subprocess.Popen(command, shell=True).wait()
        else:
            return subprocess.Popen(command, shell=True)

def slitpos(wheelPosition):
    """
    This function finds the slit position in x and y for given wheel position
    """
    #definition file (the original not the symbolic link)
    file = '/home/software/setupfiles/ALFOSC/slitpos.def'
    data = open(file, 'r').readlines()

    #just for help
    x, y = -1, -1

    #finds the right position and coordinates
    for line in data:
        pos, x, y = line.strip().split()
        if int(pos) == int(wheelPosition): break
    return x, y

def listOpenPositions():
    """
    Prints out the open positions for all wheels.
    """
    from fileloader import WheelLoader 
    
    deffilter = "/home/software/setupfiles/ALFOSC/filter.def"
    deffasua = "/home/software/setupfiles/ALFOSC/fasua.def"
    deffasub = "/home/software/setupfiles/ALFOSC/fasub.def"
    defgrism = "/home/software/setupfiles/ALFOSC/grism.def"
    defslit = "/home/software/setupfiles/ALFOSC/slit.def"

    fil = WheelLoader(deffilter)
    fa = WheelLoader(deffasua)
    fb = WheelLoader(deffasub)
    gr = WheelLoader(defgrism)
    sl = WheelLoader(defslit)

    filo, fao, fbo, gro, slo = -9, -9, -9, -9, -9

    #Prints out only the first Open position as for loops have break
    for line in fil:
        if line[2] == 'Open':
            filo = int(line[0])
            break
    for line in fa:
        if line[1] == 'Open':
            fao = int(line[0])
            break
    for line in fb:
        if line[1] == 'Open':
            fbo = int(line[0])
            break
    for line in sl:
        if line[2] == 'Open':
            slo = int(line[0])
            break
    for line in gr:
        if line[2].startswith('Open'):
            gro = int(line[0])
            break
    
    print 'fi %i' % filo
    print 'fa %i' % fao
    print 'fb %i' % fbo
    print 'ap %i' % slo
    print 'gr %i' % gro

if __name__ == '__main__':
    import sys
    import os.path
    from StringIO import StringIO
    from subprocess import Popen, PIPE
    from fileloader import WheelLoader
    
    #Gets the command line arguments
    (opts, args) = process_args()
    
    #Definition files:
    deffilter = "/home/software/setupfiles/ALFOSC/filter.def"
    deffasua = "/home/software/setupfiles/ALFOSC/fasua.def"
    deffasub = "/home/software/setupfiles/ALFOSC/fasub.def"
    defgrism = "/home/software/setupfiles/ALFOSC/grism.def"
    defslit = "/home/software/setupfiles/ALFOSC/slit.def"

    #Saves the debug boolean "echo"
    if (opts.echo is True): echo = True
    else: echo = False

    if opts.opens:
        listOpenPositions()
        sys.exit(0)
    
    if opts.verbose is True: 
        if (opts.grism is not None): print "\nYou chose to search the grism wheel!\n"
        if (opts.slit is not None): print "\nYou chose to search the slit wheel!\n"
        if (opts.filter is not None): print "\nYou chose to search a filter from filter, fasua and fasub wheels!\n"
        if (opts.echo is True): print "\nYou chose the echo -mode. Does not execute!\n"
    
    #Displays the wheel content
    if (opts.dis