#!/usr/bin/python -u

"""

ECLiPt Roaster Applet

"""

from sys import path

path.append("/usr/lib/eroaster")

import gnome.applet
import log4py
import os
import GDK

from constants import title, version, eraDataCD, eraAudioCD, eraCopyCD, iconpath, eraCDImage
from tools import split, TRUE, FALSE, cleanlist
from string import replace, strip, lower, join
from time import sleep
from types import InstanceType
from gtk import mainloop, create_pixmap_from_xpm, GtkPixmap, timeout_add, events_pending
from gtk import mainiteration, DEST_DEFAULT_DROP, DEST_DEFAULT_MOTION
from gnome.ui import STOCK_MENU_ABOUT, GnomeAbout, GnomeErrorDialog
try:
    from gnome.tools import targets
except:
    from gnometools import targets

class ERoasterApplet:

    def __init__(self):
        self.log4py = log4py.Category()
        self.applet = gnome.applet.AppletWidget("eroaster")
        self.applet.set_tooltip("%s %s" % (title, version))
        self.applet.register_stock_callback("about", STOCK_MENU_ABOUT, ("About"), self.about_eroaster_applet)
        self.applet.set_events(self.applet.get_events() | GDK.BUTTON_PRESS_MASK | GDK.ENTER_NOTIFY_MASK | GDK.LEAVE_NOTIFY_MASK)
        self.applet.connect("button_press_event", self.run_eroaster)
        self.applet.connect("enter_notify_event", self.__ERoasterApplet__highlight_applet)
        self.applet.connect("leave_notify_event", self.__ERoasterApplet__darken_applet)
        self.applet.connect("drag_data_received", self.__ERoasterApplet__dnd_receive)
        self.applet.drag_dest_set(DEST_DEFAULT_DROP | DEST_DEFAULT_MOTION, targets, GDK.ACTION_COPY | GDK.ACTION_MOVE)

        self.pixbright, self.maskbright = create_pixmap_from_xpm(self.applet, None, "%s/applet-bright.xpm" % iconpath)
        self.pixdark, self.maskdark = create_pixmap_from_xpm(self.applet, None, "%s/applet.xpm" % iconpath)
        self.pixburn, self.maskburn = create_pixmap_from_xpm(self.applet, None, "%s/applet-burn.xpm" % iconpath)
        self.app_pix = GtkPixmap(self.pixdark, self.maskdark)
        self.app_pix.show()

        self.burning = FALSE

        self.applet.add(self.app_pix)
        self.applet.show()

    # Drag and Drop data receive
    def __ERoasterApplet__dnd_receive(self, window, context, x, y, data, info, time):
        filenames = cleanlist(split(data.data,"\n"))
        startuptype = None
        files = ""
        if (len(filenames) == 1):
            filename = strip(filenames[0])
            if (filename[:5] == "file:"):
                filename = filename[5:]
            if (filename[:7] == "/dev/cd") or (filename[:8] == "/dev/scd"):
                startuptype = eraCopyCD
            elif (os.path.isdir(filename)):
                startuptype = eraDataCD
                filelist = os.listdir(filename)
                for i in range(len(filelist)):
                    filelist[i] = "%s/%s" % (filename, filelist[i])
                filename = join(filelist, "\" \"")
            elif (self.__ERoasterApplet__isaudiofile(filename) == TRUE):
                startuptype = eraAudioCD
            elif (self.__ERoasterApplet__isisoimage(filename) == TRUE):
                startuptype = eraCDImage
            else:
                GnomeErrorDialog("Sorry, I don't know how to handle \"%s\"" % filename)
            if (startuptype != None):
                files = "\"%s\"" % (filename)
        else:
            startuptype = eraAudioCD
            for i in range(len(filenames)):
                filename = filenames[i]
                if (filename[:5] == "file:"):
                    filename = filename[5:]
                filename = replace(filename, "%20", " ")
                filename = replace(filename, "\000", "")
                filename = strip(filename)
                if (self.__ERoasterApplet__isaudiofile(filename) == FALSE) and (startuptype == eraAudioCD):
                    startuptype = eraDataCD
                files = "%s \"%s\"" % (files, filename)

        if (startuptype != None):
            self.run_eroaster("%s %s" % (startuptype, files))

    # Highlight the applet icon when moving the mouse over it
    def __ERoasterApplet__highlight_applet(self, *args):
        if (self.burning == FALSE):
            self.app_pix.set(self.pixbright, self.maskbright)

    # Darken the applet icon when mouse leaves the icon
    def __ERoasterApplet__darken_applet(self, *args):
        if (self.burning == FALSE):
            self.app_pix.set(self.pixdark, self.maskdark)

    # Checks, wether a file is a audio file or not
    def __ERoasterApplet__isaudiofile(self, filename):
        extension = lower(os.path.splitext(filename)[1])
        if (extension == ".mp3") or (extension == ".wav") or (extension == ".ogg"):
            return TRUE
        else:
            return FALSE

    def __ERoasterApplet__isisoimage(self, filename):
        extension = lower(os.path.splitext(filename)[1])
        if (extension == ".iso") or (extension == ".img"):
            return TRUE
        else:
            return FALSE
        
    def run_eroaster(self, args, event = None):
        if (type(args) == InstanceType):
            args = ""
        command = "eroaster %s" % (args)
        self.execute(command)

    # Execute some command
    def execute(self, command):
        self.log4py.debug("Executing: %s" % command)
        self.burning = TRUE
        self.app_pix.set(self.pixburn, self.maskburn)
        result = os.fork()
        if (result == 0):
            os.execv("/usr/bin/env", ["/usr/bin/env"] + split(command, " ", "\""))
        else:
            pid = 0
            while (pid == 0):
                sleep(0.1)
                pid = os.waitpid(result, os.WNOHANG)[0]
                while (events_pending()):
                    mainiteration()
            self.app_pix.set(self.pixdark, self.maskdark)
            self.burning = FALSE

    # Define a About Box
    def about_eroaster_applet(self, args):
        description = 'ERoaster is a GNOME frontend for writing, copying and grabbing data and audio CDs using cdrecord, mkisofs and some other tools.'
        description = "%s\nAvailable from:\n     http://www.eclipt.at\n     http://www.its4you.at\n     http://eroaster.sourceforge.net" % description
        description = "%s\nSend comments, bug reports or any other to the e-mail address above." % description
        GnomeAbout(title, version, 'May be distributed under the terms of the GPL2', ['Martin Preishuber (Martin.Preishuber@eclipt.at)'], description).show()

    def clean_handler(self):
        return TRUE

    # Main program
    def main(self):
        self.cleanhandler = timeout_add(1000, self.clean_handler)
        mainloop()

eroaster_applet = ERoasterApplet()
eroaster_applet.main()
