#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (C) 2008  
#	Pietro Montorfano <monto@telefoninux.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.


import elementary
import dbus, e_dbus
import time
import os

TITLE                    = "Notifier"

DIALER_ICON              = "/usr/share/icons/shr/86x86/apps/openmoko-dialer.png"

MISSED_CALLS_PROGRAM     = "/usr/bin/phonelog"

CALL_1                   = " missed call"
CALL_2                   = " missed calls"

USAGE_BUSNAME            = 'org.freesmartphone.ousaged'
USAGE_OBJECTPATH         = '/org/freesmartphone/Usage'
USAGE_INTERFACE          = 'org.freesmartphone.Usage'

GSM_BUSNAME              = 'org.freesmartphone.ogsmd'
GSM_OBJECTPATH           = '/org/freesmartphone/GSM/Device'
GSM_CALL_INTERFACE       = 'org.freesmartphone.GSM.Call'

SECONDS_FOR_RETRY        = 5

system_bus               = None
gsm_bus                  = None
gsm_call_iface           = None
usage_bus                = None
usage_iface              = None
call_active              = ""
missed_calls               = {}

### UI functions
def update_ui():
    lost_call_count = 0
    for (key, value) in missed_calls.iteritems():
        lost_call_count += len(value)
        
    if (lost_call_count == 1):
        label.label_set(str(lost_call_count) + CALL_1)
    elif (lost_call_count > 1):
        label.label_set(str(lost_call_count) + CALL_2)

    if ((lost_call_count == 0) or (missed_calls == {})):
        win.hide()
    else:
        win.show()

## here's the main function, using args so that it doesn't crash even if new parameters will be added
def call_signal_handler(sender = "", *args, **kwargs):
    global call_active
    call_status = str(args[0])
    if (args[1].has_key("peer")):
        caller = str(args[1]["peer"])
    else:
        caller = call_active

    if (call_status == "incoming"):
        call_active = caller
    elif ((call_status == "active") and (call_active != "")):
        call_active = ""
    elif ((call_status == "release") and (call_active != "")):
        if (missed_calls.has_key(call_active)):
            missed_calls[call_active].append(time.time())
        else:
            missed_calls[call_active] = [time.time()]
        update_ui()
        
## elementary standard signal
def destroy(obj = None, event = None, data = ""):
    global missed_calls
    missed_calls.clear()
    win.hide()
    
def show_missed_calls(*args, **kwargs):
    global missed_calls
    missed_calls = {}
    update_ui()
    os.system(MISSED_CALLS_PROGRAM + " &")

if __name__ == "__main__":
    initialized = False
    while (not initialized):
        try:
            elementary.init()

            elementary.c_elementary.finger_size_set(100)
            elementary.c_elementary.scale_set(2.5)
            
### setting up the dbus and all the interfaces that we need
            dbus_loop = e_dbus.DBusEcoreMainLoop()
        
            system_bus = dbus.SystemBus(mainloop = dbus_loop)
            gsm_bus = system_bus.get_object(GSM_BUSNAME, GSM_OBJECTPATH)
            gsm_call_iface = dbus.Interface(gsm_bus, GSM_CALL_INTERFACE)
        
            gsm_call_iface.connect_to_signal("CallStatus", call_signal_handler)
            initialized = True
            print "Let's go on"
        except:
            time.sleep(SECONDS_FOR_RETRY)
            initialized = False
            print "Retrying..."
        
        
### Now that dbus it's ok lets build the UI
    win = elementary.Window(TITLE, 1)
    win.title_set(TITLE)
    win.destroy = destroy

    bg = elementary.Background(win)
    win.resize_object_add(bg)
    bg.show()
    
    box_main = elementary.Box(win)
    box_main.size_hint_weight_set(-1.0, 0.0)
    box_main.size_hint_align_set(-1.0, 0.0)
    win.resize_object_add(box_main)
    box_main.show()
        
    frame = elementary.Frame(win)

    box = elementary.Box(frame)

    frame.content_set(box)
    frame.show()

    frame.label_set("Calls")

    box_main.pack_end(frame)

    label = elementary.Label(frame)
    label.label_set(CALL_1)
    label.scale_set(2.0)

    label.show()
    box.show()

    frame.size_hint_weight_set(-1.0, 0.0)
    frame.size_hint_align_set(-1.0, 0.0)

    box.pack_start(label)

    box2 = elementary.Box(frame)
    box2.horizontal_set(True)
    box2.size_hint_weight_set(1.0, 0.0)
    box2.size_hint_align_set(-1.0, 0.0)


    bt_calls = elementary.Button(win)
    bt_calls.label_set("View")
    bt_calls.size_hint_weight_set(1.0, 0.0)
    bt_calls.size_hint_align_set(-1.0, 0.0)
    bt_calls_icon = elementary.Icon(bt_calls)
    bt_calls_icon.file_set(DIALER_ICON)
    bt_calls_icon.scale_set(1, 1)
    bt_calls.icon_set(bt_calls_icon)
    bt_calls.clicked = show_missed_calls
    bt_calls.show()    

    button2 = elementary.Button(frame)
    button2.label_set("Close")
    button2._callback_add('clicked', destroy)
    button2.size_hint_align_set(-1.0, 0.0)

    button2.show()

    box2.pack_start(bt_calls)
    box2.pack_end(button2)

    box2.show()

    box.pack_end(box2)


### ok, let's go!!    
    update_ui()

    elementary.run()
    elementary.shutdown()
