#!/usr/bin/python

# Copyright, 2010, Javier Palacios <javiplx@gmail.com>
#
# Copyright permissions given by the GPL Version 2.  http://www.fsf.org/


try :
    import location
except :
    location = None

import math

import gtk
import hildon


def on_changed(device, data):
    if not device:
        return
    if device.fix:
        data.sats.set( device.fix[4] , device.fix[5] , device.fix[7] )
        if device.satellites_in_view :
            data.send_expose(gtk.gdk.Event('expose'))
	if device.cell_info :
            if device.cell_info[0] & 1 : data.cell.set_gsm( device.cell_info[1] )
            if device.cell_info[0] & 2 : data.cell.set_wcdma( device.cell_info[2] )

# Function derived from pygps by Russell Nelson
def satv_draw(widget, event):
    win = widget.window
    if not win: return
    st = widget.get_style()
    gc = st.fg_gc[gtk.STATE_NORMAL]
    cm = widget.get_colormap()
    satv_grey = win.new_gc()
    satv_grey.foreground = cm.alloc_color(32767, 32767, 32767)
    satv_blue = win.new_gc()
    satv_blue.foreground = cm.alloc_color(0, 0, 65535)

    width , height = win.get_size()
    i = min(width, height)
    
    # start with it empty.
    win.draw_rectangle(widget.get_style().white_gc, True,
                   0, 0, width, height)

    # draw something in the center
    diameter = (i - 20) / 3
    win.draw_arc(st.black_gc, 0,
                 (width - diameter) / 2, (height - diameter) / 2,
                 diameter, diameter, 0, 360*64)
    diameter = (i - 20) * 2 / 3
    win.draw_arc(st.black_gc, 0,
                 (width - diameter) / 2, (height - diameter) / 2,
                 diameter, diameter, 0, 360*64)
    
    diameter = (i - 20)
    win.draw_arc(st.black_gc, 0,
                 (width - diameter) / 2, (height - diameter) / 2,
                 diameter, diameter, 0, 360*64)

    # Now draw the satellites...
    if widget.device :
     if widget.device.satellites :
      for sat in widget.device.satellites :
        # we draw as if we were lying on our back with our head pointing north.
        azimuth = sat[2] * (math.pi/180.0)
        # FIXME : division should come from liblocation
        elevation = 1 - float(sat[1]) / 90
        sinelev = elevation * diameter / 2.0
        x = int( width / 2 + math.sin(azimuth) * sinelev )
        y = int( height / 2 - math.cos(azimuth) * sinelev )

        if sat[4] :
            color = satv_blue
        else :
            color = satv_grey
        # sat[3] - signal strength , initial size was 32
        size = 24 + int( 24 * sat[3] / 30 )
        win.draw_arc(color, 1,
                     int(x - size/2), int(y - size/2),
                     size, size,
                     0, 360 * 64
                     )

        layout = widget.create_pango_layout( "%02d" % sat[0] )
        dx , dy = layout.get_pixel_size()
        x -= dx / 2
        y -= dy / 2
        win.draw_layout(gc, x, y, layout)

    widget.queue_draw()

class CellInfo ( gtk.Frame ) :

    def __init__ ( self , title="Cell Info" ) :
        gtk.Frame.__init__( self , title )

        vbox = gtk.VBox()
        self.add( vbox )

        self.gsmbox = gtk.HBox()
        vbox.pack_start( self.gsmbox )

        self.wcdmabox = gtk.HBox()
        vbox.pack_end( self.wcdmabox )

        self.gsmbox.pack_start( gtk.Label( "GSM Cell" ) )
        self.set_gsm()

        self.wcdmabox.pack_start( gtk.Label( "WCDMA Cell" ) )
        self.set_wcdma()

    def set_gsm ( self , info=None ) :
        if info :
            self.gsmbox.get_children()[1].set_text( "%s - %s - %s - %s" % info )
        else :
            self.gsmbox.add( gtk.Label( "None" ) )


    def set_wcdma ( self , info=None ) :
        if info :
            self.wcdmabox.get_children()[1].set_text( "%s - %s - %s" % info )
        else :
            self.wcdmabox.add( gtk.Label( "None" ) )


class GPSInfo ( gtk.Frame ) :

    def __init__ ( self , title="GPS Info" ) :
        gtk.Frame.__init__( self , title )

        vbox = gtk.VBox()
        self.add( vbox )

        self.latbox = gtk.HBox()
        vbox.pack_start( self.latbox )

        self.lonbox = gtk.HBox()
        vbox.add( self.lonbox )

        self.altbox = gtk.HBox()
        vbox.add( self.altbox )

        self.latbox.pack_start( gtk.Label( "Lat" ) )
        self.lonbox.pack_start( gtk.Label( "Lon" ) )
        self.altbox.pack_start( gtk.Label( "Height" ) )
        self.set()

    def set ( self , lat=None , lon=None , alt=None ) :
        if lat :
            self.latbox.get_children()[1].set_text( "%s" % lat )
        else :
            self.latbox.add( gtk.Label( "None" ) )
        if lon :
            self.lonbox.get_children()[1].set_text( "%s" % lon )
        else :
            self.lonbox.add( gtk.Label( "None" ) )
        if alt :
            self.altbox.get_children()[1].set_text( "%s" % alt )
        else :
            self.altbox.add( gtk.Label( "None" ) )



def destroy ( widget ) :
    gtk.main_quit()


def main ( ) :

    program = hildon.Program.get_instance()

    window = hildon.Window()
    window.set_title( "GPS Checker" )

    window.connect("destroy", destroy)

    program.add_window( window )

    box = gtk.HBox()
    window.add( box )

    draw = gtk.DrawingArea()
    draw.set_size_request(256,256)
    draw.connect("expose-event", satv_draw)
    draw.device = None

    if location :
        control = location.GPSDControl.get_default()
        control.set_properties(preferred_interval=location.INTERVAL_5S)
        device = location.GPSDevice()
        device.connect("changed", on_changed, window)
        control.start()
    else :
        device = None

    draw.device = device

    box.pack_start( draw )

    info = gtk.VBox()
    box.pack_end( info )

    window.cell = CellInfo()
    info.pack_start( window.cell )

    window.sats = GPSInfo()
    info.pack_end( window.sats )

    window.show_all()
    gtk.main()

    if location :
        control.stop()

if __name__ == "__main__" :
    main()
