#!/usr/bin/env python
try: 
	import gconf 
except: 
	from gnome import gconf
import gtk
import pygtk
import os
import re
from copy import deepcopy

import osso
import hildon

osso_c = osso.Context("dbus-scripts-settings", "1.1", False)

filename = "/etc/dbus-scripts.d/dbus-scripts-settings"
comment_characters = ['#', ';']
config_seperator = '\n'
conf=[]
conf_client = gconf.client_get_default ()

class dssettings(hildon.Program):

    def __init__(self):
	hildon.Program.__init__(self)

	self.main_window = hildon.Window()
        self.main_window.connect("destroy", self.destroy_main)
	self.add_window(self.main_window)

        self.btaddr_regex = re.compile("^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$")

    	try:
        	self.file = open(filename)
        	self.raw = self.file.read().strip()
        	self.temp = self.raw.split(config_seperator)
        	self.temp = [line for line in self.temp if line]
		for item in self.temp:
			if str(item.strip())[0] not in comment_characters:
				conf.append(item.split())
	except IOError:
		temp=1

	vbox = gtk.VBox(False, 0)
	self.main_window.add(vbox)
	vbox.show()

        self.model = gtk.ListStore(str, str, str, str, str, str, str, str)
        self.treeview = gtk.TreeView(self.model)
        #self.treeview.connect("row-activated", self.list_handler)
        self.sender_column = gtk.TreeViewColumn('sender')
        self.dest_column = gtk.TreeViewColumn('dest')
#        self.path_column = gtk.TreeViewColumn('path')
        self.interface_column = gtk.TreeViewColumn('interface')
        self.member_column = gtk.TreeViewColumn('member')
        self.extra_column = gtk.TreeViewColumn('extra')
        self.command_column = gtk.TreeViewColumn('Command')

	self.treeview.append_column(self.sender_column)
        self.treeview.append_column(self.dest_column)
#        self.treeview.append_column(self.path_column)
        self.treeview.append_column(self.interface_column)
        self.treeview.append_column(self.member_column)
        self.treeview.append_column(self.extra_column)
        self.treeview.append_column(self.command_column)

	self.sender_cell = gtk.CellRendererText()
        self.dest_cell = gtk.CellRendererText()
#        self.path_cell = gtk.CellRendererText()
        self.interface_cell = gtk.CellRendererText()
        self.member_cell = gtk.CellRendererText()
        self.extra_cell = gtk.CellRendererText()
        self.command_cell = gtk.CellRendererText()

	self.sender_column.pack_start(self.sender_cell)
        self.dest_column.pack_start(self.dest_cell)
#        self.path_column.pack_start(self.path_cell)
        self.interface_column.pack_start(self.interface_cell)
        self.member_column.pack_start(self.member_cell)
        self.extra_column.pack_start(self.extra_cell)
        self.command_column.pack_start(self.command_cell)

	i=0
        self.command_column.add_attribute(self.command_cell, 'text', i)
	i=i+1
	self.sender_column.add_attribute(self.sender_cell, 'text', i)
	i=i+1
        self.dest_column.add_attribute(self.dest_cell, 'text', i)
	i=i+1
#        self.path_column.add_attribute(self.path_cell, 'text', i)
#	i=i+1
        self.interface_column.add_attribute(self.interface_cell, 'text', i)
	i=i+1
        self.member_column.add_attribute(self.member_cell, 'text', i)
	i=i+1
        self.extra_column.add_attribute(self.extra_cell, 'text', i)
	i=i+1
        self.treeview.set_headers_visible(True)
        vbox.pack_start(self.treeview)

        self.button_box = gtk.HBox()
        self.add_bt_button = gtk.Button("Add BT")
	self.add_bt_button.connect("clicked", self.add_bt_command_dialog)
        self.add_conn_button = gtk.Button("Add Connection")
	self.add_conn_button.connect("clicked", self.add_conn_command_dialog)
        self.delete_button = gtk.Button("Delete")
        self.delete_button.connect("clicked", self.on_delete_button)
        self.save_button = gtk.Button("Save")
        self.save_button.connect("clicked", self.on_save_button)
        self.close_button = gtk.Button("Close")
        self.close_button.connect("clicked", self.destroy_main)
        self.button_box.pack_start(self.add_bt_button)
        self.button_box.pack_start(self.add_conn_button)
        self.button_box.pack_start(self.delete_button)
        self.button_box.pack_start(self.save_button)
        self.button_box.pack_start(self.close_button)
        vbox.pack_start(self.button_box)

        self.list_commands()

    def on_save_button(self, widget, data=None):
    	
    	try:
		os.system("sudo /usr/bin/dbus-scripts-helper 2")
        	self.file = open(filename,"w")
		self.file.writelines([' '.join(line)+'\n' for line in conf if line])
		self.file.write('\n')
		self.file.close()
		os.system("sudo /usr/bin/dbus-scripts-helper 1")
	except IOError:
		temp=1

    def run(self):
        self.main_window.show_all()
        gtk.main()

# ADD Connection -----------------------------------------------------------

    def add_conn_command_dialog(self, widget, data=None):
        self.add_conn_dialog = gtk.Dialog()
        self.info_label = gtk.Label("Add new command\n")
        self.connection_label = gtk.Label("Connection:")
        self.desc_label = gtk.Label("Description:")
        self.command_label = gtk.Label("Command:")
	
        self.connection_entry = gtk.combo_box_new_text()
        self.desc_entry = gtk.Entry()
        self.command_entry = gtk.Entry()

	self.conns = conf_client.all_dirs("/system/osso/connectivity/IAP")
	self.connection_entry.append_text("Any network")
	for item in self.conns:
		self.connection_entry.append_text(conf_client.get_string(item+"/name"))
	self.connection_entry.set_active(0)

        self.connection_combobox = gtk.combo_box_new_text()
        self.connection_combobox.append_text("on connect")
        self.connection_combobox.append_text("on disconnect")
        self.connection_combobox.set_active(0)

        self.add_conn_dialog.vbox.pack_start(self.connection_label)
        self.add_conn_dialog.vbox.pack_start(self.connection_entry)
        self.add_conn_dialog.vbox.pack_start(self.desc_label)
        self.add_conn_dialog.vbox.pack_start(self.desc_entry)
        self.add_conn_dialog.vbox.pack_start(self.command_label)
        self.add_conn_dialog.vbox.pack_start(self.connection_combobox)
        self.add_conn_dialog.vbox.pack_start(self.command_entry)

        button_box = gtk.HBox()
        add_conn_button = gtk.Button("Add")
        add_conn_button.connect("clicked", self.on_add_conn_button)
        close_button = gtk.Button("Close")
        close_button.connect("clicked", self.add_conn_dialog_destroy)
        button_box.pack_start(add_conn_button)
        button_box.pack_start(close_button)

        self.add_conn_dialog.vbox.pack_start(button_box)
        self.add_conn_dialog.show_all()

    def on_add_conn_button(self, widget, data=None):
        input_ok = True
	if self.connection_entry.get_active() == 0:
		connection = "*"
	else:
        	connection = self.conns[self.connection_entry.get_active()-1].split('/')[5]
        desc = self.desc_entry.get_text()
        command = self.command_entry.get_text()

        index = self.connection_combobox.get_active()
        if index == 0:
            table = "on_connect"
        else:
            table = "on_disconnect"

        if len(desc) == 0 or len(command) == 0:
            input_ok = False

        if input_ok:
            self.add_conn_command(connection, desc, command, table)
            self.add_conn_dialog.destroy()
        else:
            self.error_dialog = gtk.Dialog()
            self.error_dialog.vbox.pack_start(gtk.Label("Something is wrong with your input.\nPossible reasons:\n- Bluetooth address has a wrong format\n- The description is already in the database\n- You did not fill all fields"))
            close_button = gtk.Button("Close")
            close_button.connect("clicked", self.error_dialog_destroy)
            self.error_dialog.vbox.pack_start(close_button)
            self.error_dialog.show_all()

    def add_conn_command(self, connection, desc, command, table):
        if table == "on_connect":
		conf.append([command, "*", "*", "com.nokia.icd", "*", connection + " * CONNECTED"]);
        else:
		conf.append([command, "*", "*", "com.nokia.icd", "*", connection + " * IDLE"]);
        self.list_commands()

    def error_dialog_destroy(self, widget, data=None):
        self.error_dialog.destroy()

    def add_conn_dialog_destroy(self, widget, data=None):
        self.add_conn_dialog.destroy()

# ADD Connection  -----------------------------------------------------------



# ADD BT -----------------------------------------------------------

    def add_bt_command_dialog(self, widget, data=None):
        self.add_bt_dialog = gtk.Dialog()
        self.info_label = gtk.Label("Add new command\n")
        self.btaddr_label = gtk.Label("Device adress:")
        self.desc_label = gtk.Label("Description:")
        self.command_label = gtk.Label("Command:")
	
        self.btaddr_entry = gtk.combo_box_entry_new_text()
        self.desc_entry = gtk.Entry()
        self.command_entry = gtk.Entry()

	self.devices = conf_client.get_list("/system/bluetooth/devices", gconf.VALUE_STRING)
	for item in self.devices:
		self.btaddr_entry.append_text(item+ " (" + conf_client.get_string("/system/bluetooth/device/"+item+"/name")+")")

        self.connection_combobox = gtk.combo_box_new_text()
        self.connection_combobox.append_text("on connect")
        self.connection_combobox.append_text("on disconnect")
        self.connection_combobox.set_active(0)

        self.add_bt_dialog.vbox.pack_start(self.btaddr_label)
        self.add_bt_dialog.vbox.pack_start(self.btaddr_entry)
        self.add_bt_dialog.vbox.pack_start(self.desc_label)
        self.add_bt_dialog.vbox.pack_start(self.desc_entry)
        self.add_bt_dialog.vbox.pack_start(self.command_label)
        self.add_bt_dialog.vbox.pack_start(self.connection_combobox)
        self.add_bt_dialog.vbox.pack_start(self.command_entry)

        button_box = gtk.HBox()
        add_bt_button = gtk.Button("Add")
        add_bt_button.connect("clicked", self.on_add_bt_button)
        close_button = gtk.Button("Close")
        close_button.connect("clicked", self.add_bt_dialog_destroy)
        button_box.pack_start(add_bt_button)
        button_box.pack_start(close_button)

        self.add_bt_dialog.vbox.pack_start(button_box)
        self.add_bt_dialog.show_all()



    def on_add_bt_button(self, widget, data=None):
        input_ok = True
        btaddr = self.btaddr_entry.get_active_text().split(" ")[0]
        desc = self.desc_entry.get_text()
        command = self.command_entry.get_text()

        index = self.connection_combobox.get_active()
        if index == 0:
            table = "on_connect"
        else:
            table = "on_disconnect"

        if not self.btaddr_regex.match(btaddr):
            input_ok = False

        if len(desc) == 0 or len(command) == 0:
            input_ok = False

        if input_ok:
            self.add_bt_command(btaddr, desc, command, table)
            self.add_bt_dialog.destroy()
        else:
            self.error_dialog = gtk.Dialog()
            self.error_dialog.vbox.pack_start(gtk.Label("Something is wrong with your input.\nPossible reasons:\n- Bluetooth address has a wrong format\n- The description is already in the database\n- You did not fill all fields"))
            close_button = gtk.Button("Close")
            close_button.connect("clicked", self.error_dialog_destroy)
            self.error_dialog.vbox.pack_start(close_button)
            self.error_dialog.show_all()

    def add_bt_command(self, btaddr, desc, command, table):
        if table == "on_connect":
		conf.append([command, "*", "*", "org.bluez.Adapter", "RemoteDeviceConnected", btaddr]);
        else:
		conf.append([command, "*", "*", "org.bluez.Adapter", "RemoteDeviceDisconnected", btaddr]);
        self.list_commands()

    def error_dialog_destroy(self, widget, data=None):
        self.error_dialog.destroy()

    def add_bt_dialog_destroy(self, widget, data=None):
        self.add_bt_dialog.destroy()


# ADD BT -----------------------------------------------------------


    def on_delete_button(self, widget, data=None):
        selected = self.treeview.get_selection()
	if len(selected.get_selected_rows())>1 and len(selected.get_selected_rows()[1])>0:
        	index = selected.get_selected_rows()[1][0]
        	if index and index[0]>=0 and index[0]<len(conf):
			del conf[index[0]]
			self.list_commands()

    def list_commands(self):
        self.model.clear()

        self.command_list = deepcopy(conf)
	
	for c in self.command_list:
		while len(c)<8:
			c.append("")
	for i in self.command_list:
		if len(i) > 8:
			i[7] = ' '.join(i[7:])
			del(i[8:])
	for c in self.command_list:
		self.model.append(c)

    def destroy_main(self, widget, data=None):
        gtk.main_quit()

if __name__ == "__main__":
    app = dssettings()
    app.run()
