import sys
from pymol import opengl

"""
This module performs some nasty trickery in order to automatically
detect OpenGL errors, by wrapping each callable function with a
function which calls the function, but afterwards checks to see if an
error code was set, in which case it raises an exception

This is highly experimental.  To disable it, call the fast()
function.  To reenable it, call the careful() function.

"""

if opengl._numeric:
   from Numeric import ArrayType
   try:
      import _opengl_num
      _opengl = _opengl_num
   except ImportError:
      import _opengl
   except SystemError:
      import _opengl
   try:
      import openglutil_num
      openglutil =openglutil_num
   except ImportError:
      import openglutil
   except SystemError:
      import openglutil      
else:
   import _opengl
   import openglutil

origdict = _opengl.__dict__.copy()
origdict.update(openglutil.__dict__)

from glconst import *

_safetylevel = 0

# Constants
import glconst
constant_names = {}
for k, v in glconst.__dict__.items():
   if type(v) == type(1):
      constant_names[v] = k
   
error = origdict['glGetError']
class Error:
   def __init__(self, num):
      self.num = num
      self.str = constant_names.get(num, 'Unknown Error')
   def __str__(self):
      return '%s (%d)' % (self.str, self.num)

class CarefulFunction:
   def __init__(self, name, function):
      self.name = name
      self.func = function
   def __repr__(self):
      return "<careful function wrapper around %s>" % self.function
   def __call__(self, *args, **kw):
      # did someone check in a debug (non-production) version of this module?
      # this was _not_ done in the 1.1 release (causes huge gobs of printing
      # when the demos are run).
##        print "calling %s with %s, %s" % (self.func, args, kw)
      retval = apply(self.func, args, kw)
      err = error()
      if err:
         if _verysafe:
            raise Error(err)
         else:
            print Error(err)
      return retval

carefuldict = {}
for name, func in origdict.items():
   if callable(func):
      carefuldict[name] = CarefulFunction(name, func)
# These do the same sorts of things that the C versions would

def careful():
   cd = carefuldict.copy()
   if cd.has_key('error'): del cd['error']
   sys.modules['pymol.opengl.gl'].__dict__.update(cd)

import string
def fast():
   cd = origdict.copy()
   if cd.has_key('error'): del cd['error']
   if cd.has_key('glconst'): del cd['glconst']
   sys.modules['pymol.opengl.gl'].__dict__.update(cd)

# by default, be careful
if _safetylevel >= 1:
   careful()
else:
   fast()
if _safetylevel >= 2:
   _verysafe = 1
else:
   _verysafe = 0
   
def glGetIntegerv(*args):
   r = apply(glGetDoublev, args)
   if isinstance(r, type(())):
      return tuple(map(int, r))
   elif opengl._numeric and isinstance(r, ArrayType): 
      return tuple(r.astype('i').tolist())
   else:
      return int(r)
glGetInteger = glGetIntegerv
glGetBooleanv = glGetBoolean = glGetFloatv = glGetFloat = glGetDouble

# for b/w compatibility w/ 1.0??
GL_LEVELS = 0x0010

__version__ = '1.5.4'
