#! /usr/bin/env python
'''
The python AO simulation startup script.
either starts a command line or gui version of the simulation.
'''
import sys
import os
import matplotlib.pyplot as plt
import numpy as np

if sys.platform == "win32":
    # hack to stop the interpretter craching on ctrl-c events when scipy imported.
    # described in more detail here:
    # http://stackoverflow.com/questions/15457786/ctrl-c-crashes-python-after-importing-scipy-stats

    import imp
    import ctypes
    import _thread as thread
    import win32api

    # Load the DLL manually to ensure its handler gets
    # set before our handler.
    basepath = os.path.dirname(sys.executable)
    ctypes.CDLL(os.path.join(basepath, "Library", "bin", 'libmmd.dll'))
    ctypes.CDLL(os.path.join(basepath, "Library", "bin", 'libifcoremd.dll'))

    # Now set our handler for CTRL_C_EVENT. Other control event
    # types will chain to the next handler.
    def handler(dwCtrlType, hook_sigint=thread.interrupt_main):
        if dwCtrlType == 0: # CTRL_C_EVENT
            hook_sigint()
            return 1 # don't chain to the next handler
        return 0 # chain to the next handler

    win32api.SetConsoleCtrlHandler(handler, 1)

from argparse import ArgumentParser
import IPython
import soapy
# from soapy import gui


def runCmdSim(sim, newIMat=False, interactive = False):
    '''
    Runs the simulation in the command line.
    '''

    simConfig = sim.config.sim
    for w in range(simConfig.nGS):
        exec("wfs{0}Config = sim.config.wfss[{0}]".format(w))
    for d in range(simConfig.nDM):
        exec("dm{0}Config = sim.config.dms[{0}]".format(d))
    telConf = sim.config.tel

    if interactive:
        #sim.aoinit()
        IPython.embed()
        raise SystemExit



    else:
        sim.aoinit()
        sim.makeIMat()
        sim.aoloop()



if __name__=="__main__":

    #Define parser and add arguments
    parser = ArgumentParser()
    parser.add_argument("configFile", nargs="?", action="store",
            help="The AO config file you wish to simulate. Defaults to conf/sh_8x8.py if none specified.")
    parser.add_argument("--gui","-g", action="store_true", dest="gui",
            help="Starts the AO gui to visualise your simulation")

    parser.add_argument("-gl", "--with-opengl", dest="gl",
            action="store_true", help="Use opengl for gui plotting")
    parser.add_argument("-i", "--interactive", dest="interactive",
                        action="store_true", help="Open sim using ipython interactive mode")
    parser.add_argument("-V", "--verbosity", dest="verbosity",
            action="store", default=2,
            help="How much information to print about the simulation")

    parser.add_argument("-v", "--version", action="version",
            version=soapy.__version__)

    parser.add_argument('-d', "--debug", action='store_true', dest='debug',
        help='Sets the verbosity to highest level for debugging purposes (same is -v 3)')

    bin_path = os.path.abspath(os.path.realpath(__file__)+"/..")

    #Finally, parse args
    args = parser.parse_args()

    #default confFile
    if args.configFile!=None:
        configFile = args.configFile
    else:
        configFile = bin_path+"/../conf/sh_8x8.yaml"

    # Run sim with given args
    # Set the verbosity
    if args.debug:
        verbosity = 3
    else:
        verbosity = args.verbosity
    soapy.logger.setLoggingLevel(verbosity)

    #init sim with conf file
    sim = soapy.Sim(configFile)
    sim.config.sim.verbosity = args.verbosity

    #if gui start gui
    if args.gui:
        from soapy import gui
        simGUI = gui.start_gui(sim, useOpenGL=args.gl, verbosity=verbosity)

    else:
        runCmdSim(sim, interactive=args.interactive)
