# -*- coding: utf-8 -*-

##
#   ADesk Bar - menu
##

import os
import sys
import gtk
from threading import Thread

import adesk.core as Core

cat_name = {'Accessories':('Utility','Accessories'),
            'Games':('Game'),
            'Graphics':('Graphics'),
            'Network':('Internet', 'Network'),
            'Office':('Office'),
            'Other':('Other'),
            'Development':('Development'),
            'Settings':('Settings', 'X-XFCE'),
            'Multimedia':('AudioVideo', 'Audio', 'Video', 'Multimedia'),
            'System':('System', 'Administration'),
            }

cat_icon = {'Accessories':'applications-accessories',
            'Games':'applications-games',
            'Graphics':'applications-graphics',
            'Network':'applications-internet',
            'Office':'applications-office',
            'Other':'applications-other',
            'Development':'applications-development',
            'Settings':'preferences-desktop',
            'Multimedia':'applications-multimedia',
            'System':'applications-system',
            }

# Find the Name / Command / Icon from .desktop file
def info_desktop(file, term_cmd=None):
    cmd, icon, name, category = None, None, '', 'Other'
    terminal = False
    try:
        cfile = open(file,"r")

        for line in cfile:
            if 'NoDisplay=true' in line: # or 'OnlyShowIn=KDE' in line:
                icon, category = None, None
                break
            elif 'Terminal=true' in line:
                terminal = True
            elif '=' in line:
                words = line.split('=')

                if words[0] == 'Name':
                    name = words[1].replace('\n','')
                    # print 'Name =', name
                    
                elif words[0] == 'Icon':
                    icon = words[1].replace('\n','')
                    
                    # sometimes , Icon is fullpath or icon name + ext
                    # why ? So here we remove ext if exist
                    if not icon == '' and not icon[0] == '/':
                        icon = icon.split('.',1)[0]
                        
                elif words[0] == 'Exec':
                    cmd = words[1].replace('\n','')
                    cmd = cmd.split('%')[0]
                    # print 'Exec :', cmd
                    
                elif words[0] == 'Categories':
                    tab = words[1].replace('\n','')
                    tab = tab.split(';')
                    #~ category = '***************************'

                    #~ if not 'X-XFCE' in tab:

                    for cat in tab:
                        found = False
                        for c_name in cat_name:
                            if cat in cat_name[c_name]:
                                category = c_name
                                found = True
                                break
                        if found:
                            break

        # if command is 'console only', launch it with terminal ..
        if terminal:
            if term_cmd:
                cmd = "%s -e %s" % (term_cmd, cmd)
            else:
                cmd = "x-terminal-emulator -e %s" % cmd

        cfile.close()

    #~ except:
        #~ print("# Error : parsing %s" % file)
        #~ pass

    except IOError as (errno, strerror):
        print "I/O error({0}): {1}".format(errno, strerror)
    except ValueError:
        print "Could not convert data to an integer."
    except:
        print "Unexpected error:", sys.exc_info()[0]
        #~ raise

    return (cmd, icon, name, category)

# Find the best icon with highest resolution for the launcher
def find_icon(icon):
    foundiconfile=None

    if icon == '' or icon == None:
        return foundiconfile

    if icon[0] == '/':
        return icon

    iconbase=('','gnome','hicolor')
    iconpath='/usr/share/icons'
    sizelist =('', 'scalable', '256x256', '128x128', '64x64', '48x48', '32x32', '24x24')
    categorylist=('actions', 'apps',"devices", 'categories','filesystems', 'places', 'status', '')
    extensionlist = ('png', 'svg', 'xpm')

    iconimagelist=[]

    for extension in extensionlist:
        if (icon.find('.'+extension) != -1):
            icon = icon.replace('.'+extension,'')

    for size in sizelist:
        for extension in extensionlist:
            for category in categorylist:
                for iconbasecat in iconbase:
                    iconfile = iconpath+"/"+iconbasecat+'/'+size+'/'+category+'/'+icon+'.'+extension
                    iconimagelist.append(iconfile)

    for extension in extensionlist:
        iconfile = '/usr/share/pixmaps/'+icon+'.'+extension
        iconimagelist.append(iconfile)

    for extension in extensionlist:
        iconfile = '/usr/share/app-install/icons/'+icon+'.'+extension
        iconimagelist.append(iconfile)

    # Seek if the files in pre-generated list exists.. first match is the best
    # return it
    for iconimage in iconimagelist:
        if os.path.exists(iconimage):
            return iconimage

    return foundiconfile

def parse_desktop_dir(term_cmd=None):
    config = {}
    Core.logINFO('scan %s and parse .desktop file ..')
    
    desktop_dir = []
    home = os.environ['HOME']
    
    for dir in ('/usr/share/applications/', 
                "%s/.local/share/applications/" % home,
                "/usr/local/share/applications/",
                "/usr/share/applications/kde4/",
                "/usr/local/share/applications/kde4/"):
        if os.path.exists(dir):
            desktop_dir.append(dir)


    for dir in desktop_dir:
        listdir = os.listdir(dir)

        for i in listdir:
            if '.desktop' in i:
                desktop_file = dir + i
                (cmd, icon, name, category) = info_desktop(desktop_file, term_cmd)

                if category:
                    if not config.has_key(category):
                        config[category] = []
                    if icon:
                        config[category].append((cmd, icon, name, desktop_file))
                    else:
                        config[category].append((cmd, 'images/def_icon.png', name, desktop_file))
                else:
                    ## No category ?
                    pass
                
    return config


class Menu():
    def __init__(self):
        self.menu = None
        self.is_ready = False

class MakeMenu(Thread):
    def __init__ (self, menu, notebook, callback_action, terminal=None):
        Thread.__init__(self)
        self.menu = menu
        self.notebook = notebook
        self.callback_action = callback_action
        self.terminal = terminal

    def run(self):

        if self.menu.menu == None:
            menu = parse_desktop_dir(term_cmd=self.terminal)
        else:
            menu = self.menu.menu

        cat_tmp = []

        for categoty in menu:
            cat_tmp.append(categoty)
        cat_tmp.sort()

        self.cat_visible = True

        for category in cat_tmp:
            #~ print category

            bBox = gtk.VBox()
            bBox.show()
            bBox.set_spacing(1)
            bBox.set_border_width(1)

            scrolled = gtk.ScrolledWindow()
            scrolled.show()
            scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
            scrolled.add_with_viewport(bBox)

            tab_box = gtk.HBox(False, 4)
            tab_label = gtk.Label(category)
            tab_icon = gtk.Image()
            tab_icon.set_from_icon_name(cat_icon[category], 24)

            tab_box.pack_start(tab_icon, False)
            tab_box.pack_start(tab_label, False)

            # needed, otherwise even calling show_all on the notebook won't
            # make the hbox contents appear.
            tab_box.show_all()

            gtk.gdk.threads_enter()
            self.notebook.append_page(scrolled, tab_box)
            gtk.gdk.threads_leave()

            for application in menu[category]:
                
                ## cmd, icon, name, category
                
                # if no name , replace with cmd
                if application[3] == '':
                    application[3] = application[1]
                
                ## if not icon = None
                if application[1]:
                    if application[1][0] == '/':
                        button = Core.image_button(application[2], application[1], 24)
                    else:
                        icon = gtk.Image()
                        icon.set_from_icon_name(application[1], 24)
                        button = Core.image_button(application[2], icon, 24)

                #~ button.set_tooltip_text(application[3])
                button.set_name(application[3])
                button.connect("button-release-event", self.callback_action, application)
                bBox.pack_start(button, False, False)

        self.menu.is_ready = True
        self.menu.menu = menu
