"""Applications used in SFL presentations"""

import re
import os
import subprocess
import shlex
import commands

"""REQUIREMENTS:

xclip
wmctrl
gnome-terminal
gqview
google-chrome
xwininfo
gedit
osd_cat (osdx-bin)
"""

class DesktopApp(object):
    """Defines a desktop app, with a window, so that we can pop it later"""
    def __init__(self, args, shell=False):
        """Execute a new program, and return the DesktopApp associated

        Includes the winid and functions to flow through the program."""
        if isinstance(args, basestring):
            args = args.split()
        print "Running: %s" % args
        p = subprocess.Popen(args, shell=shell)

        self.process = p
        self.window_id = None

    def get_winid(self):
        """If you don't call this, you'll need to override show() and close()"""
        # Get Window ID (ask for it)
        xwin = subprocess.Popen('xwininfo', stdout=subprocess.PIPE)
        content = xwin.stdout.read()
        winid = int(re.search('Window id: ([^ ]*)', content).group(1), 16)
        self.window_id = winid
        
    def show(self):
        #subprocess.Popen(["xwit", "-pop", "-id", "0x%x" % self.window_id])
        if not self.window_id:
            raise ValueError("NO WINDOW_ID. Either override show() or call get_winid() at some point")
        subprocess.Popen(["wmctrl", "-i", "-a", "0x%x" % self.window_id])
    def terminate(self):
        self.process.terminate()
    def kill(self):
        self.process.kill()
    def xkill(self):
        os.system('xkill -id 0x%x' % self.window_id)
    def close(self):
        if not self.window_id:
            raise ValueError("NO WINDOW_ID. Either override show() or call get_winid() at some point")
        subprocess.Popen(["wmctrl", "-i", "-a", "0x%x" % self.window_id])
        os.system("wmctrl -i -c 0x%x" % self.window_id)


class Clipboard(object):
    """The clipboard doesn't need to be terminated"""
    def getclip(self):
        return commands.getoutput("xclip -o")
    def setclip(self, clipboard):
        p = subprocess.Popen(["xclip", "-i"], stdin=subprocess.PIPE)
        p.stdin.write(clipboard)
        p.stdin.close()
        p.wait()
    def close(self):
        raise NotImplemented("You don't need to call close() on Clipboard")


class OSD(object):
    """On-screen display for strings and stuff. Based on osd_cat."""
    def __init__(self):
        self.maxlines = 15
        self.process = subprocess.Popen(["osd_cat", "--color=green", "--font=-adobe-courier-bold-r-*-*-34-*-*-*-*-*-*-*", "--shadow=3", "--align=right", "--pos=top", '-l', str(self.maxlines)], stdin=subprocess.PIPE)

    def show(self, message):
        """This accepts a string or a list."""
        if isinstance(message, list):
            xlines = message
        else:
            xlines = message.split("\n")
        if len(xlines) > self.maxlines:
            raise ValueError("Can't display more than %d lines" % self.maxlines)
        lines = xlines + ([''] * (self.maxlines - len(xlines) + 1))
        self.process.stdin.write('\n'.join(lines))
    def close(self):
        self.process.stdin.close()
        self.process.wait()


class Nautilus(DesktopApp):
    def __init__(self, url):
        DesktopApp.__init__(self, 'nautilus %s' % url)

class Terminal(DesktopApp):
    def __init__(self, zoom=None):
        cmd = 'gnome-terminal --working-directory=~'
        if zoom:
            cmd += " --zoom=%s" % zoom
        DesktopApp.__init__(self, cmd)

class GEdit(DesktopApp):
    def __init__(self, file=None):
        DesktopApp.__init__(self, 'gedit')
    def open(self, file):
        os.system('gedit %s' % file)

class Browser(DesktopApp):
    def __init__(self, url=None, app=None):
        execname = "google-chrome"
        if app:
            cmd = [execname, "--app=%s" % app]
        elif url:
            cmd = [execname, "%s" % url]
        else:
            cmd = execname
        DesktopApp.__init__(self, cmd)

class GQView(DesktopApp):
    def __init__(self, path=None):
        if path:
            cmd = 'gqview %s' % path
        else:
            cmd = 'gqview'
        DesktopApp.__init__(self, cmd)
        self.basename = '/tmp'
    def set_basename(self, basename):
        """Used to prefix directories when calling show() directly"""
        self.basename = basename
    def show(self, path):
        """Jump to a path or file. Make sure it's a path if you want to call
        next() afterwards."""
        if path.startswith('/'):
            fullpath = path
        else:
            fullpath = os.path.join(self.basename, path)
        os.system('gqview -r %s' % fullpath)
    open = show
    def close(self):
        os.system("gqview -r -q")
    def next(self, num=1):
        for x in range(num):
            os.system('gqview -r -n')
    def prev(self, num=1):
        for x in range(num):
            os.system('gqview -r -b')
    def last(self):
        os.system('gqview -r --last')
    def first(self):
        os.system('gqview -r --last')
    def fullscreen(self, mode=None):
        """Toggle by default, otherwise, explicit enable/disable"""
        if mode is True:
            os.system('gqview -r -fs')
        elif mode is False:
            os.system('gqview -r -fS')
        else:
            os.system('gqview -r -f')
