<?php

/**
 * Horde Nag driver for the Kolab IMAP server.
 * Based on code by Adriaan Putter <kougom@yahoo.com>
 *
 * Copyright (C) 2003 Code Fusion, cc.
 * Written by Stuart Bingė <s.binge@codefusion.co.za>
 *
 * Created 2003-08-25
 * Last Modified 2003-08-29 by Stuart Bingė
 */

require_once(HORDE_BASE . '/lib/Kolab.php');
require_once(HORDE_BASE . '/lib/iCalendar.php');

class Nag_Driver_kolab extends Nag_Driver {

  var $_params = array();
  var $_folder;
  var $_server;

  function Nag_Driver_kolab($user, $params = array())
  {
    $this->type = 'kolab';
    $this->_user = $user;
    $this->_params = $params;
    $this->_folder = $params['folder'];
    $this->_server = $params['server'];
  }

  function retrieve()
  {
    $imap = Kolab::OpenImapConnection($this->_server, $this->_folder);
    if (!$imap) return PEAR::raiseError('Unable to open IMAP connection.');

    $this->_tasks = array();

    $mod = false;
    $cal = new Horde_iCalendar;
    $msgs = Kolab::GetMessageList($imap);
    for ($i = 0; $i < count($msgs); $i++)
    {
      $cal->parsevCalendar(imap_body($imap, $msgs[$i]));
      $todo =& $cal->findComponent('VTODO');
      if (is_null($todo)) continue;

      $headers = Kolab::GetMessageHeaders($imap, $msgs[$i]);
      $cat = Kolab::GetHeaderValue($headers, X_HEAD_CAT, 0);
      $uid = Kolab::GetHeaderValue($headers, X_HEAD_ID);
      $flags = 0;
      if (is_null($uid))
      {
        $uid = uniqid("0x");
        $flags = TASK_MODIFIED;
        $mod = true;
      }

      $due = $todo->getAttribute('DUE');
      if (is_a($due, 'PEAR_Error')) $due = 0;
      else if (is_array($due)) $due = Kolab::ArrayToTimestamp($due);

      $com = $todo->getAttribute('PERCENT-COMPLETE');
      if (is_a($com, 'PEAR_Error')) $com = 0; else if ($com == 100) $com = 1; else $com = 0;

      $task = array();
      $task['message_id'] = $msgs[$i];
      $task['task_id'] = $uid;
      $task['tasklist_id'] = $this->_user;
      $task['name'] = $todo->getAttribute('SUMMARY');
      $task['desc'] = $todo->getAttribute('DESCRIPTION');
      $task['category'] = $cat;
      $task['due'] = $due;
      $task['priority'] = $todo->getAttribute('PRIORITY');
      $task['completed'] = $com;
      $task['alarm'] = 0;
      $task['flags'] = $flags;

      $this->_tasks[$uid] = $task;
    }

    Kolab::CloseIMAPConnection($imap);

    if ($mod)
      $this->store(); // Re-save the non-Nag tasks to ensure they have their Message IDs set corerctly

    return true;
  }

  function store()
  {
    $added_tasks = $this->listTasks(TASK_ADDED);
    $modified_tasks = $this->listTasks(TASK_MODIFIED);
    $deleted_tasks = $this->listTasks(TASK_DELETED);

    if ((count($added_tasks) == 0) && (count($modified_tasks) == 0) && (count($deleted_tasks) == 0))
      return true;  // No-op

    $imap = Kolab::OpenImapConnection($this->_server, $this->_folder);
    if (!$imap) return PEAR::raiseError('Unable to open IMAP connection.');

    list($user, $pass) = Kolab::GetAuthentication();
    $cal = new Horde_iCalendar;
    $mailbox = Kolab::MailboxURI($this->_server, $this->_folder);

    foreach ($added_tasks as $task_id => $task)
    {
      $cal->clear();
      $todo =& $cal->addNewComponent('VTODO');
      if (!$todo)
      {
        Kolab::CloseIMAPConnection($imap);
        return PEAR::raiseError('Unable to add task.');
      }

      if ($task['completed']) $com = 100; else $com = 0;
      $uid = $cal->generateUID();

      $todo->setAttribute('UID', $uid);
      $todo->setAttribute('SUMMARY', $task['name']);
      $todo->setAttribute('DESCRIPTION', $task['desc']);
      $todo->setAttribute('PRIORITY', $task['priority']);
      $todo->setAttribute('PERCENT-COMPLETE', $com);
      $todo->setAttribute('ORGANIZER', 'MAILTO:' . $user);
      $todo->setAttribute('CREATED', time());
      $todo->setAttribute('LAST-MODIFIED', time());

      if ($task['due'] != 0) $todo->setAttribute('DUE', $task['due']);

      $body = str_replace("\n", MIME_NL, $cal->exportvCalendar());
      if (!Kolab::AddMessage($imap, $mailbox, $user, 'text/calendar', $body, 'Nag', array(
        'Subject' => $uid,
        X_HEAD_ID => strval($task_id),
        X_HEAD_CAT => $task['category']
      )))
      {
        Kolab::CloseIMAPConnection($imap);
        return PEAR::raiseError('Unable to add task.');
      }

      $this->setFlag($task_id, TASK_ADDED, false);
    }

    foreach ($modified_tasks as $task_id => $task)
    {
      $mid = $task['message_id'];
      if (is_null($mid)) continue;
      $cal->parsevCalendar(imap_body($imap, $mid));
      @imap_delete($imap, $mid);

      $todo =& $cal->findComponent('VTODO');
      if (!$todo)
      {
        Kolab::CloseIMAPConnection($imap);
        return PEAR::raiseError('Unable to modify task.');
      }

      if ($task['completed']) $com = 100; else $com = 0;

      $todo->setAttribute('SUMMARY', $task['name']);
      $todo->setAttribute('DESCRIPTION', $task['desc']);
      $todo->setAttribute('PRIORITY', $task['priority']);
      $todo->setAttribute('PERCENT-COMPLETE', $com);
      $todo->setAttribute('ORGANIZER', 'MAILTO:' . $user);
      $todo->setAttribute('LAST-MODIFIED', time());

      if ($task['due'] != 0)
        $todo->setAttribute('DUE', $task['due']);
      else
        $todo->clearAttribute('DUE');

      $body = str_replace("\n", MIME_NL, $cal->exportvCalendar());
      if (!Kolab::AddMessage($imap, $mailbox, $user, 'text/calendar', $body, 'Nag', array(
        'Subject' => $todo->getAttribute('UID'),
        X_HEAD_ID => strval($task_id),
        X_HEAD_CAT => $task['category']
      )))
      {
        Kolab::CloseIMAPConnection($imap);
        return PEAR::raiseError('Unable to modify task.');
      }

      $this->setFlag($task_id, TASK_MODIFIED, false);
    }

    foreach ($deleted_tasks as $task_id => $task)
    {
      $mid = $task['message_id'];
      if (is_null($mid)) continue;
      @imap_delete($imap, $mid);

        $this->setFlag($meeting_id, TASK_DELETED, false);
    }

    $this->purgeDeleted();

    Kolab::CloseIMAPConnection($imap);

    return true;
  }

    function listAlarms($date)
    {
        return true;
    }

}
?>
