#!/usr/bin/env python

# Author: Liwei Peng (lpeng@bcm.tmc.edu)
# Date 1/10/2002
#

from ScanOption import ScanOption, GLB_OPT, SPC_OPT, USE_OPT
from Img2dbServer import Img2dbServer
from Record import *
from Log import log
import os.path
import getopt
import sys
import rotor
import Util
import glob


def print_usage(program_name, options):
    sorted_options = options.keys()
    sorted_options.sort()

    key_str = ""
    option_str = ""
    lspace = ' ' * 8
    progname = os.path.basename(program_name)
    
    for key in sorted_options:
        if options[key].get_type() == USE_OPT:
            continue

        if options[key].get_type() == GLB_OPT:
            key_str = key_str + '[' + key + ' ' + options[key].get_name() + '] '
        else:
            key_str = key_str + "[" + key + "] "
            
        one_option = lspace + "  " + key + ": " + options[key].get_name()        
        one_option = one_option + "; default = " + str(options[key].get_value())
        option_str = option_str + one_option + "\n"


    print "\n   Usage 1: check in micrographs to database:\n"
    print lspace + progname, key_str, "image1 [image2 ...]",
    
    print "\n%s" % (option_str)
    
    print "   Usage 2: download micrographs:"
    print lspace + progname + " [-f] [-l] -d n"
    print lspace + "  n: shrinkfactor: 1, 1.5, 2, 3, ...\n"
    print lspace + " -f: fast download: download the latest object without ask"
    print lspace + " -l: download focal pair information"
    print
    
    print "   Usage 3: download CCD Frames:"
    print lspace + progname + " [-f] [-l] -F"
    print lspace + " -f: fast download: download the latest object without ask"
    print lspace + " -l: download focal pair information"
    print

    print "   Usage 4: download box data files:"
    print lspace + progname + " [-f] -D"
    print lspace + " -f: fast download: download the latest object without ask"
    print
    
    print "   Usage 5: download focal pair information only:"
    print lspace + progname + " -l"
    print
 
    print "   Usage 6: check in box data files:"
    print lspace + progname + " -B LP0001.box [LP0002.box ...]"
    print
   
    print "   Usage 7: check in ctf parameters:"
    print lspace + progname + " [-j] -C ctfparm1.txt [ctfparm2.txt ...]"
    print lspace + " -j: check in a second set of ctf parameters" 
    print

    print "   Usage 8: send an ISO image to burn a CD:"
    print lspace + progname + " -I isoimage"
    print
    

    print "   Usage 9: check version number:"
    print lspace + "  -v: version number"
    print

    
def main():
    VERSION = 4.6
    
    option_dict = { '-a': ScanOption('averagefactor', 1.0, GLB_OPT),
                    '-b': ScanOption('brightness', 30.0, GLB_OPT),
                    '-c': ScanOption('contrast', 68.0, GLB_OPT),
                    '-d': ScanOption('download', 1.0, USE_OPT),
                    '-e': ScanOption('exposuretime', 0.0, GLB_OPT),
                    '-f': ScanOption('fastdownload', '', USE_OPT),
                    '-g': ScanOption('gain', 0.0, GLB_OPT),
                    '-j': ScanOption('2nd-ctfparam', '', USE_OPT),
                    '-l': ScanOption('download-focalpair', '', USE_OPT),
                    '-m': ScanOption('scanner', "Zeiss", GLB_OPT),
                    '-n': ScanOption('comments', "", SPC_OPT),  
                    '-o': ScanOption('holder', "0", GLB_OPT),
                    '-p': ScanOption('parameters', '1', SPC_OPT),
                    '-s': ScanOption('scanstep', 7.0, GLB_OPT),
                    '-v': ScanOption('version', '', USE_OPT),
                    '-B': ScanOption('upload-boxdata', '', USE_OPT),
                    '-C': ScanOption('ctfparm', '', USE_OPT),
                    '-D': ScanOption('download-boxdata', '', USE_OPT),
                    '-F': ScanOption('download-ccdframe', '', USE_OPT),
                    '-I': ScanOption('burn cd', '', USE_OPT),
                    '-U': ScanOption('username', '', USE_OPT),
                    '-P': ScanOption('password', '', USE_OPT),
                    '-V': ScanOption('debug', '', USE_OPT),
                    }

    if os.name == 'nt':
        option_dict['-b'].set_value(0.0)
        option_dict['-c'].set_value(0.0)
        option_dict['-m'].set_value("Nikon")
        option_dict['-s'].set_value(6.35)

    avg_dict = { '1' : 1, '1.5': 3, '2': 2 }
    
    try:
        opts, img_filenames = getopt.getopt(sys.argv[1:], 'a:b:c:d:e:fg:hjlm:no:ps:vBCDFIU:PV:')
        
    except getopt.GetoptError:
        print "\nError: invalid option\n"
        print_usage(sys.argv[0], option_dict)
        sys.exit(1)
    
    if os.name == 'nt':
        tmp_filenames = []
        for img_filename in img_filenames:
	    files1 = glob.glob(img_filename)
            tmp_filenames = tmp_filenames + files1

        img_filenames = tmp_filenames

    IMG2DB = Img2dbServer()

    is_upload_boxdata = 0
    is_burncd = 0

    IMG2DB.db_password = get_db_passwd()
    Util.safe_unlink(".img2db")
    
    
    for opt, val in opts:
        if opt == '-h':
            print_usage(sys.argv[0], option_dict)
            sys.exit(0)
            
        elif opt == '-a':
            if not avg_dict.has_key(val):
                avg_keys = avg_dict.keys()
                avg_keys.sort()
                print "\nError: valid average factors are: ", avg_keys, "\n"
                sys.exit(1)
            
            else:
                IMG2DB.tld2mrc_ver = avg_dict[val]
                IMG2DB.tiff2mrc_avg = val
                option_dict[opt].set_value(val)

        elif option_dict[opt].get_type() == GLB_OPT:
            if option_dict[opt].set_value(val) == 0:
                sys.exit(1)
        
        elif opt == '-d':
            IMG2DB.record_type = Record(MICROGRAPH)
            IMG2DB.is_download = 1
            IMG2DB.shrink = float(val)
        elif opt == '-f':
            IMG2DB.fast_download = 1
            IMG2DB.nthreads = 3
        elif opt == '-j':
            IMG2DB.ctfparm2 = 1
        elif opt == '-l':
            IMG2DB.record_type = Record(FOCALPAIR)
            IMG2DB.download_focalpair = 1
            IMG2DB.is_download = 1
        elif opt == '-t':
            IMG2DB.microscopy_download = 1
        elif opt == '-B':
            is_upload_boxdata = 1
        elif opt == '-C':
            IMG2DB.is_ctfparm = 1
        elif opt == '-D':
            IMG2DB.record_type = Record(BOXDATA)
            IMG2DB.is_download = 1
        elif opt == '-F':
            IMG2DB.record_type = Record(CCDFRAME)
            IMG2DB.is_download = 1
        elif opt == '-I':
            is_burncd = 1
        elif opt == '-U':
            IMG2DB.db_user = val
        elif opt == '-P':            
            if not IMG2DB.db_password:
                print "\nError: to use '-P', please run 'dbpass' first\n"
                sys.exit(1)            
        elif opt == '-v':
            print "img2db", VERSION
            sys.exit(0)
        elif opt == '-V':
            IMG2DB.debug = int(val)
        else:
            option_dict[opt].need_update(1)
    
    if IMG2DB.is_download:
        if len(img_filenames) != 0:
            print_usage(sys.argv[0], option_dict)
            sys.exit(1)
    elif len(img_filenames) == 0:
        print "\nError: no file is specified!\n"
        print_usage(sys.argv[0], option_dict)
        sys.exit(1)
    
    IMG2DB.img_filenames = img_filenames
    IMG2DB.version = VERSION
            
    input_args = sys.argv[0]
    for arg in sys.argv[1:]:
        input_args = input_args + " " + arg
        
    log.init()
    log.log(input_args)
    
    if not IMG2DB.is_download:
        if IMG2DB.check_img_files() == 1:
            sys.exit(1)

    try:
        if IMG2DB.login() != 0:
            IMG2DB.is_backup_db = 1
            if IMG2DB.login() != 0:
                sys.exit(1)
                
        if IMG2DB.is_download:
            IMG2DB.download()
        elif IMG2DB.is_ctfparm:
            IMG2DB.send_ctfparms()
        elif is_upload_boxdata:
            IMG2DB.upload_boxdata()
        elif is_burncd:
            IMG2DB.send_isoimage()
        else:
            IMG2DB.build_mappings(option_dict)
            IMG2DB.send_micrographs()
            
        IMG2DB.close()

        if IMG2DB.download_focalpair == 1:
            log.write("\n\tFocal Pair Information is saved in file 'focalpair.txt'")
        
    except KeyboardInterrupt:
        IMG2DB.handle_end_signal()
    except EOFError:
        IMG2DB.handle_end_signal()
    except SystemExit:
        pass
    except:
        import traceback
        exct, excv, exctb = sys.exc_info()
        errtext = ""
        for errline in traceback.format_exception(exct, excv, exctb):
            errtext = errtext + errline
        log.mail(errtext)
    
    log.close()


def get_db_passwd():
    pfilename =".img2db"
    
    if os.path.exists(pfilename):
        pfile = open(pfilename, "r")
        lines = pfile.readlines()
                
        encrypted_k = lines[0]
        encrypted_k = encrypted_k[0:-1]
    
        rt = rotor.newrotor("", 12)
        key = rt.decrypt(encrypted_k)
        
        rt.setkey(key)
        return rt.decrypt(lines[1])
    
    return None

    
if __name__ == "__main__":    
    main()
    
      
