#!/usr/bin/env python

""" A script that parses command line arguments and launches MayaVi.
This is to be used by folks who wish to use MayaVi as a standalone
application.

This code is distributed under the conditions of the BSD license.  See
LICENSE.txt for details.

Copyright (c) 2001-2002, Prabhu Ramachandran.

This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

Author contact information:
  Prabhu Ramachandran <prabhu_r@users.sf.net>

MayaVi Home: http://mayavi.sourceforge.net

"""

# MayaVi Version - remember to change this!
VERSION = 1.3

__author__ = "Prabhu Ramachandran <prabhu_r@users.sf.net>"
__version__ = "$Revision: 1.14 $"
__date__ = "$Date: 2003/10/16 08:55:13 $"


import sys, types, string, getopt, os
import os.path

def usage ():
    msg="""Usage:\n\nmayavi [options] ... [arg1] [arg2] ...

Where arg1, arg2 ... are optional file names that correspond to saved
MayaVi visualizations.  Valid options are one or more of the
following:

--display DISPLAY

     Use DISPLAY for the X Display.

-g
--geometry WxH+X+Y

     The geometry of the main window in standard X fashion.

-d vtk-file.vtk
--vtk vtk-file.vtk    

     vtk-file.vtk can be any VTK file.

-x plot3d-xyz-file
--plot3d-xyz plot3d-xyz-file

     The plot3d-xyz-file must be a PLOT3D single block co-ordinate
     file.

-q plot3d-q-file
--plot3d-q plot3d-q-file

     The plot3d-q-file must be a PLOT3D single block solution file.
     The -q option is optional but must always follow the
     -x/--plot3d-xyz option.

-e ensight-case-file
--ensight ensight-case-file

     ensight-case-file must be a valid EnSight case file.  EnSightGold
     and EnSight6 formats are supported.

-m module-name
--module module-name

     The passed module name is loaded in the current ModuleManager.
     The module name must be a valid one if not you will get an error
     message.

--filter filter-name
-f filter-name

     The passed filter name is loaded in the current ModuleManager.
     The filter name must be a valid one if not you will get an error
     message.  If the filter is 'UserDefined' then it could be
     specified as 'UserDefined:vtkSomeFilter' where vtkSomeFilter is a
     valid VTK class.  In this case the filter will not prompt you for
     the VTK filter to use.

-z saved-visualization-file
--viz saved-visualization-file
--visualization saved-visualization-file

     Loads a previously saved MayaVi visualization file passed as the
     argument.

-M module-manager-file
--module-mgr module-manager-file

     Loads a module manager saved to a file.  If a file that does not
     exist is given this will simply create a new module manager that
     can be populated with filters and modules.

-w vrml-file
--vrml vrml-file

     Imports a VRML2 scene given an appropriate file.

-3 3DStudio-file
--3ds 3dStudio-file

     Imports a 3D Studio scene given an appropriate file.

-n
--new-window

     Creates a new window.  Any options passed after this will apply
     to this newly created window.

-V 
--version

     Prints the MayaVi version.

-h
--help

     Prints this help message.

Examples:

     mayavi examples/heart.mv

     mayavi -z examples/heart.mv -n -z examples/other.mv

     mayavi -d examples/heart.vtk -m Axes -m GridPlane \\
     -M new -f Threshold -m IsoSurface \\
     -n -d examples/heart.vtk -m Outline -m ContourGridPlane 
"""
    return msg


def parse_cmd_line (arguments):
    """Returns the options and arguments parsed via getopts.
    
    Input Arguments:
      arguments -- This can be either a list of arguments as in      
                   sys.argv[1:] or a string that is similar to the one
                   passed on the command line.  If it is a string the
                   string is split to create a list of arguments.
    """
    if type (arguments) is types.StringType:
        arguments = string.split (arguments)
        
    options = "g:d:x:q:e:m:f:z:M:w:3:n"
    
    long_opts = ['geometry=', 'display=', 'vtk=', 'plot3d-xyz=',
                 'plot3d-q=', 'ensight=', 'module=', 'filter=',
                 'visualization=', 'viz=', 'module-mgr=',
                 'vrml=', '3ds=', 'new-window']
    
    try:
        opts, args = getopt.getopt (arguments, options, long_opts)
    except getopt.error, msg:
        print msg
        print usage ()
        print '-'*70
        print msg
        sys.exit (1)
        
    return opts, args


def process_cmd_line (app, opts, args):
    """ Processes the passed command line arguments.  Returns a list
    of MayaViTkGUI instances.  This is useful when new windows are
    created from the command line because the new windows are all
    referenced in the returned list.

    Input Arguments:
      app -- A MayaViTkGUI instance.

      opts -- The list of options returned by getopt.

      args -- The remaining arguments returned by getopt.
    """    

    in_plot3d = 0
    xyz_file = ""

    apps = [app]
    geometry = ""

    for o, a in opts:
        if o in ('-g', '--geometry'):
            app.root.geometry(a)
            geometry = a

        if in_plot3d:
            if o in ('-q', '--plot3d-q'):
                app.open_plot3d (xyz_file, a, config=0)
            else:
                app.open_plot3d (xyz_file, config=0)
            in_plot3d = 0
        else:
            if o in ('-q', '--plot3d-q'):
                print "Sorry, the -q/--plot3d-q option must follow "\
                      "a -x/--plot3d-xyz."

        if o in ('-x', '--plot3d-xyz'):
            in_plot3d = 1
            xyz_file = a

        if o in ('-d', '--vtk'):
            base, ext = os.path.splitext(a)
            if ext in ['.xml', '.vti', '.vtr', '.vts', '.vtp', '.vtu',
                       '.pvti', '.pvtr', '.pvts', '.pvtp', '.pvtu']:
                app.open_vtk_xml(a, config=0)
            else:
                app.open_vtk (a, config=0)

        if o in ('-e', '--ensight'):
            app.open_ensight(a, config=0)

        if o in ('-m', '--module'):
            app.load_module (a, config=0)

        if o in ('-f', '--filter'):
            app.load_filter (a, config=0)

        if o in ('-z', '--visualization', '--viz'):
            app.load_visualization (a)

        if o in ('-M', '--module-mgr'):
            app.load_mm (a)
            
        if o in ('-w', '--vrml'):
            app.open_vrml2 (a)

        if o in ('-3', '--3ds'):
            app.open_3ds (a)

        if o in ('-n', '--new-window'):
            app = app.new_window ()
            if geometry:
                app.root.geometry (geometry)
            apps.append (app)

    # for remaining arguments simply load saved visualizations.
    for arg in args:
        base, ext = os.path.splitext (arg)
        if ext == '.mv':
            app.load_visualization (arg)
        else:
            print usage ()
            print "*"*70
            print "Error:"
            print "\tPlease specify a MayaVi file with a '.mv' extension."
            print "\tFor details on how to load other files read the above"
            print "\tusage documentation."
            print "*"*70
            sys.exit (0)

    return apps


# If the user just wants help messages.  Print them before importing
# any of the big modules.
if ('-h' in sys.argv[1:]) or ('--help' in sys.argv[1:]):
    print usage ()
    sys.exit (0)

if ('-V' in sys.argv[1:]) or ('--version' in sys.argv[1:]):
    print 'MayaVi %s'%VERSION
    sys.exit (0)


import Tkinter
try:
    # check if mayavi is available as a module.
    import mayavi
except ImportError:
    # the script is being run from the main directory.
    import Main
    MayaViTkGUI = Main.MayaViTkGUI
else:
    MayaViTkGUI = mayavi.Main.MayaViTkGUI


opts, args = parse_cmd_line (sys.argv[1:])

display = ""
if os.name == 'posix':
    for o, a in opts:
        if o in ('--display',):
            display = a
            break

if display:
    r = Tkinter.Tk (screenName=display)
else:
    r = Tkinter.Tk ()
r.withdraw ()

app = MayaViTkGUI (r)
process_cmd_line (app, opts, args)
r.mainloop ()
