#!/usr/bin/env python2.5
import re
import gtk
import hildon
import time
import pango
import sys
import thread
import urllib

index = {}
dictionary = ''

def lookup(word, callback):
    print "looking up word"
    try:
        index[word.strip().lower()]
        status = True
    except:
        status = False

    return status
#    callback(word, status)

def lookupUrl(word, callback):
    print "looking up definition"
    try:
        page = urllib.urlopen('http://thefreedictionary.com/p/%s' % word)
        prog = re.compile('.*<div class="pseg">(?P<def>.*)</div>.*')
        for line in page:
            res = prog.match(line)
            if res:
                p = re.compile(r'<[^<]*?>')
                result = p.sub('',res.group('def'))
                print result
                callback(word, result)
                return
    
        result = "no definition found"
        callback(word, result)
    except:
        callback(word, "word valid, no connection for definition lookup")

class ScrabbleDict(hildon.Program):
  invalid = False

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

      self.window = hildon.Window()
      self.add_window(self.window)    
      self.window.connect("delete_event", quit)
      self.window.connect("key-press-event", self.on_key_press)
      self.window.connect("window-state-event", self.on_window_state_change)
      self.window_in_fullscreen = False #The window isn't in full screen mode initially.

      menu_bar = self.create_menu()
      vbox = gtk.VBox(False, 0)
      hbox = gtk.HBox(False, 0)
      self.message = gtk.Entry()
      check = gtk.Button("Check")
      clear = gtk.Button("Clear")
      self.buffer = gtk.TextBuffer()
      self.label = gtk.TextView(self.buffer)
      self.dictlabel = gtk.Button("Dictionary: ")
      self.dictlabel.set_alignment(0,0.5)
      scroll = gtk.ScrolledWindow()
      scroll.add(self.label)
      scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
      self.label.set_editable(False)
      self.label.set_wrap_mode(gtk.WRAP_WORD)
      check.connect("clicked",self.check)
      clear.connect("clicked",self.clear)
      self.dictlabel.connect("clicked",self.opendict)
      hbox.pack_start(self.message, True, True, 5)
      hbox.pack_start(check, False, True, 5)
      hbox.pack_start(clear, False, True, 5)
      vbox.pack_start(self.dictlabel, False, True, 5)
      vbox.pack_start(hbox, False, True, 5)
      vbox.pack_start(scroll, True, True, 5)

      fontName = "Sans Bold 30"
      pangoFont = pango.FontDescription(fontName)
      self.message.modify_font(pangoFont)
      self.message.connect("activate",self.check)

      fontName = "Sans Bold 15"
      pangoFont = pango.FontDescription(fontName)
      self.label.modify_font(pangoFont)
   
      self.window.set_menu(menu_bar)
      self.window.add(vbox)
      self.window.connect("destroy", self.close_window)
      self.message.grab_focus()

      self.buffer.set_text("ScrabbleDict.py 0.1 Scrabble dictionary")

  def on_window_state_change(self, widget, event, *args):
        if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
            self.window_in_fullscreen = True
        else:
            self.window_in_fullscreen = False

  def on_key_press(self, widget, event, *args):
        if event.keyval == gtk.keysyms.F6:
            # The "Full screen" hardware key has been pressed
            if self.window_in_fullscreen:
                self.window.unfullscreen ()
            else:
                self.window.fullscreen ()

  def clear(self,button):
      self.message.set_text("")
      self.message.grab_focus()

  def check(self,button):
      self.message.grab_focus()
      self.invalid = False
      word = self.message.get_text()
      if word.strip() != "":
#          thread.start_new_thread(lookup, (word, self.displayresult))
          res = lookup(word, self.displayresult)
          self.displayresult(word, res)
          if res:
              thread.start_new_thread(lookupUrl, (word, self.displayresulturl))

  def displayresulturl(self, word, result):
      if self.invalid == False:
          gtk.gdk.threads_enter()
          self.buffer.set_text("%s - %s" % (word,result))
          gtk.gdk.threads_leave()
      
  def displayresult(self, word, result):
 #     gtk.gdk.threads_enter()
      if result == True:
          self.buffer.set_text("%s - looking up definition..." % (word.lower()))
      else:
          self.invalid = True
          self.buffer.set_text("%s is not a valid word" % (word.lower()))
#      gtk.gdk.threads_leave()

  def quit(self, *args): 
      gtk.main_quit()

  def create_menu(self):
      menu = gtk.Menu()
   
      menuItemOpen = gtk.MenuItem("Select dictionary")
      menuItemSeparator = gtk.SeparatorMenuItem()
      menuItemExit = gtk.MenuItem("Exit")

      menuItemOpen.connect("activate", self.opendict)
      menuItemExit.connect("activate", self.close_window)
   
      menu.append(menuItemOpen)
      menu.append(menuItemSeparator)
      menu.append(menuItemExit)
          
      return menu

  def opendict(self, caller_widget):
      dlg = gtk.FileChooserDialog("Select dictionary", self.window, gtk.FILE_CHOOSER_ACTION_OPEN)
      dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
      dlg.add_button( gtk.STOCK_OPEN, gtk.RESPONSE_OK)

      res = dlg.run()
      if res == gtk.RESPONSE_OK:
          filename = dlg.get_filename()
          thread.start_new_thread(self.loaddict, (filename,))
      dlg.destroy()

  def run(self):     
    self.window.show_all()
    gtk.gdk.threads_init()
    gtk.gdk.threads_enter()
    gtk.main()
    gtk.gdk.threads_leave()

  def close_window(self, caller_widget):
      gtk.main_quit()

  def loaddict(self, filename):
    gtk.gdk.threads_enter()
    self.dictlabel.set_label("Loading %s, please wait..." % filename)
    gtk.gdk.threads_leave()
    global index
    index = {}
    print "Indexing..."
    f = open(filename)
    lastletter = ''
    for l in f:
        here = l.lower().strip()
        index[here] = 1

        if lastletter != l.lower().strip()[0:2]:
            lastletter = l.lower().strip()[0:2]
            gtk.gdk.threads_enter()
            self.dictlabel.set_label("Loading %s, please wait...%s" % (filename,lastletter.upper()))
            gtk.gdk.threads_leave()
    f.close()
    print "done."
    gtk.gdk.threads_enter()
    self.dictlabel.set_label("Loading %s, please wait...done." % (filename))
    self.dictlabel.set_label("Dictionary: %s" % filename)
    gtk.gdk.threads_leave()

if __name__ == "__main__":
    app = ScrabbleDict()
    thread.start_new_thread(app.loaddict, ('/usr/share/dict/sowpods.txt',))
    app.run()

