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

import string
import rfc822
import mimetools
import time
import poplib
import os
import threading
from StringIO import StringIO

from Base import *
import Mailbox
import Message
import config

MARK = 0
TRASH = 1
REMOVE = 2

next_unique_id = 1
def update_next_unique_id(sources):
  global next_unique_id
  if len(sources):
    ids = map(lambda x: x['unique_id'], sources)
    next_unique_id = max(ids) + 1
  #print 'next_unique_id = %d' % next_unique_id

class Source(PMailObject):
  def __init__(self):
    PMailObject.__init__(self, 0)
    self._checkFrequency = None
    self._autoDownload = 0
    self._ui = None
    self._mailboxes = None
    self._inbatch = 0
    self._batch_mailbox = None
    self._check_at_startup = 0
    self._check_when_selected = 1
    self._expanded = 1
    self._mailbox_configs = {}
    self._display_name = None
    self._new_mail_command = ''
    self._show = 1
    
    self._working_lock = threading.RLock()
    self.add_config_params(['checkFrequency', 'autoDownload',
                            'unique_id', 'check_at_startup',
                            'check_when_selected',
                            'expanded',
                            'mailbox_configs',
                            'display_name',
                            'new_mail_command',
                            'show'])
    global next_unique_id
    self._unique_id = next_unique_id
    next_unique_id = next_unique_id + 1

    self._check_timer = None

  def lock(self):
    self._working_lock.acquire()

  def unlock(self):
    self._working_lock.release()

  def can_lock(self): # Note this takes a lock, you must call unlock when done
    return self._working_lock.acquire(0)

  def hook_setitem(self, key, val):
    if (key == 'checkFrequency' and self._ui) \
       or key == 'ui':
      if self._check_timer:
        self._ui.remove_check_timer(self._check_timer)
      if self._checkFrequency:
        self._check_timer = self._ui.add_check_timer(self,
                                                     self._checkFrequency*60)

  def __add_mailboxconfigs(self, boxes):
    if boxes:
      for path, box in boxes.items():
        conf = box.get_config()
        self._mailbox_configs[box.config_name()] = conf
        self.__add_mailboxconfigs(box._mailboxes)

  def get_config(self):
    if self._mailboxes:
      #print self.name(), self._mailboxes
      self._mailbox_configs = {}
      self.__add_mailboxconfigs(self._mailboxes)
    return PMailObject.get_config(self)

  def fixup(self):
    pass

  def mailbox_with_path(self, path):
    if self.mailboxes():
      for box in self.mailboxes():
        b = box.mailbox_with_path(path)
        if b:
          return b
    return None

  def cache_dir(self):
    return os.path.join(config.config_dir, 'msg.cache.%d' %
                        self._unique_id)
    
  def save_message_cache(self):
    self.lock()
    if self._mailboxes:
      source_dir = self.cache_dir()
      if not os.path.exists(source_dir):
        os.mkdir(source_dir)

      for box in self.mailboxes():
        box.save_message_cache(source_dir)
    self.unlock()

  def can_add_subfolder(self):
    return false

  def can_delete(self):
    return false

  def can_rename(self):
    return false

  def can_expunge(self):
    return false

  def name(self):
    return self._name

  def mailboxes(self):
    pass

  def _get_body(self, mailbox, uid, part_number=''):    
    pass

  def delete_message(self, message):
    pass

  def unseen_count(self, mailbox):
    pass

  def message_count(self, mailbox):
    pass

  def _get_messages(self, mailbox):
    pass

  def delete_subfolder(self, mailbox):
    pass
  
  def create_subfolder(self, name, mailbox=None):
    pass

  def rename(self, mailbox, newname):
    pass

  def message_creator(self, source, mailbox, id):
    pass

  def append_message(self, mailbox, message):
    mailbox._message_count = None
    mailbox._unseen_count = None
    return 1

  def search(self, mailbox, criteria):
    pass

  def get_search_posibilities(self):
    return None
  

  def start_batch(self, mailbox=None):
    # call before doing a bunch of changes
    self.lock()
    self._inbatch = 1
    self._batch_mailbox = mailbox
    self.unlock()

  def end_batch(self):
    self.lock()
    self._inbatch = 0
    self._batch_mailbox = None
    self.unlock()


  def _run_new_mail_command(self, command=None):
    if not command:
      command = self._new_mail_command

    #if os.name == 'posix':
    #  os.execl('/bin/sh', '-c', command)
    #else:
    os.system(command)

  def check_mail(self):
    self.lock()
    try:
      res = 0
      for box in self.mailboxes():
        bres = box.check_mail()
        res = bres or res

      if res and self._new_mail_command and len(self._new_mail_command):
        self._run_new_mail_command()
        
    finally:
      self.unlock()

    return res

class RemoteSource(Source):
  def __init__(self, serverName, userName, password, port):
    Source.__init__(self)
    self._serverName = serverName
    self._port = port
    self._userName = userName
    self._password = password
    self._rememberPassword = 1

    self.add_config_params(['serverName',
                            'port',
                            'userName',
                            'password',
                            'rememberPassword'])

  def name(self):
    if self._serverName:
      return not self._display_name and \
             '{%s}%s@%s' % (self.type_name(), self._userName, self._serverName) \
             or self._display_name
    else:
      return ''

class LocalStorageSource(Source):
  def __init__(self):
    Source.__init__(self)

