# -*- python -*-
import pygtk
pygtk.require('2.0')
import bonobo
import xchat
import xml.sax.saxutils
import gconf
gconfclient = gconf.client_get_default()
gconfprefix = '/apps/xchatosd'

__module_name__ = 'xchatosd'
__module_version__ = '0.3'
__module_description__ = 'Notifies you of IRC message directed to you, using OSD'

def get_pref_bool(name, default):
    val = gconfclient.get('/'.join((gconfprefix, name)))
    if val is None:
        return default
    else:
        return val.get_bool()

def set_pref_bool(name, val):
    gconfclient.set_bool('/'.join((gconfprefix, name)), val)

ENABLED = get_pref_bool("enabled", True)
SHOW_FULL_MESSAGE = get_pref_bool("show_full_message", True)

def escape(text):
    return xml.sax.saxutils.escape(text, {'\\': '&apos;',
                                          '"': '&quot;'})

_osd = None
def get_osd():
    global _osd
    if _osd is not None:
        ser, cli = _osd
        try:
            # "ping" it
            ser.ref()
            ser.unref()
            return cli
        except:
            _osd = None
            print 'OSD server died!'
    if _osd is None:
        osd = bonobo.get_object('OAFIID:GNOME_OSD', 'IDL:Bonobo/Application:1.0')
        # AppClient steals one reference
        osd.ref()
        cli = bonobo.AppClient(osd)
        _osd = (osd, cli)
        return cli

def osd_show(text):
    osd = get_osd()
    if isinstance(text, unicode):
        text = text.encode('utf-8')
    err = osd.msg_send('show-full', (text,))
    if err:
        print err

def print_cb(word, word_eol, userdata):
    sender = word[0]
    channel= xchat.get_info('channel')
    text = word[1]
    message = "<span foreground='red'>%s</span> "\
              "<span weight='bold' foreground='white'>&lt;</span>%s"\
              "<span weight='bold' foreground='white'>&gt;</span>" % \
              (escape(channel), escape(sender))
    if SHOW_FULL_MESSAGE:
        message += ' ' + escape(text)
    message = "<message id='xchat' ellipsize='end'>%s</message>" % message
    if ENABLED:
        osd_show(message)
    return xchat.EAT_NONE

EVENTS = []
EVENTS.append(('Channel Action Hilight', 1))
EVENTS.append(('Channel Msg Hilight', 1))
EVENTS.append(('Private Message', 1))
EVENTS.append(('Private Message to Dialog', 1))
for event in EVENTS:
    xchat.hook_print(event[0], print_cb, event)

def unload(userdata):
    print 'Plugin ' + __module_name__ + ' ' + __module_version__ + ' unloaded.'

def osd_disable(word, word_eol, userdata):
    global ENABLED
    ENABLED = False
    set_pref_bool("enabled", ENABLED)
    print 'On Screen Display script disabled.'
    return xchat.EAT_ALL

def osd_enable(word, word_eol, userdata):
    global ENABLED
    ENABLED = True
    set_pref_bool("enabled", ENABLED)
    print 'On Screen Display script enabled.'
    return xchat.EAT_ALL

def osd_full(word, word_eol, userdata):
    global SHOW_FULL_MESSAGE
    SHOW_FULL_MESSAGE = True
    set_pref_bool("show_full_message", SHOW_FULL_MESSAGE)
    print 'On Screen Display script now displaying the message text.'
    return xchat.EAT_ALL

def osd_alert(word, word_eol, userdata):
    global SHOW_FULL_MESSAGE
    SHOW_FULL_MESSAGE = False
    set_pref_bool("show_full_message", SHOW_FULL_MESSAGE)
    print 'On Screen Display script now displaying only an OSD alert, without the message text.'
    return xchat.EAT_ALL

xchat.hook_unload(unload)
xchat.hook_command('OSD_ENABLE', osd_enable, help='/OSD_ENABLE Enable the on screen display script.')
xchat.hook_command('OSD_DISABLE', osd_disable, help='/OSD_DISABLE Disable the on screen display script.')
xchat.hook_command('OSD_FULLMESSAGE', osd_full, help='/OSD_FULLMESSAGE Display the full message text in the OSD.')
xchat.hook_command('OSD_ONLYALERT', osd_alert, help='/OSD_ONLYALERT Display only an OSD alert, without the message text.')

print 'Plugin ' + __module_name__ + ' ' + __module_version__ + ' loaded.'
