#!/usr/bin/python
import cairo
import gtk
import gtk.gdk
import gobject
import math
import serial
import struct
import sys

class Gauge (gtk.DrawingArea):
    def __init__(self):
        super(Gauge, self).__init__()

        self.gauge_arc = 1.5*math.pi #270 degrees
        self.value1 = .25
        self.value2 = .25

        self.connect("expose_event", self.expose)

    def expose(self, widget, event):
        context = widget.window.cairo_create()
        # set a clip region for the expose event
        context.rectangle(event.area.x, event.area.y,
                          event.area.width, event.area.height)
        context.clip()
        self.draw_face(context)
        self.draw_value(context)
        return False #don't need to repeat this event   

    def context_center(self):
        rect = self.get_allocation()
        center_x = rect.x + rect.width / 2.0
        center_y = rect.y + rect.height / 2.0
        return (center_x, center_y)

    def draw_face(self, context):        
        #fill with black
        context.set_source_rgb(0,0,0)
        context.paint()

    def draw_value(self, context):
        #context data
        rect = self.get_allocation()

        #draw first circle
        rad1 = self.value1*.5*rect.width
        context.arc(.33*rect.width, .5*rect.height, rad1, 0, 2*math.pi)

        context.set_source_rgba(1,.2,.2,.5)
        context.set_line_width(3)
        context.set_line_cap(cairo.LINE_CAP_ROUND)
        context.fill_preserve()
        context.set_source_rgba(1,.2,.2,.75)
        context.stroke()

        #draw second circle
        rad1 = self.value2*.5*rect.width
        context.arc(.66*rect.width, .5*rect.height, rad1, 0, 2*math.pi)

        context.set_source_rgba(.5,.5,1,.5)
        context.set_line_width(3)
        context.set_line_cap(cairo.LINE_CAP_ROUND)
        context.fill_preserve()
        context.set_source_rgba(.5,.5,1,.75)
        context.stroke()

    def timer_cb(self):
        #read value from board and redraw
        lines = ser.readlines()
        data = lines[-1].strip()
        if len(data) == 3:
            values = struct.unpack("BBB", data)
            self.value1 = values[1]/255.0
            self.value2 = values[2]/255.0
            #print values

        self.redraw()
        return True

    def redraw(self):
         if self.window:
            alloc = self.get_allocation()
            self.queue_draw_area(alloc.x, alloc.y, alloc.width, alloc.height)
            self.window.process_updates(True)

#gobals
ser = None

#MAIN   
def main():
    global ser
    ser = serial.Serial(sys.argv[1], 19200, timeout=.001)
    
    window = gtk.Window()
    gauge = Gauge()

    window.add(gauge)
    window.connect("destroy", gtk.main_quit)
    window.show_all()

    timer = gobject.timeout_add(100, gauge.timer_cb)
    gtk.main()

if __name__ == "__main__":
    main()
