""" MainloopManager.py

"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__license__ = """
Straw 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.

Straw 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., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. """


import pygtk
pygtk.require("2.0")
import gtk
import gobject
import error

class MainloopManager:
    instance = None
    
    def __init__(self):
        self._idle_handlers = []
        self._timers = {}
        self._call_depth = 0

    def add_idle_handler(self, handler):
        oid = self._add_idle(handler)
        self._idle_handlers.append((oid, handler))

    def _add_idle(self, handler):
        oid = gtk.idle_add(handler)
        return oid

    def remove_idle_handler(self, handler):
        for oid, h in self._idle_handlers:
            if h == handler:
                gtk.idle_remove(oid)
                break
        else:
            error.log("no handler ", handler, " found!")

    def remove_idle_handler_by_id(self, oid):
        gtk.idle_remove(oid)

    def call_pending(self):
        if self._call_depth > 0:
            error.log("Trying re-entry! Not allowed.")
            return
        self._call_depth += 1
        try:
            for oid, handler in self._idle_handlers:
                self.remove_idle_handler_by_id(oid)
            while gtk.events_pending():
                gtk.main_iteration(False)

            for index in xrange(len(self._idle_handlers)):
                oid, handler = self._idle_handlers[index]
                new_id = self._add_idle(handler)
                self._idle_handlers[index] = (new_id, handler)
        finally:
            self._call_depth -= 1

    def set_repeating_timer(self, timeout, function, data = None):
        def f(*args):
            if not self._timers.has_key(function):
                return
            try:
                if len(args) > 0:
                    function(*args)
                else:
                    function()
            finally:
                if data is not None:
                    gobject.timeout_add(timeout, f, data)
                else:
                    gobject.timeout_add(timeout, f)
        if data is not None:
            gobject.timeout_add(timeout, f, data)
        else:
            gobject.timeout_add(timeout, f)
        self._timers[function] = True

    def end_repeating_timer(self, function):
        if self._timers.has_key(function):
            del self._timers[function]

    def get_instance(klass):
        if klass.instance is None:
            klass.instance = klass()
        return klass.instance
    get_instance = classmethod(get_instance)
