#!/usr/bin/env python

import sys
import random

try:
    import pygtk
    pygtk.require("2.0")
except:
    print("pygtk Not Availible")
    sys.exit(1)
try:
    import gtk
except:
    print("GTK Not Availible")
    sys.exit(1)

def treeview_manage_edit(tv, editable, edit_handler=None):
    cols = tv.get_columns()
    for n, col in enumerate(cols):
        cells = col.get_cell_renderers()
        for cell in cells:
            cell.set_property('editable', editable)
            if edit_handler:
                cell.connect("edited", edit_handler, n)

def treeview_enable_edit(tv, edit_handler):
    cols = tv.get_columns()
    for n, col in enumerate(cols):
        cells = col.get_cell_renderers()
        for cell in cells:
            cell.set_property('editable', True)
            cell.connect("edited", edit_handler, n)

def treeview_disable_edit(tv):
    cols = tv.get_columns()
    for col in cols:
        cells = col.get_cell_renderers()
        for cell in cells:
            cell.set_property('editable', False)

def get_statusbar_text(sb):
    frame = sb.get_children()[0]
    hbox = frame.get_children()[0]
    lbl = hbox.get_children()[0]
    return lbl.get_text()

def get_app_random(config):
    if config.getboolean('operations', 'alt_random'):
        rand = random.SystemRandom()
    else:
        rand = random
    rand.seed()
    return rand

def simple_dialog(Prompt="Enter value: ", parent=None, text=None):
    dialog = gtk.Dialog(Prompt, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 
        buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
    hb = gtk.HBox(True)
    hb.show()
    lbl = gtk.Label(Prompt)
    lbl.show()
    hb.pack_start(lbl)
    entry = gtk.Entry()
    if text:
        entry.set_text(text)    
    hb.pack_start(entry)
    entry.show()
    aa = dialog.get_content_area()
    aa.pack_end(hb)
    ret = ''
    if dialog.run() == gtk.RESPONSE_OK:
        ret = entry.get_text()
    dialog.destroy()
    return ret

def simple_spin_dialog(title=None, parent=None):
    dialog = gtk.Dialog(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 
        buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
    adj = gtk.Adjustment(value=10, lower=1, upper=1000000, step_incr=1, page_incr=10)
    spin = gtk.SpinButton(adj)
    spin.show()
    aa = dialog.get_content_area()
    aa.pack_end(spin)
    ret = 0
    if dialog.run() == gtk.RESPONSE_OK:
        ret = spin.get_value_as_int()
    dialog.destroy()
    return ret

def check_dependencies(module_list):
    ret = []
    for module in module_list:
        try:
            __import__(module)
        except:
            ret.append(module)
    return ret

def textview_add_widget(textview, offset, widget):
    textbuffer = textview.get_buffer()
    iter = textbuffer.get_iter_at_offset(offset)
    iter.backward_line()
    iter.forward_line()
    anchor = textbuffer.create_child_anchor(iter)
    textview.add_child_at_anchor(widget, anchor)

def get_text_buffer(textview):
    buffer = textview.get_buffer()
    start = buffer.get_start_iter()
    end = buffer.get_end_iter()
    return buffer.get_text(start, end)

def get_selection_text(textview):
    buffer = textview.get_buffer()
    if not buffer.get_has_selection(): return False
    text = get_text_buffer(textview)
    text = unicode(text.decode('utf8'))
    sel = buffer.get_selection_bounds()
    return text[sel[0].get_offset():sel[1].get_offset()]

def set_text_buffer(textview, text):
    textview.get_buffer().set_text(text)

def varname_is_valid(var_name):
    x = '{0}=1'.format(var_name)
    try:
        exec(x)
        return True
    except:
        return False

def make_treeview(column_types, column_names, editable=False, edit_handler=None):
        liststore = gtk.ListStore(*column_types)
        treeview = gtk.TreeView(liststore)
        treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)        
        for n in range(len(column_names)):
            tvcolumn = gtk.TreeViewColumn(column_names[n])
            treeview.append_column(tvcolumn)
            cell = gtk.CellRendererText()
            if editable:
                cell.set_property('editable', True)
                if edit_handler:
                    cell.connect("edited", edit_handler, n)
            tvcolumn.pack_start(cell, True)
            tvcolumn.add_attribute(cell, 'text', n)
            tvcolumn.set_resizable(True)
            tvcolumn.set_expand(True)
        return liststore, treeview

def error_dialog(window, msg, title):
    dialog = gtk.MessageDialog(window, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format = msg)
    dialog.set_title(title)
    dialog.run()
    dialog.destroy()
    return False

def create_menu(accel_group, caption, menu_items, callback):
    """
    a function to facilitate the creation of a menu based on menu_items
    tuple containing menu items'texts and a common callback. The caption of
    this menu is caption
    """
    menu = gtk.Menu()
    for item in menu_items:
        # first check if an accelarator is present (search for &)
        item_list = item.split(":")
        if len(item_list) == 2:
            item, accel = item_list
        else:
            accel = None
        # if the text string for menu item caption is multiwords
        # join them with underlines to create a unique data for
        # passing to the handler (e.g. edit.copy_text)
        s = "_".join([x.lower() for x in item.replace("_", "").split()])
        c = "_".join([x.lower() for x in caption.replace("_", "").split()])
        insert_menu_item(accel_group, menu, item, accel, callback, "%s.%s" % (c, s))
    menu_item = gtk.MenuItem(caption)
    menu_item.show()
    menu_item.set_submenu(menu)
    return menu_item

def insert_menu_item(accel_group, menu, caption, accel, callback, data):
    """
    a function to simplify the menu item creation job
    menu: which menu this item append to
    caption: the text for this menu item
    callback: the handler function for this menu item
    data: data to be passed to the handler
    """
    if caption != '-':
        try:
            stock = eval("gtk.STOCK_" + "_".join(caption.replace("_", "").upper().split()))
        except AttributeError:
            stock = caption
    if caption != '-':
        menu_item = gtk.ImageMenuItem(stock)
        menu.append(menu_item)
        menu_item.connect("activate", callback, data)
        if accel:
            key, mod = gtk.accelerator_parse(accel)
            menu_item.add_accelerator("activate", accel_group, key, mod, gtk.ACCEL_VISIBLE)
    else:
        menu_item = gtk.SeparatorMenuItem()
        menu.append(menu_item)
    menu_item.show()

def add_tool_button(toolbar, label, image, callback, data=None):
    tool_button = gtk.ToolButton(image)
    tool_button.set_label(label)
    tool_button.connect("clicked", callback, data)
    tool_button.show()
    toolbar.insert(tool_button, -1)

def select_file(window, title, action):
    """
    A generic method returning file name
    """
    stock = {gtk.FILE_CHOOSER_ACTION_OPEN: gtk.STOCK_OPEN, gtk.FILE_CHOOSER_ACTION_SAVE: gtk.STOCK_SAVE}
    buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, stock[action], gtk.RESPONSE_OK)
    fdialog = gtk.FileChooserDialog(title, window, action, buttons)
    fdialog.set_default_response(gtk.RESPONSE_OK)
    response = fdialog.run()
    if response == gtk.RESPONSE_OK:
        file_name = fdialog.get_filename()
    else:
        file_name = None
    fdialog.destroy()
    return file_name

def build_iconset(img_file):
    img = gtk.Image()
    img.set_from_file(img_file)
    img.show()
    pixbuf = img.get_pixbuf()        
    return gtk.IconSet(pixbuf)

def add_icon(icon_id, icon_label, icon_file, icon_factory):
    icon_set = build_iconset(icon_file)
    icon_factory.add(icon_id, icon_set)
    gtk.stock_add([(icon_id, icon_label, 0, 0, None)])

def strip_ml_tags(in_text):
	"""Description: Removes all HTML/XML-like tags from the input text.
	Inputs: s --> string of text
	Outputs: text string without the tags
	
	# doctest unit testing framework

	>>> test_text = "Keep this Text <remove><me /> KEEP </remove> 123"
	>>> strip_ml_tags(test_text)
	'Keep this Text  KEEP  123'
	"""
	# convert in_text to a mutable object (e.g. list)
	s_list = list(in_text)
	i,j = 0,0
	
	while i < len(s_list):
		# iterate until a left-angle bracket is found
		if s_list[i] == '<':
			while s_list[i] != '>':
				# pop everything from the the left-angle bracket until the right-angle bracket
				s_list.pop(i)
				
			# pops the right-angle bracket, too
			s_list.pop(i)
		else:
			i=i+1
			
	# convert the list back into text
	join_char=''
	return join_char.join(s_list)
    # a better way is to use re
    # p = re.compile('<.*?>')
    # return p.sub('', data)
