<?php
/**
 * Kronolith external API interface.
 *
 * This file defines Kronolith's external API interface. Other
 * applications can interact with Kronolith through this API.
 *
 * $Horde: kronolith/lib/api.php,v 1.74 2003/05/22 16:57:00 chuck Exp $
 */

$_services['list'] = array(
    'args' => array('startDate', 'endDate', 'calendars', 'showRecurrence'),
    'type' => 'array');

$_services['listCalendars'] = array(
    'args' => array('owneronly', 'permission'),
    'type' => 'array');

$_services['import_icalendar'] = array(
    'args' => array('icalendar_data', 'cal'),
    'type' => 'array');

$_services['import_vevent'] = array(
    'args' => array('vevent', 'cal'),
    'type' => 'array');

$_services['export_vfreebusy'] = array(
    'args' => array('startstamp', 'endstamp', 'calendar'),
    'type' => 'array');

$_services['show'] = array(
    'link' => '%application%/viewevent.php?calendar=|calendar|' . ini_get('arg_separator.output') . 'eventID=|event|');

$_services['block'] = array(
    'args' => array('type', 'params'),
    'type' => 'array');

$_services['blocks'] = array(
    'args' => array(),
    'type' => 'array');

$_services['listCategories'] = array(
    'args' => array('calendar'),
    'type' => 'array');

$_services['formatCategory'] = array(
    'args' => array('categoryID', 'calendar'),
    'type' => 'string');


function _kronolith_block($type, $params)
{
    @define('KRONOLITH_BASE', dirname(__FILE__) . '/..');
    require_once KRONOLITH_BASE . '/lib/base.php';

    $class = 'Kronolith_' . $type . '_Block';
    require_once KRONOLITH_BASE . '/lib/Block/' . $type . '.php';
    return new $class($params);
}

function _kronolith_blocks()
{
    @define('KRONOLITH_BASE', dirname(__FILE__) . '/..');
    require_once KRONOLITH_BASE . '/lib/base.php';

    $blocks = array('summary' => array('name' => _("Calendar Summary"),
                                       'type' => 'summary',
                                       'params' => array('calendar' => array('name' => _("Calendar"),
                                                                             'type' => 'enum',
                                                                             'default' => '__all',
                                                                             'values' => array()))));
    $blocks['summary']['params']['calendar']['values']['__all'] = _("All Visible");

    foreach (Kronolith::listCalendars() as $id => $cal) {
        $blocks['summary']['params']['calendar']['values'][$id] = $cal->getShareName();
    }

    return $blocks;
}

function _kronolith_list($startDate = null, $endDate = null, $calendars = null, $showRecurrence = true)
{
    require_once dirname(__FILE__) . '/base.php';

    // If this is from an external source, say XML-RPC, it translates
    // empty/null args into empty strings.
    if ($startDate === '') {
        $startDate = null;
    }
    if ($endDate === '') {
        $endDate = null;
    }
    if ($calendars === '') {
        $calendars = null;
    }
    if ($showRecurrence === '') {
        $showRecurrence = true;
    }

    // Make sure that we check permissions on the calendars to be
    // listed.
    if (is_array($calendars)) {
        $permittedcalendars = Kronolith::listCalendars(false, _PERMS_READ);
        foreach ($calendars as $cal) {
            if (!isset($permittedcalendars[$cal])) {
                unset($calendars[$cal]);
            }
        }
    } else {
        $calendars = null;
    }

    return Kronolith::listEvents($startDate, $endDate, $calendars, $showRecurrence);
}

function _kronolith_listCalendars($owneronly = false, $permission = null)
{
    require_once dirname(__FILE__) . '/base.php';
    if (!isset($permission)) {
        $permission = _PERMS_SHOW;
    }
    return array_keys(Kronolith::listCalendars($owneronly, $permission));
}

function _kronolith_formatCategory($categoryID = 0, $calendar = null)
{
    require_once dirname(__FILE__) . '/base.php';
    if (!array_key_exists($calendar, Kronolith::listCalendars(false, _PERMS_READ))) {
        return PEAR::raiseError(_("Permission Denied"));
    }
    return Kronolith::formatCategory($categoryID, $calendar);
}

function _kronolith_listCategories($calendar = null)
{
    require_once dirname(__FILE__) . '/base.php';
    if (!array_key_exists($calendar, Kronolith::listCalendars(false, _PERMS_READ))) {
        return PEAR::raiseError(_("Permission Denied"));
    }
    return Kronolith::listCategories($calendar);
}

function _kronolith_import_icalendar($icalendar_data, $cal = null)
{
    require_once dirname(__FILE__) . '/base.php';
    require_once HORDE_BASE . '/lib/Data.php';
    global $calendar, $prefs;

    // Set the calendar to the user's default calendar if none is
    // specified, and check for permissions to that calendar.
    if (is_null($cal)) {
        $cal = $prefs->getValue('default_share');
    }
    if (!array_key_exists($cal, Kronolith::listCalendars(false, _PERMS_EDIT))) {
        return PEAR::raiseError(_("Permission Denied"));
    }
    $calendar->open($cal);

    $vcs = &Horde_Data::singleton('icalendar');
    $result = $vcs->importData($icalendar_data);
    if (is_a($result, 'PEAR_Error')) {
        return PEAR::raiseError(sprintf(_("There was an error importing the iCalendar data: %s."), $result->getMessage()));
    }

    $events = array();
    $iMax = $vcs->count();
    for ($i = 0; $i < $iMax; $i++) {
        $hash = $vcs->toHash($i);
        $event = &$calendar->getEventObject();
        $event->fromHash($hash);
        $event->createEvent();
        $eventID = $event->save();
        if ($eventID) {
            $events[$eventID] = array($cal, $event->getTitle());
        } else {
            if (count($events)) {
                foreach ($events as $id => $name) {
                    $calendar->deleteEvent($id);
                }
            }
            return PEAR::raiseError(_("There was an error importing the iCalendar data."));
        }
    }

    return $events;
}

/**
 * Import a vEvent
 *
 * @param Horde_iCalendar_vevent   $vevent The event to import
 * @param String                   $cal    (optional) The callendar to import
 *                                          the event to, default is taken from
 *                                          default_share preference.
 *
 * @return Array    Array containing details of the event
 *                  or PEAR_Error on failure.
 */
function _kronolith_import_vevent($vevent, $cal = null)
{
    require_once dirname(__FILE__) . '/base.php';
    global $calendar, $prefs;

    // Set the calendar to the user's default calendar if none is
    // specified, and check for permissions to that calendar.
    if (is_null($cal)) {
        $cal = $prefs->getValue('default_share');
    }
    if (!array_key_exists($cal, Kronolith::listCalendars(false, _PERMS_EDIT))) {
        return PEAR::raiseError(_("Permission Denied"));
    }
    $calendar->open($cal);

    if (!is_a($vevent, 'Horde_iCalendar_vevent')) {
        require_once HORDE_BASE . '/lib/iCalendar.php';
        $vCal = &new Horde_iCalendar();
        if (!$vCal->parsevCalendar($vevent)) {
            return PEAR::raiseError(_("There was an error importing the iCalendar data."));
        }

        $components = $vCal->getComponents();
        switch (count($components)) {
        case 0:
            return PEAR::raiseError(_("No iCalendar data was found."));

        case 1:
            $vevent = $components[0];
            if (!is_a($vevent, 'Horde_iCalendar_vevent')) {
                return PEAR::raiseError(_("vEvent not found."));
            }
            break;

        case 2:
            return PEAR::raiseError(_("Multiple iCalendar components found. Use calendar/import_icalendar instead."));
        }
    }

    $hash = $vevent->toKronolithHash();

    $event = &$calendar->getEventObject();
    $event->fromHash($hash);
    $event->createEvent();
    $eventID = $event->save();
    if ($eventID) {
        return array('calendar' => $cal,
                     'event' => $event->getTitle(),
                     'eventID' => $eventID);
    } else {
        return PEAR::raiseError(_("There was an error importing the iCalendar data."));
    }
}

/**
 * Export Freebusy information for a given time period.
 *
 * @param integer $startstamp  The start of the time period to retrieve.
 * @param integer $endstamp    The end of the time period to retrieve.
 * @param string  $calendar    (optional) The calendar to view free/busy
 *                             slots for.
 *
 * @return Horde_iCalendar_vfreebusy    Freebusy object that covers the
 *                                      specified time period.
 */
function _kronolith_export_vfreebusy($startstamp, $endstamp, $calendar = null)
{
    global $prefs;
    require_once dirname(__FILE__) . '/base.php';

    if (is_null($calendar)) {
        $calendar = $prefs->getValue('default_share');
    }

    $vFb = Kronolith::generateFreeBusy($calendar, $startstamp, $endstamp, true);

    return $vFb;
}
