#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import clutter
import cluttergtk
import gobject
import gtk
import champlain
import champlaingtk

class LauncherGTK:

    def __init__(self):
        self.window = gtk.Window()
        self.window.set_border_width(10)
        self.window.set_title("Move a marker")

        self.window.connect("destroy", lambda w: gtk.main_quit)

        vbox = gtk.VBox(False, 12)

        self.view = champlain.View()
        self.view.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC)
        self.view.set_property("zoom-on-double-click", False)
    
        self.layer = MarkerLayer()

        marker = self.layer.add_marker("Marker title", 38.575935, -7.921326)

        self.view.add_layer(self.layer)

        embed = cluttergtk.Embed()
        embed.set_size_request(640, 480)
        
        self.view.set_reactive(True)
        self.view.connect("button-release-event", self.champlain_view_click, self.view, marker)

        bbox = gtk.HBox(False, 6)
        button = gtk.Button(stock=gtk.STOCK_ZOOM_IN)
        button.connect("clicked", self.zoom_in)
        bbox.add(button)

        button = gtk.Button(stock=gtk.STOCK_ZOOM_OUT)
        button.connect("clicked", self.zoom_out)
        bbox.add(button)
        
        combo = gtk.combo_box_new_text()
        self.map_source_factory = champlain.map_source_factory_dup_default()
        liststore = gtk.ListStore(str, str)
        for source in self.map_source_factory.dup_list():
            liststore.append([source["id"], source["name"]])
            combo.append_text(source["name"])
        combo.set_model(liststore)
        combo.set_attributes(combo.get_cells()[0], text=1)
        combo.set_active(0)
        combo.connect("changed", self.map_source_changed)
        bbox.add(combo)
        
        self.spinbutton = gtk.SpinButton(gtk.Adjustment(lower=0, upper=20, value=1, step_incr=1))
        self.spinbutton.connect("changed", self.zoom_changed)
        self.view.connect("notify::zoom-level", self.map_zoom_changed)
        self.spinbutton.set_value(5)
        bbox.add(self.spinbutton)

        self.layer.show_all()

        vbox.pack_start(bbox, expand=False, fill=False)
        vbox.add(embed)

        self.window.add(vbox)
        # we need to realize the widget before we get the stage
        embed.realize()

        stage = embed.get_stage()
        self.view.set_size(640, 480)
        stage.add(self.view)

        self.window.show_all()
        self.view.center_on(38.575935, -7.921326)
        
        self.window.connect("delete_event", self.close)

    def champlain_view_click(self, widget, event, view, marker):
        print event.click_count
        if event.button != 1 or event.click_count > 1:
            return False
        
        #print view.get_coords_from_event(event)
        (latitude, longitude) = view.get_coords_at(int(event.x), int(event.y))
        
        marker.set_position(latitude, longitude)

    def zoom_in(self, widget):
        self.view.zoom_in()

    def zoom_out(self, widget):
        self.view.zoom_out()
        
    def toggle_layer(self, widget):
        if widget.get_active():
            self.layer.show_all()
        else:
            self.layer.hide()

    def zoom_changed(self, widget):
        self.view.set_property("zoom-level", self.spinbutton.get_value_as_int())

    def map_source_changed(self, widget):
        model = widget.get_model()
        iter = widget.get_active_iter()
        id = model.get_value(iter, 0)
        source = self.map_source_factory.create(id);
        self.view.set_property("map-source", source)

    def map_zoom_changed(self, widget, value):
        self.spinbutton.set_value(self.view.get_property("zoom-level"))
        
    def close(self, widget, responde=None):
        gtk.main_quit()


class MarkerLayer(champlain.Layer):

    def __init__(self):
        champlain.Layer.__init__(self)
        self.orange = clutter.Color(0xf3, 0x94, 0x07, 0xbb)
        
        #RGBA
        self.white = clutter.Color(0xff, 0xff, 0xff, 0xff)
        self.black = clutter.Color(0x00, 0x00, 0x00, 0xff)
        
        self.hide()
        
    def add_marker(self, text, latitude, longitude, bg_color=None, text_color=None, font="Airmole 8"):
        if not text_color:
            text_color = self.black
            
        if not bg_color:
            bg_color = self.orange
        
        marker = champlain.marker_new_with_text(text, font, text_color, bg_color)

        #marker.set_position(38.575935, -7.921326)
        marker.set_position(latitude, longitude)
        self.add(marker)
        return marker
    
    # http://code.activestate.com/recipes/266466/
    # original by Paul Winkler
    def HTMLColorToRGB(self, colorstring):
        """ convert #RRGGBB to a clutter color var """
        colorstring = colorstring.strip()
        if colorstring[0] == '#': colorstring = colorstring[1:]
        if len(colorstring) != 6:
            raise ValueError, "input #%s is not in #RRGGBB format" % colorstring
        r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
        r, g, b = [int(n, 16) for n in (r, g, b)]
        return clutter.Color(r, g, b)
    
if __name__ == "__main__":
    gobject.threads_init()
    clutter.init()
    LauncherGTK()
    gtk.main()
