#  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.  

try:
  from gnome.ui import *
  import _gnomeui
except:
  pass

from gtk import *
import string

import gutil
import config
import mail
import Base
import GladeWindow
import MozillaMsgWindow

import mail.Source
import mail.IMAP
import mail.POP
import mail.MH
import mail.SpoolFile

dialog = None

def show(parent):
  global dialog
  if not dialog:
    dialog = Preferences()
  dialog._parentW = parent
  if parent:
    dialog.set_parent(parent._window)
  dialog.show()

class Preferences(GladeWindow.Window):
  def __init__(self):
    GladeWindow.Window.__init__(self)


    sigs = { 'snew_clicked': self.snew_clicked,
             'sedit_clicked': self.sedit_clicked,
             'sdelete_clicked': self.sdelete_clicked,
             'ok_clicked': self.ok_clicked,
             'cancel_clicked': self.cancel_clicked,
             'apply_clicked': self.apply_clicked,
             'wrap_toggled': self.wrap_toggled,
             }
    self._glade.signal_autoconnect(sigs)

  def update_display(self):
    self.update_sending_page()
    self.update_mail_page()
    self.update_display_page()
    self.update_others_page()

  def update_server_list(self):
    self._server_list.clear_items(0, len(self._server_list.children()))

    items = []
    for source in mail.get_sources():
      item = GtkListItem(label=source.name())
      item.show()
      items.append(item)
      
    if len(items):
      self._server_list.append_items(items)
      self._server_list.select_item(0)

  def update_mail_page(self):
    self.update_server_list()
    self._smtpServer.set_text(mail.get_config('smtp_server'))
    self._smtpUserName.set_text(mail.get_config('smtp_user'))

  def update_display_page(self):
    wm = config.getParam(None, 'Display', 'messageDisplayClass',
                         'TextMsgWindow')

    if wm == 'XmHTMLMsgWindow':
      self._XmHTML.set_active(1)
    elif wm == 'MozillaMsgWindow':
      self._Mozilla.set_active(1)
    elif wm == 'TextMsgWindow':
      self._PlainText.set_active(1)

    if not MozillaMsgWindow.have_mozilla:
      self._Mozilla.set_sensitive(0)

    txt = ''
    self._list_headers.delete_text(0, -1)

    if self._parentW:
      for header in self._parentW._messageList._columnHeaders:
        self._list_headers.insert_text(header + '\n')

    self.update_color('unread')
    self.update_color('deleted')
    self.update_color('flagged')
    self.update_color('normalfor', 0)
    self.update_color('normalback', 0)

    self._quote_with.set_text(mail.get_config('quote_string'))

    gutil.set_radio(self, 'fwd', mail.get_config('forward_type'))
    gutil.set_radio(self, 'reply', mail.get_config('reply_type'))

    font = config.getParam(None, 'Display', 'messageFont')
    if font:
      self._fontpicker.set_font_name(font)
      
  def update_sending_page(self):
    self._users_name.set_text(mail.get_config('users_name'))
    self._email_address.set_text(mail.get_config('email_address'))
    self._default_domain.set_text(mail.get_config('default_domain'))
    self._reply_to.set_text(mail.get_config('reply_to'))
    self._sig.set_text(mail.get_config('sig'))
    self._bcc.set_text(mail.get_config('bcc'))
    v = mail.get_config('empty_trash')
    self._empty_trash.set_active(v)
    if mail.get_config('wrap_column'):
      self._wrap_column.set_sensitive(1)
      self._wrap_column.set_text('%d' % mail.get_config('wrap_column'))
      self._wrap_text.set_active(1)
    else:
      self._wrap_column.set_sensitive(0)
      self._wrap_column.set_text('')
      self._wrap_text.set_active(0)
    self.update_folder_popups()

  def update_folder_popups(self):
    self._folder_configs = [
      [self._sent_folder, 'sent_box', None],
      [self._drafts_folder, 'drafts_box', None],
      [self._trash_folder, 'trash_box', None]
      ]

    for f in self._folder_configs:
      g = f[0]
      gutil.folder_option_menu(g)
      g.get_menu().connect('selection_done', self.folder_selected, f)
      gutil.select_folder_option(g, mail.get_mailbox_config_value(f[1]))

    
  def update_others_page(self):
    self._attachment_dir.set_text(config.getParam(None, 'Other',
                                                  'attachment_dir', '/tmp'))

  def update_color(self, name, do_radio=1):
    if not self._parentW:
      return
    
    exec 'c = self._parentW._messageList._%s_colort' % name

    nc = [c[0], c[1], c[2]]
    for idx in range(len(nc)):
      if nc[idx] != 0:
        p = nc[idx]
        nc[idx] = float(p)/float(65535.0)
    
    exec 'self._%s_picker.set_d(nc[0], nc[1], nc[2], 0)' % name
    if do_radio:
      exec 'forb = self._parentW._messageList._%s_forb' % name
      if forb:
        exec 'self._%s_forground.set_active(1)' % name
      else:
        exec 'self._%s_background.set_active(1)' % name

  def get_color(self, name, do_radio=1):
    if not self._parentW:
      return
    
    exec 'c = self._%s_picker.get_d()' % name
    nc = [c[0], c[1], c[2]]
    for i in range(len(nc)):
      p = nc[i]
      nc[i] = float(p) * float(65535.0)
      
    exec 'self._parentW._messageList._%s_colort = tuple(nc)' % name
    exec 'self._parentW._messageList._%s_color = self._parentW._messageList.get_colormap().alloc(nc[0], nc[1], nc[2])' % name
    if do_radio:
      exec 'self._parentW._messageList._%s_forb = self._%s_forground.get_active()' % (name, name)

  def snew_clicked(self, data):
    showSource(None, self)

  def sedit_clicked(self, d):
    sel =  self._server_list.get_selection()

    if len(sel):
      idx = self._server_list.child_position(sel[0])
      source = mail.get_sources()[idx]
      showSource(source, self)

  def sdelete_clicked(self, d):
    sel =  self._server_list.get_selection()

    if len(sel):
      idx = self._server_list.child_position(sel[0])
      source = mail.get_sources()[idx]
      mail.remove_source(source)
      self.update_display()

  def ok_clicked(self, d):
    if self.update_config():
      self._window.hide()
      if self._parentW:
        self._parentW.preferences_changed()

  def cancel_clicked(self, d):
    self._window.hide()

  def apply_clicked(self, d):
    self.update_config()

  def folder_selected(self, d, f):
    idx, item = gutil.selected_menu_item(d)
    folder = item.get_data('folder')
    f[2] = folder

  def wrap_toggled(self, d):
    #print 'wrap_toggled'
    if self._wrap_text.get_active():
      self._wrap_column.set_sensitive(1)
      txt = self._wrap_column.get_text()
      if not txt or len(txt) == 0:
        self._wrap_column.set_text('72')
    else:
      self._wrap_column.set_sensitive(0)

  def update_config(self):
    mw = ''
    if self._XmHTML.get_active():
      mw = 'XmHTMLMsgWindow'
    elif self._Mozilla.get_active():
      mw = 'MozillaMsgWindow'
    elif self._PlainText.get_active():
      mw = 'TextMsgWindow'
    config.setParam(None, 'Display', 'messageDisplayClass', mw)

    mail.set_config('smtp_user', self._smtpUserName.get_text())
    mail.set_config('smtp_server', self._smtpServer.get_text())

    self.get_color('unread')
    self.get_color('deleted')
    self.get_color('flagged')
    self.get_color('normalfor', 0)
    self.get_color('normalback', 0)
    #font = self._fontpicker.get_font_name()
    #FIXME: when they fix spelling error in gnome/ui.py
    font = _gnomeui.gnome_font_picker_get_font_name(self._fontpicker._o)
    config.setParam(None, 'Display', 'messageFont', font)

    mail.set_config('quote_string', self._quote_with.get_text())
    mail.set_config('users_name', self._users_name.get_text())
    mail.set_config('email_address', self._email_address.get_text())
    mail.set_config('default_domain', self._default_domain.get_text())
    mail.set_config('reply_to', self._reply_to.get_text())
    mail.set_config('sig', self._sig.get_text())
    mail.set_config('bcc', self._bcc.get_text())
    mail.set_config('empty_trash', self._empty_trash.get_active())

    if self._wrap_text.get_active():
      v = gutil.get_int_from_text('Wrap Column', self._wrap_column)
      if v != None:
        mail.set_config('wrap_column', v)
      else:
        return 0
    else:
      mail.set_config('wrap_column', None)

    for f in self._folder_configs:
      if f[2]:
        mail.set_mailbox_config_value(f[1], f[2])

    mail.set_config('forward_type',  gutil.get_radio(self, 'fwd'))
    mail.set_config('reply_type', gutil.get_radio(self, 'reply'))

    #FIXME: get the headers

    config.setParam(None, 'Other', 'attachment_dir',
                    self._attachment_dir.get_text())

    return 1
    
sourceDialog = None

def showSource(source, parent):
  global sourceDialog
  if not sourceDialog:
    sourceDialog = SourceDialog()
  sourceDialog.show(source, parent)


class SourceDialog(GladeWindow.Window):
  def __init__(self):
    GladeWindow.Window.__init__(self)
    self._remove_orig = 0
    #self._window.set_modal(1)
    
    sigs = { 'source_ok_clicked': self.ok_clicked,
             'source_cancel_clicked': self.cancel_clicked,
             'check_toggled': self.check_toggled,
             }
    self._glade.signal_autoconnect(sigs)

    self._type.get_menu().connect('selection_done', self.type_selected)
    
    
    self._imap_page = self._notebook.get_nth_page(1)
    self._pop_page = self._notebook.get_nth_page(2)
    self._spool_page = self._notebook.get_nth_page(3)
    self._mh_page = self._notebook.get_nth_page(4)
    self._notebook.remove_page(1)
    self._notebook.remove_page(1)
    self._notebook.remove_page(1)
    self._notebook.remove_page(1)

  def show(self, source, parent):
    self._parent = parent
    self._source = source
    self._orig_source = source
    self.update_display()
    if parent:
      self.set_parent(parent._window)
    self._window.show()


  def update_display(self):
    if not self._source:
      self._source = mail.IMAP.IMAPSource()
      self._source['ui'] = self._parent._parentW
    
    if isinstance(self._source, mail.Source.RemoteSource):
      self._serverName.set_sensitive(1)      
      self._serverName.set_text(self._source['serverName'])

    if self._source['checkFrequency'] == None:
      self._check.set_active(0)
      self._minutes.set_text('')
      #self._minutes.set_sensitive(0)
    else:
      self._check.set_active(1)
      #self._minutes.set_sensitive(1)      
      self._minutes.set_text('%d' % self._source['checkFrequency'])

    self._autodownload.set_active(self._source['autoDownload'])
    self._check_at_startup.set_active(self._source['check_at_startup'])
    self._check_when_selected.set_active(self._source['check_when_selected'])
    self._display_name.set_text(self._source.name())
    self._new_mail_command.set_text(self._source['new_mail_command'])

    if isinstance(self._source, mail.IMAP.IMAPSource):
      self._notebook.append_page(self._imap_page, GtkLabel('IMAP'))
      self._imapPort.set_text("%d" % self._source['port'])
      self._imapRemember.set_active(self._source['rememberPassword'])
      self._showSubscribed.set_active(self._source['showOnlySubscribed'])
      self._imapUserName.set_text(self._source['userName'])
      self._onDelete.set_history(self._source['deleteOption'])
      self._type.set_history(0)
      self._personalNS.set_text(
        string.join(self._source['personalNameSpace'], ','))
      self._othersNS.set_text(
        string.join(self._source['othersNameSpace'], ','))
      self._publicNS.set_text(
        string.join(self._source['publicNameSpace'], ','))
      self._serverOverride.set_active(self._source['serverOverrideNameSpace'])
    elif isinstance(self._source, mail.POP.POPSource):
      self._notebook.append_page(self._pop_page, GtkLabel('POP'))
      self._popUserName.set_text(self._source['userName'])
      self._popRemember.set_active(self._source['rememberPassword'])
      self._popPort.set_text('%d' % self._source['port'])
      self._pop_delete.set_active(self._source['delete_from_server'])
      self._pop_delete_on_delete.set_active(self._source['delete_on_delete'])
      self._use_apop.set_active(self._source['use_apop'])
      box = mail.mailbox_from_config(self._source['storage_config'])
      self._selected_storage_folder = None
      gutil.folder_option_menu(self._storage_folder, 0)
      gutil.select_folder_option(self._storage_folder, box)
      self._storage_folder.get_menu().connect('selection_done',
                                              self.storage_folder_selected)
      self._type.set_history(1)
      self._pop_check_with_storage.set_active(
        self._source['check_with_storage'])
      self._pop_show.set_active(self._source['show'])
    elif isinstance(self._source, mail.SpoolFile.SpoolFileSource):
      self._notebook.append_page(self._spool_page, GtkLabel('Spool'))        
      self._type.set_history(3)
      self._serverName.set_text('')
      self._serverName.set_sensitive(0)
      self._spool_path.set_text(self._source['path'])
      self._spool_on_delete.set_history(self._source['deleteOption'])      
    elif isinstance(self._source, mail.MH.MHSource):
      self._notebook.append_page(self._mh_page, GtkLabel('MH'))
      self._type.set_history(2)
      self._serverName.set_text('')
      self._serverName.set_sensitive(0)
      dir = self._source['directory'] or ''
      self._mh_directory.set_text(dir)
      self._mh_on_delete.set_history(self._source['deleteOption'])      

  def ok_clicked(self, d):
    if self.update_config():
      self._notebook.remove_page(1)
      self._window.hide()
      self._parent.update_server_list()
      self._parent.update_folder_popups()
    
  def cancel_clicked(self, d):
    self._notebook.remove_page(1)    
    self._window.hide()

  def type_selected(self, d):
    idx = gutil.selected_option(self._type)
      
    if idx == 0:
      new = mail.IMAP.IMAPSource()
    elif idx == 1:
      new = mail.POP.POPSource()
    elif idx == 2:
      new = mail.MH.MHSource('~/Mail')
    else:
      new = mail.SpoolFile.SpoolFileSource()

    if new.__class__ == self._source.__class__:
      return
    elif self._orig_source:
      self._remove_orig = 1

    new['ui'] = self._parent._parentW
    self._source = new
    self._notebook.remove_page(1)
    self.update_display()
    self._display_name.set_text('')
    

  def check_toggled(self, d):
    if self._check.get_active():
      self._minutes.set_sensitive(1)
      txt = self._minutes.get_text()
      if not txt or len(txt) == 0:
        self._minutes.set_text('10')
    else:
      self._minutes.set_sensitive(0)

  def storage_folder_selected(self,d):
    #print 'storage_folder_selected'
    idx, item = gutil.selected_menu_item(d)
    folder = item.get_data('folder')
    self._selected_storage_folder = folder

  def update_config(self):
    if self._remove_orig:
      mail.remove_source(self._remove_orig)

    if isinstance(self._source, mail.Source.RemoteSource):
      self._source['serverName'] = self._serverName.get_text()

    if not self._check.get_active():
      val = None
    else:
      val = gutil.get_int_from_text('Minutes', self._minutes)
      if val is None:
        return 0
      
    self._source['checkFrequency'] = val

    self._source['autoDownload'] = self._autodownload.get_active()
    self._source['check_at_startup'] = self._check_at_startup.get_active()
    self._source['check_when_selected'] = self._check_when_selected.get_active()
    self._source['new_mail_command'] = self._new_mail_command.get_text()
    n = self._display_name.get_text()
    if n != self._source._display_name:
      self._source['display_name'] = len(n) and n or None

    if isinstance(self._source, mail.IMAP.IMAPSource):
      self._source['port'] = string.atoi(self._imapPort.get_text())
      self._source['rememberPassword'] = self._imapRemember.get_active()
      self._source['showOnlySubscribed'] = self._showSubscribed.get_active()
      self._source['userName'] = self._imapUserName.get_text()
      self._source['deleteOption'] = gutil.selected_option(self._onDelete)
      
      self._source['personalNameSpace'] = string.split(
        self._personalNS.get_text(), ',')
      self._source['othersNameSpace'] = string.split(
        self._othersNS.get_text(), ',')
      self._source['publicNameSpace'] = string.split(
        self._publicNS.get_text(), ',')
      self._source['serverOverrideNameSpace'] = \
                                              self._serverOverride.get_active()
    elif isinstance(self._source, mail.POP.POPSource):
      self._source['userName'] = self._popUserName.get_text()
      self._source['rememberPassword'] = self._popRemember.get_active()
      self._source['port'] = string.atoi(self._popPort.get_text())
      self._source['delete_from_server'] = self._pop_delete.get_active()
      self._source['delete_on_delete'] = self._pop_delete_on_delete.get_active()
      self._source['use_apop'] = self._use_apop.get_active()
      self._source['check_with_storage'] = self._pop_check_with_storage.get_active()
      self._source['show'] = self._pop_show.get_active()
      
      if self._selected_storage_folder:
        self._source['storage_config'] =\
          mail.mailbox_config_value(self._selected_storage_folder)
    elif isinstance(self._source, mail.SpoolFile.SpoolFileSource):
      self._source['path'] = self._spool_path.get_text()
      self._source['deleteOption'] = gutil.selected_option(self._spool_on_delete)
    elif isinstance(self._source, mail.MH.MHSource):
      self._source['directory'] = self._mh_directory.get_text()
      self._source['deleteOption'] = gutil.selected_option(self._mh_on_delete)
      

    if self._source not in mail.get_sources():
      mail.add_source(self._source)

    return 1
      
    
