<?php
/**
 * $Horde: imp/folders.php,v 2.217 2003/07/26 22:11:12 chuck Exp $
 *
 * Copyright 2000-2003 Charles J. Hagenbuch <chuck@horde.org>
 * Copyright 2000-2003 Jon Parise <jon@horde.org>
 * Copyright 2000-2003 Anil Madhavapeddy <avsm@horde.org>
 *
 * See the enclosed file COPYING for license information (GPL).  If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 */

/**
 * This reinitializes the $imaptree variable and recalculates the folder
 * list.
 *
 * @param object IMP_Tree $imaptree  The IMAP tree.
 * @param boolean $showall           Show all?
 */
function _initializeTree(&$imaptree, $showall)
{
    global $prefs;

    $imaptree->init($prefs->getValue('subscribe') && !$showall);

    switch ($prefs->getValue('nav_expanded')) {
    case 1:
        $imaptree->expandAllFolders();
        break;

    case 2:
        $imaptree->expandAsLast();
        break;
    }
}

/**
 * Utility function to return a url for the various folder images.
 *
 * @param string $name     Image filename.
 * @param string $alt      Image alt tag.
 * @param integer $width   Image width.
 * @param integer $height  Image height.
 *
 * @return string  Link to the folder image.
 */
function _folderImage($name, $alt, $width, $height)
{
    return Horde::img('folders/' . $name, $alt, '" hspace="0" border="0" width="' . $width . '" height="' . $height . '"');
}

$authentication = OP_HALFOPEN;
define('IMP_BASE', dirname(__FILE__));
require_once IMP_BASE . '/lib/base.php';
require_once IMP_BASE . '/lib/Tree.php';
require_once IMP_BASE . '/lib/Folder.php';

/* Redirect back to the mailbox if folder use is not allowed. */
if (!$conf['user']['allow_folders']) {
    header('Location: ' . Horde::applicationUrl('mailbox.php', true));
    exit;
}

/* Obtain the IMP $css array so that mouseovers will work. */
Horde::getThemeConfig(IMP_BASE);

/* Get quota information. */
if (isset($imp['quota']) && is_array($imp['quota'])) {
    require_once IMP_BASE . '/lib/Quota.php';
    $quotaDriver = &IMP_Quota::singleton($imp['quota']['driver'], $imp['quota']['params']);
    if ($quotaDriver !== false) {
        $quota_html = Horde::bufferOutput(array($quotaDriver, 'quotaHTML'));
    }
    IMP::checkAuthentication(OP_HALFOPEN, true);
}

/* Get the base URL for this page. */
$folders_url = Horde::selfURL();

/* Initialize the IMP_Folder & IMP_Tree objects. */
$imp_folder = &IMP_Folder::singleton();
$imaptree = &new IMP_Tree($imp['dotfiles'], $imp['hierarchies']);

/* Check to see if user has a defined set of folders to poll. */
if (!$prefs->isLocked('nav_poll')) {
    $folderPollList = @unserialize($prefs->getValue('nav_poll'));
}

/* If not, then only check the INBOX. */
if (!isset($folderPollList) || !is_array($folderPollList)) {
    $folderPollList = array('INBOX' => true);
}

/* Decide whether or not to show all the unsubscribed folders */
if ($prefs->getValue('subscribe') && isset($imp['showunsub'])) {
    $showAll = $imp['showunsub'];
} else {
    $showAll = false;
}

if (isset($imp['imaptree']) && is_array($imp['imaptree'])) {
    $imaptree->unpickle($imp['imaptree']);
} else {
    _initializeTree($imaptree, $showAll);
}

$folder_list = Horde::getFormData('folder_list');
$refresh_time = $prefs->getValue('refresh_time');

/* Run through the action handlers */
$actionID = Horde::getFormData('actionID');
switch ($actionID) {
case 'expand_folder':
    $folder = Horde::getFormData('folder');
    if (!empty($folder)) {
        $imaptree->expand($folder);
    }
    break;

case 'expand_all_folders':
    $imaptree->expandAllFolders();
    break;

case 'collapse_folder':
    $folder = Horde::getFormData('folder');
    if (!empty($folder)) {
        $imaptree->collapse($folder);
    }
    break;

case 'collapse_all_folders':
    $imaptree->collapseAllFolders();
    break;

case 'refresh_folders':
    _initializeTree($imaptree, $showAll);
    break;

case 'delete_folder':
    if (is_array($folder_list)) {
        if ($imp_folder->delete($imp['stream'], $folder_list, $prefs->getValue('subscribe'))) {
            foreach ($folder_list as $folder) {
                $imaptree->delete(IMP::serverString($folder));
                unset($folderPollList[$folder]);
            }
            $prefs->setValue('nav_poll', serialize($folderPollList));
        }
    }
    break;

case 'download_folder':
case 'download_folder_zip':
    if (is_array($folder_list)) {
        $mbox = $imp_folder->generateMbox($imp['stream'], $folder_list, false);
        if ($actionID == 'download_folder') {
            $browser->downloadHeaders($folder_list[0] . '.mbox', null, false, strlen($mbox));
        } else {
            include_once HORDE_BASE . '/lib/Compress.php';
            $horde_compress = &Horde_Compress::singleton('zip');
            $mbox = $horde_compress->compress(array(array('data' => $mbox, 'name' => $folder_list[0] . '.mbox')));
            $browser->downloadHeaders($folder_list[0] . '.zip', 'application/zip', false, strlen($mbox));
        }
        echo $mbox;
        exit;
    }
    break;

case 'import_mbox':
    $import_folder = Horde::getFormData('import_folder');
    if (!empty($import_folder)) {
        include_once HORDE_BASE . '/lib/Server.php';
        $res = Server::wasFileUploaded('mbox_upload', _("mailbox file"));
        if (!is_a($res, 'PEAR_Error')) {
            $res = $imp_folder->importMbox($imp['stream'], $import_folder, $_FILES['mbox_upload']['tmp_name']);
            if ($res === false) {
                $notification->push(sprintf(_("There was an error importing %s."), basename($_FILES['mbox_upload']['name'])), 'horde.error');
            } else {
                $notification->push(sprintf(_("Imported %d messages from %s."), $res,  basename($_FILES['mbox_upload']['name'])), 'horde.success');
            }
        } else {
            $notification->push($res, 'horde.error');
        }
        $actionID = null;
    }
    break;

case 'create_folder':
    $new_mailbox = Horde::getFormData('new_mailbox');
    if (!empty($new_mailbox)) {
        $new_mailbox = String::convertCharset($new_mailbox, NLS::getCharset(), 'UTF7-IMAP');
        if (is_array($folder_list) && count($folder_list) == 1) {
            $new_mailbox = $folder_list[0] . $imaptree->getDelimiter() . $new_mailbox;
        } elseif (!empty($imp['folders'])) {
            $new_mailbox = $imp['folders'] . $new_mailbox;
        }

        if ($imp_folder->create($imp['stream'], $new_mailbox, $prefs->getValue('subscribe'))) {
            _initializeTree($imaptree, $showAll);
        }
    }
    break;

case 'rename_folder':
    $new_names = explode("\n", Horde::getFormData('new_names'));
    $old_names = explode("\n", Horde::getFormData('old_names'));
    if (!empty($new_names) && !empty($old_names) &&
        (count($new_names) == count($old_names))) {
        $iMax = count($new_names);
        for ($i = 0; $i < $iMax; $i++) {
            $imp_folder->rename($imp['stream'], trim($old_names[$i], "\r\n"), IMP::addPreambleString(String::convertCharset(trim($new_names[$i], "\r\n"), NLS::getCharset(), 'UTF7-IMAP')), $prefs->getValue('subscribe'));
        }
        _initializeTree($imaptree, $showAll);
    }
    break;

case 'subscribe_folder':
case 'unsubscribe_folder':
    if (is_array($folder_list)) {
        if ($actionID == 'subscribe_folder') {
            $imp_folder->subscribe($imp['stream'], $folder_list);
        } else {
            $imp_folder->unsubscribe($imp['stream'], $folder_list);
        }
    } else {
        $notification->push(_("No folders were specified"), 'horde.message');
    }
    _initializeTree($imaptree, $showAll);
    break;

case 'toggle_subscribed_view':
    if ($prefs->getValue('subscribe')) {
        $imp['showunsub'] = ($showAll = !$showAll);
    }
    _initializeTree($imaptree, $showAll);
    break;

case 'poll_folder':
    if (is_array($folder_list) && !$prefs->isLocked('nav_poll')) {
        foreach ($folder_list as $folder) {
            $folderPollList[$folder] = true;
        }
        $prefs->setValue('nav_poll', serialize($folderPollList));
    }
    break;

case 'nopoll_folder':
    if (is_array($folder_list) && !$prefs->isLocked('nav_poll')) {
        foreach ($folder_list as $folder) {
            unset($folderPollList[$folder]);
        }
        $prefs->setValue('nav_poll', serialize($folderPollList));
    }
    break;

case 'folders_empty_mailbox':
    if (is_array($folder_list)) {
        include_once IMP_BASE . '/lib/Message.php';
        $imp_message = &new IMP_Message();
        $imp_message->emptyMailbox($folder_list);
    }
    break;
}

/* Display the correct message on the action bar */
$subToggleText = $showAll ? _("Hide Unsubscribed") : _("Show Unsubscribed");

/* Set the URL to refresh the page to in the META tag */
$refresh_url = Horde::applicationUrl('folders.php', true);

$title = _("Folder Navigator");
$js_onLoad = null;
require IMP_TEMPLATES . '/common-header.inc';
IMP::menu();
IMP::status();

/* Print quota information. */
if (isset($quota_html)) {
    echo $quota_html;
}

/* Default to the very top of the hierarchy */
if (!isset($pattern)) {
    $pattern = '%';
}

$i = 0;
$imaptree->reset();
$newmsgs = array();
$rowct = 0;

require_once IMP_TEMPLATES . '/folders/javascript.inc';
if ($imp['file_upload'] && ($actionID == 'import_mbox')) {
    require IMP_TEMPLATES . '/folders/import.inc';
    require IMP_TEMPLATES . '/common-footer.inc';
    exit;
} else {
    require IMP_TEMPLATES . '/folders/head.inc';
    require IMP_TEMPLATES . '/folders/actions.inc';
}

/* Always poll the INBOX for new mail. */
$nm = $imaptree->updateMessageInfo();
$hd = $imaptree->head();
if (isset($hd['newmsg']) && ($hd['newmsg'] > 0)) {
    $newmsgs['INBOX'] = $hd['newmsg'];
}

if ($showAll) {
    $unsubList = $imp_folder->flistUnsubscribed_IMP();
}

/* Start iterating through the list of mailboxes, displaying them. */
$mailbox = $imaptree->head();
$name_url = Horde::addParameter(Horde::applicationUrl('mailbox.php'), 'no_newmail_popup', 1);
while (isset($mailbox) && is_array($mailbox)) {
    /* Determine if we need to poll this mailbox for new messages. */
    if (isset($folderPollList[$mailbox['value']])) {
        /* If we need message information for this folder, update it now. */
        $imaptree->updateMessageInfo();
        $mailbox = $imaptree->current();
    } elseif (isset($mailbox['message'])) {
        /* If we have stale information in the imaptree cache, then zero
           it. */
        $imaptree->flushMessageInfo();
        $mailbox = $imaptree->current();
    }

    /* Populate the $newmsgs hash with new msgs since last view of the
       navigator. */
    if (isset($mailbox['newmsg']) && ($mailbox['newmsg'] > 0)) {
        $newmsgs[$mailbox['value']] = $mailbox['newmsg'];
    }

    /* Highlight mailboxes with unread messages in bold */
    if (!empty($mailbox['unseen'])) {
        $mailbox['label'] = '<b>' . $mailbox['label'] . '</b>';
    }

    if (!($mailbox['attributes'] & LATT_NOSELECT)) {
        $name = Horde::addParameter($name_url, 'mailbox', $mailbox['value']);
        $name = Horde::link($name, sprintf(_("View messages in %s"), IMP::displayFolder($mailbox['value']))) . $mailbox['label'] . '</a>';

        if ($mailbox['value'] == 'INBOX') {
            $dir2 = _folderImage('inbox.gif', _("INBOX"), 16, 16);
        } elseif ($mailbox['attributes'] & LATT_MARKED) {
            $dir2 = _folderImage('mbox_marked.gif', _("Mailbox"), 16, 16);
        } elseif ($mailbox['attributes'] & LATT_UNMARKED) {
            $dir2 = _folderImage('mbox_unmarked.gif', _("Mailbox"), 16, 16);
        } else {
            $dir2 = _folderImage('mbox.gif', _("Mailbox"), 16, 16);
        }
    } else {
        $name = $mailbox['label'];
        if ($imaptree->isOpen($mailbox)) {
            $dir2 = _folderImage('folder_open.gif', _("Open Folder"), 16, 16);
        } else {
            $dir2 = _folderImage('folder.gif', _("Closed Folder"), 16, 16);
        }
    }

    if ($imaptree->hasChildren($mailbox)) {
        $dir = Horde::addParameter($folders_url, 'folder', $imaptree->getServer() . $mailbox['value']);
        if ($imaptree->isOpen($mailbox)) {
            $dir = Horde::addParameter($dir, 'actionID', 'collapse_folder');
            $dir = Horde::link($dir, _("Collapse Folder")) . _folderImage('expanded.gif', _("Collapse Folder"), 18, 18) . "</a>$dir2";
        } else {
            $dir = Horde::addParameter($dir, 'actionID', 'expand_folder');
            $dir = Horde::link($dir, _("Expand Folder")) . _folderImage('collapsed.gif', _("Expand Folder"), 18, 18) . "</a>$dir2";
        }
    } else {
        $dir = _folderImage('empty.gif','', 18, 18) . $dir2;
    }

    /* Set up status information. */
    if ($name == $mailbox['label']) {
        $msgs = '&nbsp;';
        $new  = '&nbsp;';
    } else {
        if (isset($mailbox['messages'])) {
            $msgs = $mailbox['messages'];
        } else {
            $msgs = '&nbsp;';
        }
        if (isset($mailbox['unseen'])) {
            $new = $mailbox['unseen'];
        } else {
            $new = '&nbsp;';
        }
    }

    if ($showAll && isset($unsubList[$mailbox['value']])) {
        $navclass = 'folderunsub';
    } else {
        $navclass = (++$rowct % 2) ? 'list' : 'listlt';
    }

    $indent_level = $mailbox['level'];

    if (($imaptree->getPrefix() != '') &&
        ($mailbox['value'] != 'INBOX') &&
        String::substr($mailbox['value'], 0, String::length($imaptree->noTrailingDelimiter($imaptree->getPrefix()))) == $imaptree->noTrailingDelimiter($imaptree->getPrefix())) {
        /* We have a folder prefix, shift each folder in the hierarchy up
           one level before showing it to the user. */
        $indent_level--;
    }

    if ($indent_level < 0) {
        /* This is a folder prefix; hide it from the user, and revert rowct,
           since we hide the folder prefix. */
        $rowct++;
    } else {
        /* Display the folder. */
        include IMP_TEMPLATES . '/folders/row.inc';
        $displayNames[] = addslashes(IMP::displayFolder($mailbox['value']));
        $i++;
    }

    if ($imaptree->isOpen($mailbox)) {
        $mailbox = $imaptree->next();
    } else {
        $mailbox = $imaptree->nextOnLevel();
    }
}

/* Put the tree back into the session object for caching */
$imp['imaptree'] = $imaptree->pickle();

if ($rowct > 10) {
    require IMP_TEMPLATES . '/folders/actions.inc';
}

require IMP_TEMPLATES . '/folders/foot.inc';

/* Check to see if user wants new mail notification */
if ($prefs->getValue('nav_popup')) {
    global $__alert, $__mailbox_message;
    $__alert = '';
    $count = 0;
    foreach ($newmsgs as $mb => $nm) {
        $count++;
        $__mailbox_message = $mb;
        $__alert .= IMP::displayFolder($__mailbox_message) . ($nm > 1 ? _(" - $nm new messages") : _(" - $nm new message")) . '\n';
    }
    if (!empty($__alert)) {
        if ($count == 1) {
            include IMP_TEMPLATES . '/folders/confirm.inc';
        } else {
            include IMP_TEMPLATES . '/folders/alert.inc';
        }
    }
}

require IMP_TEMPLATES . '/common-footer.inc';

// Catch error messages from c-client.
imap_errors();
