"""
QuickFinder
"""
#  Copyright (C) 2004  Henning Jacobs <henning@srcco.de>
#
#  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 2 of the License, or
#  (at your option) any later version.
#
#  $Id: QuickFinder.py 142 2005-09-13 21:16:23Z henning $

import sys
import os
import string
from Tkinter import *
import tkMessageBox
import Pmw
import IconImages
import debug
import broadcaster
import broker
import types
import Preferences

class QuickFinder:

    from ContactSelectboxWidget import ContactSelectboxWidget
    from ContactViewWidget import ContactViewWidget
    from HistoryWidget import HistoryWidget
    import Query
    import Bindings
    
    def __init__(self, version, model, tkroot=None):
        if not tkroot:
            tkroot = Pmw.initialise()
            tkroot.withdraw()
        self.tkroot = tkroot
        self.__version = version
        self.model = model
        
        self.initOptionDatabase()
        self.createWidgets()
        self.centerWindow()
    
        self.applyBindings()
        self.registerAtBroadcaster()
    
    def applyBindings(self, keydefs=None):
        "Apply Key-Bindings / Add, Connect to Events"
        if keydefs is None:
            keydefs = self.Bindings.default_keydefs
        self.keydefs = keydefs
        top = self.top
        for event, keylist in keydefs.items():
            if keylist:
                top.event_add(event, *keylist)
        
        top.bind("<<close-application>>", self.close)
        
    def registerAtBroadcaster(self):
        "Register our Callback Handlers"
        # Show Message Box on Notification Broadcast:
        broadcaster.Register(self.onNotification,
            source='Notification')
        broadcaster.Register(self.onContactsOpen,
            source='Contacts', title='Opened')
        broadcaster.Register(self.onCommandComposeLetter,
            source='Command', title='Compose Letter')
    
    def initOptionDatabase(self):
        try:
            family, size, mod = Preferences.get('client.font', types.ListType)
        except:
            family = None
        if family:
            self.tkroot.option_add("*font", (family, size, mod))
        if sys.platform != 'win32':
            # Enable 'MouseOver'-highlighting of buttons, etc:
            self.tkroot.option_add("*activeBackground", "#ececec")
            self.tkroot.option_add("*activeForeground", "black")
            # I prefer windows-alike look on unix:
            # (Listbox, Entry and Text widgets have grey background
            # on unix per default)
            self.tkroot.option_add("*Listbox*background", "white")
            # 2004-02-27: I no longer want flat listboxes:
            # self.tkroot.option_add("*Listbox*relief", "flat")
            self.tkroot.option_add("*Entry*background", "white")            
            self.tkroot.option_add("*Text*background", "white")          
        
    def createWidgets(self):
        "create the top level window"
        #self._menubar = Menu(self.tkroot)
        top = self.top = Toplevel(self.tkroot, class_='PyCoCuMa')
        top.protocol('WM_DELETE_WINDOW', self.close)
        top.title('PyCoCuMa %s' % self.__version)
        top.iconname('PyCoCuMa')
        try:
            os.chdir(os.path.dirname(sys.argv[0]))
            if sys.platform == "win32":
                top.iconbitmap("pycocuma.ico")
            else:
                top.iconbitmap("@pycocuma.xbm")
                top.iconmask("@pycocuma_mask.xbm")
        except:
            debug.echo("Could not set TopLevel window icon")

        top.rowconfigure(1, weight=1)
        top.columnconfigure(0, weight=1)
        top.withdraw()

        import ToolTip
    
        ## Top Bar:
        topbar = Frame(top)
        topbar.grid(sticky=W+E)
        topbar.columnconfigure(0, weight=1)
    
        self.selContact = self.ContactSelectboxWidget(topbar, self.model, self.openContact, label_text='')
        self.selContact.grid(sticky=W+E, padx=2, pady=2)

        self.history = self.HistoryWidget(topbar, command = self.openContactFromHistory)
        self.history.grid(column=1, row=0, sticky=W+E+N+S, padx=2, pady=2)
        self.history.configure(state="disabled")

        self.btnCloseContactView = Button(topbar, text="Collapse", command=self.closeContactView)
        self.btnCloseContactView.grid(column=2, row=0, sticky=W+E, padx=2, pady=2)
        self.btnCloseContactView["state"]=DISABLED
    
        self.btnOpenMainView = Button(topbar, text="Main Window", command=self.openMainView)
        self.btnOpenMainView.grid(column=3, row=0, sticky=W+E, padx=2, pady=2)
    
        self.contactview = None
        self.contactview = self.ContactViewWidget(top, selectcommand=self.openMainViewForEdit)
        self.contactview.grid(sticky=W+E+N+S)
        self.contactview.grid_forget()
    
    def centerWindow(self, relx=0.5, rely=0.3):
        "Center the Main Window on Screen"
        widget = self.top
        master = self.tkroot
        widget.update_idletasks() # Actualize geometry information
        if Preferences.get("client.finder_centered") != "no":
            if master.winfo_ismapped():
                m_width = master.winfo_width()
                m_height = master.winfo_height()
                m_x = master.winfo_rootx()
                m_y = master.winfo_rooty()
            else:
                m_width = master.winfo_screenwidth()
                m_height = master.winfo_screenheight()
                m_x = m_y = 0
            w_width = widget.winfo_reqwidth()
            w_height = widget.winfo_reqheight()
            x = m_x + (m_width - w_width) * relx
            y = m_y + (m_height - w_height) * rely
            if x+w_width > master.winfo_screenwidth():
                x = master.winfo_screenwidth() - w_width
            elif x < 0:
                x = 0
            if y+w_height > master.winfo_screenheight():
                y = master.winfo_screenheight() - w_height
            elif y < 0:
                y = 0
            widget.geometry("+%d+%d" % (x, y))
        widget.deiconify() # Become visible at the desired location

    def openContactFromHistory(self, handle):
        self.openContact(handle, addToHistory=False)
        
    def openContact(self, handle=None, addToHistory=True):
        "Open contact by handle or default (first)"
        if handle is None:
            handles = self.model.ListHandles()
            if handles:
                contact = self.model.GetContact(handles[0])
            else:
                contact = None
        else:
            contact = self.model.GetContact(handle)
        self.contactview.bind_contact(contact)
        if contact:
            # Inform other widgets of newly opened contact:
            self.selContact.selectContact(contact.handle())
            broadcaster.Broadcast('Contact', 'Opened',
                data={'handle':contact.handle()})
            self.contactview.grid()
            self.btnCloseContactView["text"]="Collapse"
            self.btnCloseContactView["state"]=NORMAL
        if contact and addToHistory:
            # Store in history
            self.history.addHistory(contact.handle())
        
    def closeContactView(self):
        "Close Contact Window"
        if self.btnCloseContactView["text"] == "Show":
            self.contactview.grid()
            self.btnCloseContactView["text"]="Collapse"
        else:
            self.contactview.grid_forget()
            self.btnCloseContactView["text"]="Show"

    mainview = None
    def createMainView(self):
        if not self.mainview:
            from MainView import MainView
            self.mainview = MainView(self.__version, self.model,
                tkroot=self.tkroot, slavewindow=True)
            broadcaster.Broadcast("Contacts", "Opened")
    
    def openMainView(self):
        "Open the Main Window"
        self.createMainView()
        self.mainview.openContact(self.contactview.cardhandle())
        self.mainview.deiconify()
        
    def openMainViewForEdit(self, cardhandle):
        "Open the Main Window and edit Contact"
        self.createMainView()
        self.mainview.editContact(cardhandle)
        self.mainview.deiconify()
        
    def onNotification(self):
        "Show Messagebox on Notification"
        title = broadcaster.CurrentTitle()
        showdialog = False
        if title == 'Error': 
            icon = tkMessageBox.ERROR
            showdialog = True
        elif title == 'Status':
            pass
        elif title == 'Event':
            pass
        else:
            icon = tkMessageBox.WARNING
            showdialog = True
        if showdialog:
            m = tkMessageBox.Message(
                title=title,
                message=broadcaster.CurrentData()['message'],
                icon=icon,
                type=tkMessageBox.OK,
                master=self.top)
            m.show()        
    
    def onContactsOpen(self):
        "Callback, triggered on Broadcast"
        self.selContact.focus_set()

    def onCommandComposeLetter(self):
        "Redirect to MainView"
        self.createMainView()
        self.mainview.onCommandComposeLetter()
        
    def close(self, event=None):
        self.tkroot.quit()
        self.top.destroy()
        
    def window(self):
        "Returns Tk's TopLevel Widget"
        return self.top
    
    def withdraw(self):
        "Withdraw: Forward to TopLevel Method"
        self.top.withdraw()
    
    def deiconify(self):
        "DeIconify: Forward to TopLevel Method"
        self.top.deiconify()
        

