#!/usr/bin/env python

"""Interactive interpreter for python-csp, with online help.

Features:
 * CSP primitives are imported automatically.
 * History is saved between sessions in C{~/.csp-console-history}.
 * Tab-completion can be used to complete keywords or variables.

Copyright (C) Sarah Mount, 2009.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
"""

try:
    import readline
except ImportError:
    print("Module readline not available.")
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")

import atexit
import code
import os
import sys


__author__ = 'Sarah Mount <s.mount@wlv.ac.uk>'
__date__ = 'December 2008'


class _Printer(object):
    """Print documentation in twenty-line chunks.

    Based on a class of the same name from the site.py module.
    """
    MAXLINES = 20
    def __init__(self, documentation):
        self.__lines = documentation.split('\n')
        self.__linecnt = len(self.__lines)

    def __call__(self):
        prompt = '\n*** Hit Return for more, or q (and Return) to quit: '
        lineno = 0
        while True:
            try:
                for i in range(lineno, lineno + self.MAXLINES):
                    print(self.__lines[i])
            except IndexError:
                break
            else:
                lineno += self.MAXLINES
                key = None
                while key not in ('', 'q', 'Q'):
                    key = input(prompt)
                if key == 'q':
                    break
                print() 


class TabSafeCompleter(rlcompleter.Completer):
    """Enable safe use of Tab for either tab completion or nested scope.
    """
    def complete(self, text, state):
        if text == '':
            return ['\t', None][state]
        else:
            return rlcompleter.Completer.complete(self, text, state)


class CSPConsole(code.InteractiveConsole):
    """python-csp interactive console with REPL.

    Features:
     * CSP channel server is started automatically.
     * CSP primitives are imported automatically.
     * History is saved between sessions in C{~/.csp-console-history}.
     * Tab-completion can be used to complete keywords or variables.
    """

    # From the docs of the readline module.
    def __init__(self, locals=None, filename="<console>",
                 histfile=os.path.expanduser("~/.csp-console-history")):
        code.InteractiveConsole.__init__(self)
        self.init_history(histfile)

    def init_history(self, histfile):
        readline.parse_and_bind("tab: complete")
        delims = ' \t\n`!@#$%^&*()-=+[{]}\\|;:,<>?'
        readline.set_completer_delims(delims)
        readline.set_completer(TabSafeCompleter().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)

    def raw_input(self, *args):
        return code.InteractiveConsole.raw_input(self, *args)


_ban = "\npython-csp (c) 2008. Licensed under the GPL(v2).\n\n"


if __name__ == '__main__':
    c = CSPConsole(locals=locals())
    # Don't expect the csp types to be available in locals()
    c.push('from csp.csp import *')
    c.push('from csp.builtins import *')
    c.push('from csp.guards import *')    
    c.interact(banner=_ban)
