#! /usr/bin/env python
"""
Python shell for SymPy. Executes the commands in the "init_code" variable
before giving you a shell.

command line options:
  -c : permits to specify a python interactive interpreter, currently only
       python or ipython. Example usage:
           isympy -c python
       default is set to ipython

  -h : prints this help message

  --version: prints version number
"""

init_code = """
from __future__ import division
from sympy import *
x, y, z = symbols('xyz')
k, m, n = symbols('kmn', integer=True)
Basic.set_repr_level(2)     # pretty print output; Use "1" for python output
pprint_try_use_unicode()    # use unicode pretty print when available
"""

import sys

# hook in-tree sympy into python path if running in-tree version of isympy
import os.path
isympy_dir  = os.path.dirname(__file__)         # bin/isympy
sympy_top   = os.path.split(isympy_dir)[0]      # ../
sympy_dir   = os.path.join(sympy_top, 'sympy')  # ../sympy/
if os.path.isdir(sympy_dir):
    #print 'working in-tree...'
    sys.path.insert(0, sympy_top)

from sympy import __version__ as sympy_version
python_version = "%d.%d.%d" % tuple(sys.version_info[:3])

def indent(s):
    """Puts ">>> " in front of each line."""
    r = ""
    for l in s.split("\n"):
        if l != "":
            r+=">>> "+l+"\n"
    return r

welcome_msg = \
    "Python %s console for SymPy %s. These commands were executed:\n%s" % \
            (python_version, sympy_version, indent(init_code))

def run_ipython_interpreter():

    from IPython.Shell import IPShellEmbed

    #is the -nopprint necessary?
    #args = ['-nopprint']
    args = []
    ipshell = IPShellEmbed(args)
    api = ipshell.IP.getapi()
    api.ex(init_code)
    api.ex('__IP.compile("from __future__ import division", "<input>", "single") in __IP.user_ns')

    ### create some magic commands

    #def pretty_print(self, arg):
    #    self.api.ex("print str((%s).__pretty__())" % arg)

    #api.expose_magic("pprint", pretty_print)

    # Now start an embedded ipython.
    ipshell(welcome_msg)
    sys.exit("Exiting ...")

def run_python_interpreter():
    print """\
Couldn't locate IPython. Having IPython installed is greatly recommended.  See
http://ipython.scipy.org for more details. If you use Debian/Ubuntu, just
install the "ipython" package and start isympy again.\n"""

    import code
    import readline
    import atexit
    import os


    class HistoryConsole(code.InteractiveConsole):
        def __init__(self, locals=None, filename="<console>",
	                 histfile=os.path.expanduser("~/.sympy-history")):
            code.InteractiveConsole.__init__(self)
            self.init_history(histfile)
            self.runcode(self.compile("from __future__ import division", 
                "<input>", "single"))

        def init_history(self, histfile):
	        readline.parse_and_bind("tab: complete")
	        if hasattr(readline, "read_history_file"):
	            try:
	                readline.read_history_file(histfile)
	            except IOError:
	                pass
                atexit.register(self.save_history, histfile)

        def save_history(self, histfile):
            readline.write_history_file(histfile)

    sh = HistoryConsole()
    sh.runcode(init_code)
    sh.interact(welcome_msg)
    sys.exit("Exiting ...")


from optparse import OptionParser

def main():
    from sympy import __version__ as sympy_version
    parser = OptionParser("usage: isympy [options]", version=sympy_version )
    parser.add_option("-c", "--console", dest="console",
                      help="specify a python interactive interpreter, python or ipython")
    (options, args) = parser.parse_args()

    if options.console == "python":
        run_python_interpreter()
    elif options.console == "ipython":
        run_ipython_interpreter()
    else:
	    try:
	        run_ipython_interpreter()

	    except ImportError:
	        run_python_interpreter()

if __name__ == "__main__":
    main()

