# The starting point of the OpenOffice player.

import asyncore
import optparse
import os
import Queue
import sys

import player_presentation_command
import ONELAN.logger
import player_presentation_protocol_slave
import player_protocol_definition
import player_presentation_queue_runner


class OnelanOptionParser(optparse.OptionParser):

    def exit(self, status=0, msg=None):
        if msg:
            sys.stdout.write(msg)
        sys.exit(status)


def main():
    # Parse the command line arguments and pass them to start_player.
    parser = OnelanOptionParser()
    parser.add_option('--debug', action='store_true',
                      help='Log debugging messages.')
    parser.add_option('--no-oo', action='store_false', dest="start_oo",
                      help="Don't start an instance of OpenOffice.")
    parser.add_option('--identity', type='string',
                      help='The identity of the player.')
    parser.add_option('--log-file', type='string', dest='log_file',
                      metavar='FILE', help='The file to log to.')
    parser.add_option('--log-stdout', action='store_true', dest='log_stdout',
                      help='Log to stdout.')
    parser.add_option('-o', '--openoffice', type='string', dest='openoffice',
                      metavar='PATH', help='The OpenOffice executable to use.')
    parser.add_option('--protocol-trace', action='store_true',
                      dest='protocol_trace',
                      help='Log protocol trace messages.')
    parser.set_defaults(debug=False,
                        identity='unknown',
                        log_file='logfile',
                        log_stdout=False,
                        openoffice='/usr/lib/ooo-3.0/program/soffice',
                        protocol_trace=False,
                        start_oo=True)
    options = parser.parse_args()[0]
    start_player(debug=options.debug,
                 identity=options.identity,
                 log_file=options.log_file,
                 log_stdout=options.log_stdout,
                 openoffice=options.openoffice,
                 protocol_trace=options.protocol_trace,
                 start_oo=options.start_oo)

def start_player(debug, identity, log_file, log_stdout, openoffice,
                 protocol_trace, start_oo):
    # Start the player.

    logger = ONELAN.logger.Logger('app_log_name', log_file)
    logger.setupLogging(thread_safe=True)
    logger.setProtocolTrace(protocol_trace)
    logger.setDebug(debug)
    if log_stdout:
        logger.logToStdout()

    queue = Queue.Queue(0)

    player = player_presentation_protocol_slave.OOPlayerProtocolSlave(logger,
                                                                      identity)
    runner = player_presentation_queue_runner.QueueRunner(queue,
                                                          identity,
                                                          logger.log,
                                                          openoffice,
                                                          start_oo)
    runner.start()

    logger.log.info('Presentation player: %s' % (os.getpid(),))

    def do_action(action):
        # Perform the given action.
        if isinstance(action, player_presentation_command.ImmediateCommand):
            action.set_runner(runner)
            action.run()
        else:
            queue.put(action)

    def action_factory(player, action_id, command_name, command_params):
        # Create a Command object for the given command_name.
        try:
            command = player_presentation_command.command_registry[command_name]
        except KeyError:
            player.sendResponse(
                player_protocol_definition.MSG_EncodeFatalResponse(
                    action_id,
                    ['UnsupportedCommand', command_name]
                    ))
            return player_presentation_command.NoOp(player,
                                                    action_id,
                                                    command_params)
        return command(player, action_id, command_params)

    player.add_cleanup(runner.stop)
    player.setActionFactory(action_factory)
    player.setActionHandler(do_action)
    player.connectToMaster()
    asyncore.loop()


if __name__ == '__main__':
    main()

