#import everything from the C-code
from plus import *

import giScript

#hook into our custom output routines
class giScript_stdout:
    def write(self, s):
        giScript.debug_stdout(s)

class giScript_stderr:
    def __init__(self):
        self.count = 0
    def write(self, s):
        self.count += 1
        giScript.debug_stderr(s)
    def flush(self):
        pass

import sys
import linecache
import traceback

sys.stdout = giScript_stdout()
sys.stderr = giScript_stderr()

#import all necessary modules here
try:
    import Levels
    import Missions
except:
    giScript.debug_stderr("Error loading module\n")
    giScript.debug_stderr(str(sys.exc_info()[1]) + "\n")

def dispatchEvent(event_name, data):
    "Call 'event_name(data)' on all objects that respond to that event."
    #TODO: would a map be quicker?
    # ie, map(dispatchToObject, objects, (data,) * len(objects))

    pass

def cleanup():
    print "Cleaning up"

###############################################################################
# debug tracing
###############################################################################

class Tracer:
    def lineno(self, filename, line):
        return linecache.getline(filename, line)

    def __call__(self, frame, event, arg):
        if event == 'line':
            code = frame.f_code
            file = code.co_filename
            line = frame.f_lineno
            caughtError(self.lineno(file, line), "%s (%s)" % (file, code.co_name), line)
        return self

def settrace(tracer):
    # Start debugging from here
    try:
        raise SystemError
    except:
        if hasattr(sys, 'exc_info'):
            frame = sys.exc_info()[2].tb_frame.f_back
        else:
            frame = sys.exc_traceback.tb_frame.f_back

    while frame:
        frame.f_trace = tracer
        frame = frame.f_back

    sys.settrace(tracer)

def unsettrace():
    settrace(None)

###############################################################################
# import helpers
###############################################################################

global compileFilename
compileFilename = "<string>"

def SetCompileFilename(filename):
    global compileFilename
    compileFilename = filename

def Compile(code):
    "Return bytecode from a string."
    return compile(code, compileFilename, "exec")

#register this function so it can be called from C++
giScript.register_function(dispatchEvent)

# un-comment these lines to add debug tracing
#tracer = Tracer()
#settrace(tracer)

print "Main module loaded"

# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52192
def add_method(self, method, name=None):
  if name is None: name = method.func_name
  class new(self.__class__): pass
  setattr(new, name, method)
  self.__class__ = new
