#  PMail - GNOME/GTK/Python email client
#  Copyright (C) 2000 Scott Bender <sbender@harmony-ds.com>

#  This file is part of PMail.

#  PMail 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, or (at your option)
#  any later version.

#  PMail is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with GNU Emacs; see the file COPYING.  If not, write to
#  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
#  Boston, MA 02111-1307, USA.  

from gtk import *
import string
import time

import gutil
import mail

import GladeWindow
import MessageList
import SMessageWindow
from mail.SearchCriteria import SearchCriteria

def show(parent, mailbox):
  w = SearchMessages(parent, mailbox)
  w.show()

class SearchMessages(GladeWindow.Window):
  def __init__(self, mainWindow, mailbox):
    GladeWindow.Window.__init__(self)
    
    self._mainWindow = mainWindow
    self.set_parent(mainWindow._window)

    sigs = { 'search': self.search,
             'more': self.more,
             'less': self.less,
             'open': self.open,
             'open_main': self.open_in_main,
             'close': self.destroy
             }
    self._glade.signal_autoconnect(sigs)

    self._list = MessageList.Window(mainWindow, None, 'GtkSearchMessageList')
    self._table.attach(self._list, 0, 2, 3, 4)
    self._list.show()

    self._bools = []
    self._fields = []
    self._operators = []
    self._values = []
    self._ops_hboxes = []

    gutil.folder_option_menu(self._folder, do_none=0)
    self._folder.get_menu().connect('selection_done', self.folder_selected)

    self._mailbox = mailbox
    self.add_operation_widgets()

  def update_for_mailbox(self, box):
    if not self._mailbox or box.source().__class__ != self._mailbox.__class__:
      fields = map(lambda x: x[:1] + string.lower(x[1:]),
                   box.source().get_search_posibilities().keys())
      idx = 0
      for menu in self._fields:
        gutil.fill_option_menu(menu, fields)
        menu.get_menu().connect('selection_done', self.field_selected)
        menu.set_history(0)
        menu.get_menu().set_data('row', idx)
        self.update_for_field(box, idx, 0)
        idx = idx + 1

    self._mailbox = box

  def update_for_field(self, box, op_idx, idx):
    pos = box.source().get_search_posibilities()
    field = pos.keys()[idx]
    info = pos.get(field)
    operators = map(lambda x: SearchCriteria.operator_strings[x], info[1])
    gutil.fill_option_menu(self._operators[op_idx], operators, info[1])
    self._operators[op_idx].set_history(0)
    self._values[op_idx].set_sensitive(info[2] != None)

  def folder_selected(self, menu):
    idx, item = gutil.selected_menu_item(menu)
    folder = item.get_data('folder')
    if folder.source().get_search_posibilities():
      self.update_for_mailbox(folder)

  def field_selected(self, menu):
    idx, item = gutil.selected_menu_item(menu)
    op_idx = menu.get_data('row')
    self.update_for_field(self._mailbox, op_idx, idx)

  def _try_date(self, s):
    try: res = time.strptime(s)
    except ValueError:
      try: res = time.strptime(s, '%m/%d/%Y')
      except ValueError:
        try: res = time.strptime(s, '%m/%d/%y')
        except ValueError:
          try: res = time.strptime(s, '%m/%d/%Y %H:%M')
          except ValueError:
            try: res = time.strptime(s, '%m/%d/%y %H:%M')
            except ValueError:
              res = s
    return res
  
  def search(self, d):
    idx, item = gutil.selected_menu_item(self._folder.get_menu())
    box = item.get_data('folder')

    if box \
       and isinstance(box, mail.Mailbox) \
       and box.source().get_search_posibilities():
      sc = SearchCriteria()

      for i in range(len(self._ops_hboxes)):
        fidx, b = gutil.selected_menu_item(self._fields[i].get_menu())
        idx, op = gutil.selected_menu_item(self._operators[i].get_menu())
        pos = self._mailbox.source().get_search_posibilities()    
        field = pos.keys()[fidx]
        val = self._values[i].get_text()
        if pos.get(field)[2] == 'date':
          val = self._try_date(val)
        boolo = None
        if i > 0:
          boolo, skip = gutil.selected_menu_item(self._bools[i].get_menu())
        sc.add_operation(field, op.get_data('data'), val, boolo)

      msgs = box.search(sc)
      self._list.list_messages(None, msgs)

  def more(self, d):
    self.add_operation_widgets()

  def less(self, d):
    row = len(self._bools)-1
    if row > 0:
      self._ops_box.remove(self._ops_hboxes[row])
      self._ops_hboxes.remove(self._ops_hboxes[row])
      self._bools.remove(self._bools[row])
      self._fields.remove(self._fields[row])
      self._operators.remove(self._operators[row])
      self._values.remove(self._values[row])

  def open(self, d):
    for msg in self._list.selected_messages():
      SMessageWindow.show(msg)

  def open_in_main(self, d):
    msgs = self._list.selected_messages()
    if len(msgs):
      self._mainWindow.display_message(msgs[0])

  def add_operation_widgets(self):
    row = len(self._bools)

    self._bools.append(GtkOptionMenu())
    self._fields.append(GtkOptionMenu())
    self._operators.append(GtkOptionMenu())
    self._values.append(GtkEntry())

    hbox = GtkHBox()
    self._ops_hboxes.append(hbox)
    self._ops_box.pack_start(hbox)

    gutil.fill_option_menu(self._bools[row], ['And', 'Or'])

    hbox.pack_start(self._bools[row])
    hbox.pack_start(self._fields[row])
    hbox.pack_start(self._operators[row])
    hbox.pack_start(self._values[row])
    hbox.show()

    self._values[row].connect('activate', self.search)

    self._bools[row].show()
    self._fields[row].show()
    self._operators[row].show()
    self._values[row].show()

    self._bools[row].set_history(0)
    if row == 0:
      self._bools[row].set_sensitive(0)

    if self._mailbox:
      gutil.select_folder_option(self._folder, self._mailbox)
      self.update_for_mailbox(self._mailbox)

    #self._bools[row].set_data('row', row)
    #self._fields[row].set_data('row', row)
    #self._operators[row].set_data('row', row)
    #self._values[row].set_data('row', row)
    
    

