"""
adesklets initializer module
"""

from sys import _getframe, argv, stdin
from os import getenv, putenv
from os.path import basename
from time import sleep
import re

from error_handler import *
from singleton import _Singleton, _States
from children_handler import _Children_handler
from communicator import _Communicator
from commands_handler import _Commands_handler
from which import Which

class _Initializer(_Singleton, _States):
    """
    Initialize the whole modules global instances.
    """
    def __init__(self, debug=False):
        """
        Initialize the whole adesklets thing. Set debug to True
        to avoid problem raising exceptions.
        """
        _Singleton.__init__(self,'_initializer')
        _States.__init__(self)
        self.hdlrs = [ _Children_handler() ]
        # Determine stack lowest frame
        i=0
        while 1:
            try:
                _getframe(i)
            except ValueError:
                break
            i+=1
        i-=1;
        # Use it to find canonical applet name
        if _getframe(i).f_locals.has_key('__file__'):
           script_name = Which(_getframe(i).f_locals['__file__']).run()
           if script_name is None:
               script_name=':'
        else:
            script_name=':'

        # Special treatment for help
        if '--help' in argv[1:] or '-h' in argv[1:]:
            putenv('ADESKLETS_EMBEDDED','1')
            comm=_Communicator('adesklets', ['--help'])
            try:
                while 1:
                    out = comm.out(.1)
                    if out: print out,
            except ADESKLETSError:
                pass
            raise ADESKLETSError(5)

        # Filtering out unsupported options
        for opt in ('-f',
                    '-k', '--killall',
                    '-c', '--cleanup',
                    '-i', '--installer',
                    '-v', '--version'):
            if opt in argv[1:]:
                raise ADESKLETSError(3, 'unsupported `%s\' option.' % opt)

        # Added warning mecanism.
        if getenv('ADESKLETS_ID') is None:
            if stdin.isatty():
                if raw_input('Do you want to (r)egister this desklet ' +
                             'or to (t)est it? ').lower() == 't':
                    print '\n'.join(
                        ['Now testing...',
                         '='*60,
                         'If you do not see anything (or just an initial flicker',
                         'in the top left corner of your screen), try `--help\',',
                         'and see the FAQ: `info adesklets\'.',
                         '='*60])
                    script_name=':'
        # Filter out pydoc too
        if basename(script_name) == 'pydoc': script_name=':'
            
        self._States__shared_state.setdefault('script_name',script_name)
        comm=_Communicator('adesklets', argv[1:] + [script_name])
        self._States__shared_state.setdefault('communicator', comm)

        re_event=re.compile('^event:')
        re_event_ready=re.compile('^event: ready!$')
        while 1:
            # Loop until the ready event in sent.
            # Raise initialization exception error on first problem.
            event=comm.err(.1)
            if event:
                if re_event.match(event):
                    if re_event_ready.match(event):
                        break
                else:
                    if not debug:
                        raise ADESKLETSError(3,event)
                    else:
                        print event

        self._States__shared_state.setdefault('commands_handler',
                                              _Commands_handler())
        
        # New behavior, bail out on unregistered desklet that needs registering
        if getenv('ADESKLETS_ID') is None and script_name != ':':
            print 'Registered. Run \'adesklets\' to (re)start your desklets.'
            print 'Look at \'adesklets --help\' for special options.'
            print >> comm, 'quit'
            try:
                sleep(10)
            except ADESKLETSError:
                raise ADESKLETSError(5)
            
    def __del__(self):
        _States.__del__(self)
        _Singleton.__del__(self)
