#! /usr/bin/env python

from __future__ import division

import gtk
import gtk.glade

def update_preview_cb(file_chooser, preview):
    filename = file_chooser.get_preview_filename()
    try:
        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 128, 128)
        preview.set_from_pixbuf(pixbuf)
        have_preview = True
    except:
        have_preview = False

    file_chooser.set_preview_widget_active(have_preview)
    return


class Screen:
    def __init__(self, name, size, offset):
        self.name = name
        self.size = size
        self.offset = offset

def get_file(description, save=False):
    if save:
        action = gtk.FILE_CHOOSER_ACTION_SAVE
    else:
        action = gtk.FILE_CHOOSER_ACTION_OPEN

    my_file_chooser = gtk.FileChooserDialog(description, action=action,
            buttons= (
                gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
    preview = gtk.Image()
    my_file_chooser.set_preview_widget(preview)
    my_file_chooser.connect("update-preview", update_preview_cb, preview)

    if save:
        my_file_chooser.set_do_overwrite_confirmation(True)

    try:
        if my_file_chooser.run() == gtk.RESPONSE_OK:
            return my_file_chooser.get_filename()
        else:
            import sys
            sys.exit(1)
    finally:
        my_file_chooser.destroy()

def main():
    from subprocess import Popen, PIPE
    randr_out = Popen(["xrandr"], stdout=PIPE).communicate()[0]
    screens = [
            Screen("VGA", (1280,1024), (0,768)),
            Screen("LVDS", (1024,768), (0,0)),
            ]

    import re
    display_re = re.compile(
            r"^([A-Za-z0-9]+)\s+connected\s+"
            "([0-9]+)x([0-9]+)"
            "\+([0-9]+)\+([0-9]+)")
    screens = []
    for line in randr_out.split("\n"):
        match = display_re.match(line)
        if match is not None:
            screens.append(Screen(match.group(1),
                    size=(int(match.group(2)), int(match.group(3))),
                    offset=(int(match.group(4)), int(match.group(5))),
                    ))

    import sys

    out = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False,
            bits_per_sample=8, 
            width=max(s.offset[0] + s.size[0] for s in screens), 
            height=max(s.offset[1] + s.size[1] for s in screens),
            )

    for s in screens:
        in_pic = gtk.gdk.pixbuf_new_from_file(
                get_file("Pick wallpaper for %s" % s.name))
        in_pic.composite(out,
                s.offset[0], s.offset[1],
                s.size[0], s.size[1],
                s.offset[0], s.offset[1],
                s.size[0] / in_pic.get_width(),
                s.size[1] / in_pic.get_height(),
                gtk.gdk.INTERP_HYPER, overall_alpha=255
                )

    out_name = get_file("Pick output filename", save=True)

    from os.path import splitext
    name, ext = splitext(out_name)
    assert ext.startswith(".")
    
    out.save(out_name, ext[1:])

    import gconf
    c = gconf.client_get_default()
    c.set_value("/desktop/gnome/background/picture_filename", out_name)

if __name__ == "__main__":
    main()
