<?php
/**
 * Mnemo external API interface.
 *
 * $Horde: mnemo/lib/api.php,v 1.53.2.1 2005/01/24 10:31:58 jan Exp $
 *
 * This file defines Mnemo's external API interface. Other
 * applications can interact with Mnemo through this API.
 *
 * @package Mnemo
 */

$_services['list'] = array(
    'args' => array(),
    'type' => '{urn:horde}stringArray'
);

$_services['listBy'] = array(
    'args' => array('action' => 'string', 'timestamp' => 'int'),
    'type' => '{urn:horde}stringArray'
);

$_services['import'] = array(
    'args' => array('content' => 'string', 'contentType' => 'string'),
    'type' => 'int'
);

$_services['export'] = array(
    'args' => array('uid' => 'string', 'contentType' => 'string'),
    'type' => 'string'
);

$_services['delete'] = array(
    'args' => array('uid' => 'string'),
    'type' => 'boolean'
);

$_services['replace'] = array(
    'args' => array('uid' => 'string', 'content' => 'string', 'contentType' => 'string'),
    'type' => 'boolean'
);


/**
 * Returns an array of UIDs for all notes that the current user is
 * authorized to see.
 *
 * @return array  An array of UIDs for all notes the user can access.
 */
function _mnemo_list()
{
    require_once dirname(__FILE__) . '/base.php';
    global $conf;

    if (!isset($conf['storage']['driver']) ||
        !isset($conf['storage']['params'])) {
        return PEAR::raiseError('Not configured');
    }

    $memos = Mnemo::listMemos();
    if (is_a($memos, 'PEAR_Error')) {
        return $memos;
    }

    $uids = array();
    foreach ($memos as $memo) {
        $uids[] = $memo['uid'];
    }

    return $uids;
}

/**
 * Returns an array of UIDs for notes that have had $action happen
 * since $timestamp.
 *
 * @param string  $action     The action to check for - add, modify, or delete.
 * @param integer $timestamp  The time to start the search.
 *
 * @return array  An array of UIDs matching the action and time criteria.
 */
function &_mnemo_listBy($action, $timestamp)
{
    require_once dirname(__FILE__) . '/base.php';
    require_once 'Horde/History.php';

    $history = &Horde_History::singleton();
    $histories = $history->getByTimestamp('>', $timestamp, array(array('op' => '=', 'field' => 'action', 'value' => $action)), 'mnemo');
    if (is_a($histories, 'PEAR_Error')) {
        return $histories;
    }

    return array_keys($histories);
}

/**
 * Import a memo represented in the specified contentType.
 *
 * @param string $content      The content of the memo.
 * @param string $contentType  What format is the data in? Currently supports:
 *                             text/plain
 *                             text/x-vnote
 * @param string $notepad      (optional) The notepad to save the memo on.
 *
 * @return string  The new UID, or false on failure.
 */
function _mnemo_import($content, $contentType, $notepad = null)
{
    global $prefs;
    require_once dirname(__FILE__) . '/base.php';

    /* Make sure we have a valid notepad and permissions to edit
     * it. */
    if (empty($notepad)) {
        $notepad = Mnemo::getDefaultNotepad(PERMS_EDIT);
    }

    if (!array_key_exists($notepad, Mnemo::listNotepads(false, PERMS_EDIT))) {
        return PEAR::raiseError(_("Permission Denied"));
    }

    /* Create a Mnemo_Driver instance. */
    require_once MNEMO_BASE . '/lib/Driver.php';
    $storage = &Mnemo_Driver::singleton($notepad);

    switch ($contentType) {
    case 'text/plain':
        $noteId = $storage->add($storage->getMemoDescription($content), $content);
        break;

    case 'text/x-vnote':
        require_once 'Horde/iCalendar.php';

        // Create the new iCalendar.
        $vCal = &new Horde_iCalendar();
        $vCal->setAttribute('PRODID', '-//The Horde Project//Mnemo //EN');
        $vCal->setAttribute('METHOD', 'PUBLISH');

        // Create new note.
        $vNote = &Horde_iCalendar::newComponent('vnote', $vCal);

        if (!$vNote->parsevCalendar($content)) {
            return PEAR::raiseError(_("There was an error importing the vNote data."));
        }

        $note = $storage->fromiCalendar($vNote);
        $noteId = $storage->add($note['desc'],
                                $note['body'], !empty($note['category']) ? $note['category'] : '');
        break;

    default:
        return PEAR::raiseError(_("Unsupported Content-Type."));
    }

    if (is_a($noteId, 'PEAR_Error')) {
        return $noteId;
    }

    $note = $storage->get($noteId);
    return $note['uid'];
}

/**
 * Export a memo, identified by UID, in the requested contentType.
 *
 * @param string $uid          Identify the memo to export.
 * @param mixed  $contentType  What format should the data be in?
 *                             Either a string with one of:
 *                              'text/plain'
 *                              'text/x-vnote'
 *                             or an array with options:
 *                             'ContentType':  as above
 *                             'ENCODING': (optional) character encoding
 *                                         for strings fields
 *                             'CHARSET':  (optional) charset. Like UTF-8
 *
 * @return string  The requested data.
 */
function _mnemo_export($uid, $contentType)
{
    require_once dirname(__FILE__) . '/base.php';

    $storage = &Mnemo_Driver::singleton();
    $memo = $storage->getByUID($uid);
    if (is_a($memo, 'PEAR_Error')) {
        return $memo;
    }

    if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, PERMS_EDIT))) {
        return PEAR::raiseError(_("Permission Denied"));
    }

    if (is_array($contentType)) {
        $options = $contentType;
        $contentType = $options['ContentType'];
        unset($options['ContentType']);
    } else {
        $options = array();
    }

    switch ($contentType) {
    case 'text/plain':
        return $memo['body'];

    case 'text/x-vnote':
        require_once 'Horde/iCalendar.php';

        // Create the new iCalendar container.
        $iCal = &new Horde_iCalendar();
        $iCal->setAttribute('VERSION', '1.1');
        $iCal->setAttribute('PRODID', '-//The Horde Project//Mnemo //EN');
        $iCal->setAttribute('METHOD', 'PUBLISH');

        // Create a new vNote.
        $vNote = $storage->toiCalendar($memo, $iCal);

        // Set encoding options for all string values. For vNotes,
        // just BODY.
        $vNote->setParameter('BODY', $options);

        return $vNote->exportvCalendar();

    default:
        return PEAR::raiseError(_("Unsupported Content-Type."));
    }
}

/**
 * Delete a memo identified by UID.
 *
 * @param string | array $uid  Identify the note to delete, either a
 *                             single UID or an array.
 *
 * @return boolean  Success or failure.
 */
function _mnemo_delete($uid)
{
    // Handle an arrray of UIDs for convenience of deleting multiple
    // notes at once.
    if (is_array($uid)) {
        foreach ($uid as $u) {
            $result = _mnemo_delete($u);
            if (is_a($result, 'PEAR_Error')) {
                return $result;
            }
        }

        return true;
    }

    require_once dirname(__FILE__) . '/base.php';

    $storage = &Mnemo_Driver::singleton();
    $memo = $storage->getByUID($uid);
    if (is_a($memo, 'PEAR_Error')) {
        return $memo;
    }

    if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, PERMS_DELETE))) {
        return PEAR::raiseError(_("Permission Denied"));
    }

    return $storage->delete($memo['memo_id']);
}

/**
 * Replace the memo identified by UID with the content represented in
 * the specified contentType.
 *
 * @param string $uid         Idenfity the memo to replace.
 * @param string $content      The content of the memo.
 * @param string $contentType  What format is the data in? Currently supports:
 *                             text/plain
 *                             text/x-vnote
 *
 * @return boolean  Success or failure.
 */
function _mnemo_replace($uid, $content, $contentType)
{
    require_once dirname(__FILE__) . '/base.php';

    $storage = &Mnemo_Driver::singleton();
    $memo = $storage->getByUID($uid);
    if (is_a($memo, 'PEAR_Error')) {
        return $memo;
    }

    if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, PERMS_EDIT))) {
        return PEAR::raiseError(_("Permission Denied"));
    }

    switch ($contentType) {
    case 'text/plain':
        return $storage->modify($memo['memo_id'], $storage->getMemoDescription($content), $content, null);

    case 'text/x-vnote':
        require_once 'Horde/iCalendar.php';

        // Create the new iCalendar container.
        $iCal = &new Horde_iCalendar();
        $iCal->setAttribute('PRODID', '-//The Horde Project//Mnemo //EN');
        $iCal->setAttribute('METHOD', 'PUBLISH');

        // Create a new vNote.
        $vNote = &Horde_iCalendar::newComponent('vnote', $iCal);

        if (!$vNote->parsevCalendar($content)) {
            return PEAR::raiseError(_("There was an error importing the vNote data."));
        }
        $note = $storage->fromiCalendar($vNote);

        return $storage->modify($memo['memo_id'], $note['desc'],
                                $note['body'],!empty($note['category']) ? $note['category'] : '');

    default:
        return PEAR::raiseError(_("Unsupported Content-Type."));
    }
}
