from rhentry import *
from  rhtkinter import *
from rhdialog import *
from fileselect import *
from balloon import *

##############################################
#
# Global variables
#
##############################################

# Shall we show balloons?
showballoons = 1

##############################################
#
# Utility functions
#
##############################################

def doFileSelect(strvar):
	win = FileSelectWin("*", ".", 0)
	win.master.title("Select a file")
	oldgrab = win.grab_current()
	win.grab_set()
	win.wait_window(win)
	if win.getResult() != None:
		strvar.set(win.getResult())
	else:
		strvar.set("")
	if oldgrab:
		oldgrab.grab_set()

##############################################
#
# Utility classes
#
##############################################

class FolderTabs(RHFrame):
    # This class will hopefully eventually be based on a canvas and
    # paint nice pictures of folder tabs.  In the meantime, this works...
    def addTab(self, text, command, default = 0, help = ""):
        b = Button(self, {'text':text})
        r = relay(self.callTab, b)
        b['command'] = r.cb
        self.bg = b['bg']
        self.activebackground = b['activebackground']
        self.tabs.append((b, command))
        if self.type == 'h':
        	b.pack( { 'side' : 'left', 'ipady' : '2', 'expand' : '1', 'fill' : 'x' } )
        else:
        	b.pack( { 'side' : 'top', 'ipady' : '2', 'expand' : '1', 'fill' : 'x' } )
        if default:
            self.setTab(b, 1)
        else:
            self.setTab(b, 0)
        if help and showballoons:
        	Balloon(b, help)

    def callTab(self, button):
        for tabs in self.tabs:
            if tabs[0] == button:
                tabs[1]()
                self.setTab(tabs[0], 1)
            else:
                self.setTab(tabs[0])

    def setTab(self, button, default = 0):
        if default:
            button.config({'bg':'#b3b3b3', 'activebackground':'#c6c6c6'})
        else:
            button.config({'bg':self.bg, 'activebackground':self.activebackground})

    def __init__(self, Master = None, type):
        Frame.__init__(self, Master)
        self.tabs = []    
        self.type = type

##############################################
#
# Controls
#
##############################################

class LabelledCheckbutton(RHFrame):
	def bind(self, key, action):
		self.E.bind(key, action)
	def focus_set(self):
		self.E.focus_set()
	def __init__(self, Master, text, textvar, width):
		RHFrame.__init__(self, Master)
		self.L = Label(self, {'text':text, 'width':width, 'anchor':'w'})
		self.E = Checkbutton(self, {'variable':textvar,'offvalue':'Off',
		'onvalue':'On'})
		self.L.pack({'side':'left'})
		self.E.pack({'side':'left'})

class _setit:
		def __init__(self, var, value):
				self.__value = value
				self.__var = var

		def __call__(self, *args):
				self.__var.set(self.__value)

# This is a copy of the OptionMenu in Tkinter.py, except
# it uses a tuple of values instead of stupid variable arguments
class GOptionMenu(Menubutton):
		def __init__(self, master, variable, values):
				kw = {"borderwidth": 2, "textvariable": variable,
					  "indicatoron": 1, "relief": RAISED, "anchor": "c",
					  "highlightthickness": 2}
				Widget.__init__(self, master, "menubutton", kw)
				self.widgetName = 'tk_optionMenu'
				menu = self.__menu = Menu(self, name="menu", tearoff=0)
				self.menuname = menu._w
				for v in values:
						menu.add_command(label=v, command=_setit(variable, v))
				self["menu"] = menu

		def __getitem__(self, name):
				if name == 'menu':
						return self.__menu
				return Widget.__getitem__(self, name)

		def destroy(self):
				Menubutton.destroy(self)
				self.__menu = None

class LabelledOptionMenu(RHFrame):
	def bind(self, key, action):
		self.E.bind(key, action)

	def focus_set(self):
		self.E.focus_set()

	def __init__(self, Master, text, textvar, width, vals):
		RHFrame.__init__(self, Master)
		self.L = Label(self, {'text':text, 'width':width, 'anchor':'w'})
		self.E = GOptionMenu(self, textvar, vals)
		self.L.pack({'side':'left'})
		self.E.pack({'side':'left', 'expand':'1', 'fill':'x'})

class LabelledFileEntry(RHFrame):
	def bind(self, key, action):
		self.E.bind(key, action)
	def focus_set(self):
		self.E.focus_set()
	def __init__(self, Master, text, textvar, width):
		RHFrame.__init__(self, Master)
		self.L = Label(self, {'text':text, 'width':width, 'anchor':'w'})
		self.E = Entry(self,{'textvar':textvar})
		self.B = Button(self, {'text':'Select...', 'command':Relay(doFileSelect, textvar).callback})
		self.L.pack({'side':'left'})
		self.E.pack({'side':'left', 'expand':'1', 'fill':'x'})
		self.B.pack({'side':'left', 'expand':'1', 'fill':'x'})

##############################################
#
# Different kinds of frames
#
##############################################

class SubFrame(RHFrame):
	def show(self):
		self.pack({'expand':'1', 'fill':'both'})
	def hide(self):
		self.forget()
	def addBoundControl(self, label, variable, width, type, help=""):
		if(type[0] == 'b'):
			w = LabelledCheckbutton(self, label, variable, width)
		elif(type[0] == 'm'):
			w = LabelledOptionMenu(self, label, variable, width, string.split(type[2:-1], "|"))
		elif(type[0] == 'f' or type[0] == 'D'):
			w = LabelledFileEntry(self, label, variable, width)
		else:
			w = LabelledEntry(self, label, variable, width)
		w.pack({'fill':'x'})
		if help and showballoons:
			Balloon(w, help)

class TabFrameRelay:
    def __init__(self, tframe, frame):
        self.tframe = tframe
        self.frame = frame
    def cb(self):
    	self.tframe.showFrame(self.frame)

class TabFrame(SubFrame):
	def __init__(self, Master, type = 'h'):
		SubFrame.__init__(self, Master)
		self.Frame = Frame(self, {'relief':'groove', 'bd':'4'})
 		t = Frame(self)
 		self.tabs = FolderTabs(t, type)
		self.tabs.pack({'side':'left', 'anchor':'nw'})
		if type == 'h':
			t.pack({'side':'top', 'anchor':'nw', 'fill':'x'}) 		
		else:
			t.pack({'side':'left', 'anchor':'nw', 'fill':'x'}) 		
		self.Frame.pack({'fill':'both', 'expand':'1'})
		self.currentframe = None
	def addTab(self, name, frame, help = ""):
		if not self.currentframe:
			default = 1
			self.currentframe = frame
		else:
			default = 0
		self.tabs.addTab(name, TabFrameRelay(self, frame).cb, default, help)
	def showFrame(self, f):
		if self.currentframe:
			self.currentframe.hide()
			self.currentframe = f
			self.currentframe.show()
	def show(self):
		SubFrame.show(self)
		if self.currentframe:
			self.currentframe.show()


##############################################
#
# Dialogs
#
##############################################

class MyDialog(SubFrame):
	def __init__(self, title):
		self.Master = Toplevel()
		self.Master.title(title)
		SubFrame.__init__(self, self.Master)
	def show(self):
		SubFrame.show(self)
		Button(self.Master, {'text':'Close', 'command':self.Master.destroy}).pack({'side':'right'})
		self.Master.update()
		self.Master.grab_set()
		self.Master.wait_window(self.Master)






