
from __future__ import with_statement

import gtk, gobject
import gtk.gtkgl
import gtk.gdkgl
gobject.threads_init()

from glitch.camera import Camera

class GtkCamera(Camera, gtk.gtkgl.widget.DrawingArea):
    "A camera that is also a C{gtk.Widget}."

    mode = (
        gtk.gdkgl.MODE_ACCUM |
        gtk.gdkgl.MODE_RGB |
        gtk.gdkgl.MODE_DEPTH |
        gtk.gdkgl.MODE_DOUBLE |
        gtk.gdkgl.MODE_STENCIL)

    def __init__(self, **kwargs):
        glconfig = gtk.gdkgl.Config(mode=self.mode)
        gtk.gtkgl.widget.DrawingArea.__init__(self, glconfig)
        Camera.__init__(self, **kwargs)
        self.connect('expose-event', self.expose)

    def __enter__(self):
        context = gtk.gtkgl.widget_get_gl_context(self)
        drawable = self.get_gl_drawable()

        if not drawable.gl_begin(context):
            raise RuntimeError("couldn't begin GL drawing")

        return drawable.get_size()

    def __exit__(self, type, exception, traceback):
        drawable = self.get_gl_drawable()
        drawable.gl_end()
        drawable.swap_buffers()

    def expose(self, widget, e):
        with self as (w, h):
            (self.context['w'], self.context['h']) = (w, h)
            Camera.render(self, None)

    def refresh(self):
        self.queue_draw()

    def refresh_now(self):
        self.refresh()
        while gtk.events_pending():
            gtk.main_iteration()

    def make_window(self, fullscreen=False):
        w = gtk.Window()
        w.connect('destroy', lambda w: gtk.main_quit())
        w.add(self)
        if fullscreen:
            w.fullscreen()

        return w

    def run(self,fullscreen=False):
        w = self.make_window(fullscreen)
        w.show_all()

        try:
            gtk.main()
        except KeyboardInterrupt:
            pass

