#!/usr/bin/python2

# the main GUI program. Relies on fract4d libs to do the real work
version = '2.13'

# python stdlib
import sys
import os
import getopt
import distutils.sysconfig

# gettext
import gettext
os.environ.setdefault('LANG', 'en')
if os.path.isdir('po'):
    gettext.install('gnofract4d','po')
else:
    gettext.install('gnofract4d')

# gtk
try:
    import gtk
except ImportError, err:
    print _("Can't find PyGTK. You need to install it before you can run Gnofract 4D.")
    sys.exit(1)

# check for pygtk >=1.99
pygtk_ok = True
try:
    (major,minor,patch) = gtk.pygtk_version
    if major < 2:
        if minor < 99:
            pygtk_ok = False
    import gobject
    
except Exception:
    pygtk_ok = False

if not pygtk_ok:
    print _("Sorry, your PyGTK version is too old. You need at least 1.99")
    sys.exit(1)

try:
    libdir = '/usr/lib'
    # we install our libs privately instead of to site-packages
    sys.path.append(os.path.join(libdir, 'gnofract4d-%s' % version))
    # gui modules
    from fract4dgui import main_window, preferences, utils
    
except ImportError, err:
    print _('''
Can't import a required module.
If you haven't set up Gnofract 4D yet, run './setup.py build'
Error was: '%s' ''') % err
    sys.exit(1)

# stop PyGTK from complaining about our use of ItemFactory - I want this to
# carry on working with older PyGTK's, so UIManager is out, and the differences
# between the 2 are too large to hide
try:
    import warnings
    warnings.filterwarnings(
        "ignore",
        ".*UIManager.*",
        DeprecationWarning,
        ".*",
        0)

except Exception, exn :
    print exn
    pass

# Threads are optional because RedHat seem to compile pygtk
# without thread support. Grrr.
try:
    #gtk.gdk.threads_init()
    #utils.threads_enabled = True
    pass
except:
    pass
    
def help():
    print """Gnofract 4D %s
Usage: gnofract4d [flags] [paramfile]

Flags:
-h --help\t\tShow this message
-v --version\t\tShow version info
-p --params FILE\tUse FILE as a parameter file
-q --quit\t\tExit as soon as the image is finished
-s --save IMAGEFILE\tSave image to IMAGEFILE
-i --width N\t\tMake image N pixels wide
-j --height N\t\tMake image N pixels tall
-P --path P\t\tAdd P to the formula search path
-f --formula F#func\tUse formula 'func' from file F
   --inner F#func\tUse coloring algorithm 'func' from file F
   --outer F#func\tUse coloring algorithm 'func' from file F
-X --explorer\tStart in explorer mode

To generate an image non-interactively, use:
gnofract4d -s myimage.png -q myfractal.fct

""" % version

def print_version():
    try:
        gtk_version = "%d.%d.%d" % gtk.gtk_version
    except:
        gtk_version = "unknown"

    try:
        pygtk_version = "%d.%d.%d" % gtk.pygtk_version
    except:
        pygtk_version = "unknown"
        
    print """Gnofract 4D %s
GTK %s
PyGTK %s""" % (version, gtk_version, pygtk_version)
               
def splitarg(val, name,mainWindow):
    n = val.rfind('#')
    if n==-1:
        help()
        print "ERROR: %s should be file#func" % name
        sys.exit(1)
    (file, func) = (val[:n], val[n+1:])
    path = os.path.dirname(file)
    if path: 
        mainWindow.compiler.file_path.append(path)

    basename = os.path.basename(file)
    return (basename,func)

def main():
    mainWindow = main_window.MainWindow()

    width = preferences.userPrefs.getint("display","width")
    height = preferences.userPrefs.getint("display","height")
    (basename,func) = (None,None)
    (innername,innerfunc) = (None,None)
    (outername,outerfunc) = (None,None)
    try:
        (opts, args) = getopt.getopt(
            sys.argv[1:],
            "p:i:j:s:qhP:Xv",
            [ "params=",
              "width=",
              "height=",
              "save=",
              "help",
              "path=",
              "formula=",
              "inner=",
              "outer=",
              "quit",
              "explorer",
              "version"])

        for (name, val) in opts:
            if name=="-p" or name=="--params":
                args.insert(0,val)
            elif name=="-q" or name=="--quit":
                mainWindow.quit_when_done = True
            elif name=="-s" or name=="--save":
                mainWindow.save_filename = val
            elif name=="-i" or name=="--width":
                width = int(val)
            elif name=="-j" or name=="--height":
                height = int(val)
            elif name=="-h" or name=="--help":
                help()
                return
            elif name=="-P" or name=="--path":
                mainWindow.compiler.file_path.append(val)
            elif name=="-X" or name=="--explorer":
                mainWindow.set_explorer_state(True)
            elif name=="--formula":
                (basename,func) = splitarg(val,name,mainWindow)
            elif name=="--inner":
                (innername,innerfunc) = splitarg(val,name,mainWindow)
            elif name=="--outer":
                (outername,outerfunc) = splitarg(val,name,mainWindow)
            elif name=="--version" or name=="-v":
                print_version()
                return
            else:
                print "Unknown argument", name, val
                
    except getopt.GetoptError:
        help()
        return 1
    
    mainWindow.f.set_size(width,height)

    if len(args) > 0:
        mainWindow.load(args[0])
        
    if basename and func:
        mainWindow.f.set_formula(basename,func)
        mainWindow.f.reset()

    if innername and innerfunc:
        mainWindow.f.set_inner(innername, innerfunc)
        mainWindow.f.reset()

    if outername and outerfunc:
        mainWindow.f.set_outer(outername, outerfunc)
        mainWindow.f.reset()
        
    if mainWindow.f.thaw():
        mainWindow.on_fractal_change()

    gtk.main()

def main_n(n):
    for i in xrange(n):
        main()

if __name__ == '__main__':
    if os.environ.get("DO_GF4D_PROFILE"):
        import hotshot
        prof = hotshot.Profile("gf4d.prof")
        prof.runcall(main_n, 5)
        prof.close()
    else:
        main()
