<?php
/**
 * $Horde: imp/mailbox.php,v 2.519 2003/08/07 09:25:58 jan Exp $
 *
 * Copyright 1999-2003 Charles J. Hagenbuch <chuck@horde.org>
 * Copyright 1999-2003 Jon Parise <jon@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.
 */

/**
 * Delete a list of messages.
 */
function _deleteMessages($indices)
{
    global $imp, $mailbox_url;

    if (!empty($indices)) {
        require_once IMP_BASE . '/lib/Message.php';
        $imp_message = &new IMP_Message();
        $imp_message->delete($indices);

        /* For POP3, redirect so that refreshing the page doesn't delete more
           messages accidentally. */
        if ($imp['base_protocol'] == 'pop3') {
            header('Location: ' . Horde::url($mailbox_url, true));
            exit;
        }

        return true;
    }

    return false;
}

/**
 * Stylize a string.
 */
function _stylize($string, $styles)
{
    if (!is_array($styles)) {
        return $string;
    }

    foreach ($styles as $style) {
        if (!empty($style)) {
            $string = '<' . $style . '>' . $string . '</' . $style . '>';
        }
    }

    return $string;
}

/**
 * Open a compose window.
 */
function _openComposeWin($options = array())
{
    global $prefs;

    if ($prefs->getValue('compose_popup')) {
        return true;
    } else {
        $options += IMP::getComposeArgs();
        $url = Horde::addParameter(Horde::applicationUrl('compose.php', true), $options);
        header('Location: ' . $url);
        return false;
    }
}

$do_filter = false;
$open_compose_window = false;
$set = false;
if (isset($new_lang)) {
    $language = $new_lang;
    $set = true;
}

@define('IMP_BASE', dirname(__FILE__));
require_once IMP_BASE . '/lib/base.php';
require_once IMP_BASE . '/lib/Mailbox.php';
require_once IMP_BASE . '/lib/Search.php';
require_once HORDE_BASE . '/lib/MIME.php';
require_once HORDE_BASE . '/lib/Identity.php';
require_once HORDE_BASE . '/lib/Text.php';

/* There is a chance that this page is loaded directly via
   message.php. If so, don't re-include config files, and the
   following variables will already be set: $actionID, $start. */
if (!isset($from_message_page)) {
    require HORDE_BASE . '/config/html.php';
    require IMP_BASE . '/config/html.php';
}

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

/* $actionID may be set in message.php already. */
if (!isset($from_message_page)) {
    $actionID = Horde::getFormData('actionID');
}

if ($actionID == 'login_compose') {
    $open_compose_window = _openComposeWin();
}

/* Get form data and make sure it's the type that we're expecting. */
$targetMbox = Horde::getFormData('targetMbox');
$newMbox = Horde::getFormData('newMbox');
if (!is_array(($indices = Horde::getFormData('indices')))) {
    $indices = array($indices);
}

/* Set the current time zone. */
NLS::setTimeZone();

/* Initialize the user's identities. */
$identity = &Identity::singleton(array('imp', 'imp'));

/* Get the base URL for this page. */
if (isset($from_message_page)) {
    $mailbox_url = Horde::applicationURL('mailbox.php');
} else {
    $mailbox_url = Horde::selfURL();
}

/* Check for 'sortby' and 'sortdir' changes. */
if (($sortby = Horde::getFormData('sortby')) !== null) {
    $prefs->setValue('sortby', $sortby);
}
if (($sortdir = Horde::getFormData('sortdir')) !== null) {
    $prefs->setValue('sortdir', $sortdir);
}

/* Run through the action handlers */
switch ($actionID) {
case 'blacklist':
    require_once IMP_BASE . '/lib/Filter.php';
    IMP_Filter::blacklistMessage($indices);
    break;

case 'whitelist':
    require_once IMP_BASE . '/lib/Filter.php';
    IMP_Filter::whitelistMessage($indices);
    break;

case 'spam_report':
    require_once IMP_BASE . '/lib/Contents.php';

    /* Abort immediately if spam reporting has not been enabled. */
    if (!$conf['spam']['reporting']) {
        break;
    }

    /* We know we have at least 1 message */
    $msg_count = 0;

    foreach ($indices as $msgnum) {
        /* Fetch the raw message contents (headers and complete body). */
        $imp_contents = &new IMP_Contents($msgnum);
        $raw_msg = $imp_contents->fullMessageText();

        $msg_count++;

        /* If a spam reporting program has been provided, use it. */
        if (!empty($conf['spam']['program'])) {
            /* Use a pipe to write the message contents. This should be
               secure. */
            $pipe = popen($conf['spam']['program'], 'w');
            fwrite($pipe, $raw_msg);
            pclose($pipe);
        }

        /* If a spam reporting email address has been provided, use it. */
        if (!empty($conf['spam']['email'])) {
            require_once IMP_BASE . '/lib/Compose.php';
            $imp_compose = &new IMP_Compose();
            $imp_compose->sendSpamReportMessage($raw_msg);
        }
    }

    /* Report what we've done. */
    if (!empty($conf['spam']['program'])) {
        if ($msg_count > 1) {
            $notification->push(sprintf(_("%d messages have been reported as spam."), $msg_count), 'horde.message');
        } else {
            $notification->push(_("1 message has been reported as spam."), 'horde.message');
        }
    }

    if (!empty($conf['spam']['email'])) {
        if ($msg_count > 1) {
            $notification->push(sprintf(_("%d messages have been reported as spam to your system administrator."), $msg_count), 'horde.message');
        } else {
            $notification->push(_("1 message has been reported as spam to your system administrator."), 'horde.message');
        }
    }

    /* Delete Spam after report */
    if ($prefs->getValue('delete_spam_after_report')) {
        if (_deleteMessages($indices)) {
            $notification->push(sprintf(_("%d message(s) have been deleted."),
                                          $msg_count), 'horde.message');
        }
    }
    break;

case 'message_missing':
    $notification->push(_("There was an error viewing the requested message."), 'horde.error');
    break;

case 'fwd_digest':
    $options['fwddigest'] = serialize($indices);
    $options['actionID'] = 'fwd_digest';
    $open_compose_window = _openComposeWin($options);
    break;

case 'delete_messages':
    _deleteMessages($indices);
    break;

case 'undelete_messages':
    if (!empty($indices)) {
        require_once IMP_BASE . '/lib/Message.php';
        $imp_message = &new IMP_Message();
        $imp_message->undelete($indices);
    }
    break;

case 'move_messages':
case 'copy_messages':
    if (!empty($indices) && !empty($targetMbox)) {
        require_once IMP_BASE . '/lib/Message.php';
        $imp_message = &new IMP_Message();
        $action = ($actionID == 'move_messages') ? IMP_MESSAGE_MOVE : IMP_MESSAGE_COPY;
        if (!empty($newMbox) && ($newMbox == 1)) {
            $new_mailbox = IMP::addPreambleString(String::convertCharset($targetMbox, NLS::getCharset(), 'UTF7-IMAP'));

            require_once IMP_BASE . '/lib/Folder.php';
            $imp_folder = &IMP_Folder::singleton();
            if ($imp_folder->create($imp['stream'], $new_mailbox, $prefs->getValue('subscribe'))) {
                $imp_message->copy($new_mailbox, $action, $indices);
            }
        } else {
            $imp_message->copy($targetMbox, $action, $indices);
        }
    }
    break;

case 'flag_messages':
    $flag = Horde::getPost('flag');
    if (!empty($indices) && !empty($flag)) {
        if ($flag[0] == '0') {
            $_POST['flag'] = '\\' . substr($flag, 1);
            $set = false;
        } else {
            $_POST['flag'] = '\\' . $flag;
            $set = true;
        }
        require_once IMP_BASE . '/lib/Message.php';
        $imp_message = &new IMP_Message();
        $imp_message->flag($_POST['flag'], $indices, $set);
    }
    break;

case 'hide_deleted':
    $prefs->setValue('delhide', !$prefs->getValue('delhide'));
    break;

case 'expunge_mailbox':
    require_once IMP_BASE . '/lib/Message.php';
    $imp_message = &new IMP_Message();
    $imp_message->expungeMailbox();
    break;

case 'filter':
    $do_filter = true;
    break;

case 'empty_mailbox':
    require_once IMP_BASE . '/lib/Message.php';
    $imp_message = &new IMP_Message();
    $imp_message->emptyMailbox();
    if ($url = Horde::getFormData('return_url')) {
        header('Location: ' . str_replace('&amp;', '&', $url));
        exit;
    }
    break;
}

/* Deal with filter options. */
if ($imp['filteravail'] && ($imp['mailbox'] == 'INBOX')) {
    if ($prefs->getValue('filter_on_display')) {
        $do_filter = true;
    } else {
        $filter_url = Horde::addParameter($mailbox_url, 'actionID', 'filter');
    }
}

/* Run filters now. */
if ($do_filter) {
    require_once IMP_BASE . '/lib/Filter.php';
    IMP_Filter::filter();
}

/* Generate folder options list. */
if ($conf['user']['allow_folders']) {
    $folder_options = IMP::flistSelect(_("Messages to"), true, array($imp['mailbox']), null, true);
}

/* Get the start index. It may already be set from message.php. */
if (!isset($from_message_page)) {
    $start = Horde::getFormData('start');
}

/* Build the list of messages in the mailbox. */
if (!isset($imp_mailbox)) {
    $imp_mailbox = &new IMP_Mailbox();
}
$pageOb = $imp_mailbox->buildMailboxPage(Horde::getFormData('page'), $start);

/* Generate First/Previous page links. */
if ($pageOb->page == 1) {
    $pages_first = Horde::img('nav/first-grey.gif', '', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde'));
    $pages_prev = Horde::img('nav/left-grey.gif', '', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde'));
} else {
    $first_url = Horde::addParameter($mailbox_url, 'page', 1);
    $pages_first = Horde::link($first_url, _("First Page")) . Horde::img('nav/first.gif', '&lt;&lt; [ ' . _("First Page") . ' ]', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde')) . '</a>';
    $prev_url = Horde::addParameter($mailbox_url, 'page', $pageOb->page - 1);
    $pages_prev = Horde::link($prev_url, _("Previous Page")) . Horde::img('nav/left.gif', '&lt; [ ' . _("Previous Page") . ' ]', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde')) . '</a>';
}

/* Generate Next/Last page links. */
if ($pageOb->page == $pageOb->pagecount) {
    $pages_last = Horde::img('nav/last-grey.gif', '', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde'));
    $pages_next = Horde::img('nav/right-grey.gif', '', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde'));
} else {
    $next_url = Horde::addParameter($mailbox_url, 'page', $pageOb->page + 1);
    $pages_next = Horde::link($next_url, _("Next Page")) . Horde::img('nav/right.gif', '[ ' . _("Next Page") . ' ] &gt;', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde')) . '</a>';
    $last_url = Horde::addParameter($mailbox_url, 'page', $pageOb->pagecount);
    $pages_last = Horde::link($last_url, _("Last Page")) . Horde::img('nav/last.gif', '[ ' . _("Last Page") . ' ] &gt;&gt;', 'width="16" height="16" align="middle"', $registry->getParam('graphics', 'horde')) . '</a>';
}

/* Determine if we are going to show the Hide/Purge Deleted Message links. */
$showdelete = $imp_mailbox->showDeleteLinks();
if ($showdelete && !$prefs->isLocked('delhide')) {
    if ($prefs->getValue('delhide')) {
        $deleted_prompt = _("Show Deleted");
    } else {
        $deleted_prompt = _("Hide Deleted");
    }
}

/* Generate mailbox summary string. */
if (!empty($pageOb->end)) {
    $msg_count = sprintf(_("%d to %d of %d Messages"), $pageOb->begin, $pageOb->end, $pageOb->msgcount);
} else {
    $msg_count = sprintf(_("No Messages"));
}

/* If user wants the mailbox to be refreshed, set time here. */
$refresh_time = $prefs->getValue('refresh_time');
$refresh_url = Horde::addParameter($mailbox_url, 'page', $pageOb->page);
if (isset($filter_url)) {
    $filter_url = Horde::addParameter($filter_url, 'page', $pageOb->page);
}

/* Set the folder for the sort links. */
$sortdir = $prefs->getValue('sortdir');
$sort_url = Horde::addParameter($mailbox_url, 'sortdir', ($sortdir) ? 0 : 1);

/* If we are showing a preview, define some other variables. */
$show_preview = ($conf['mailbox']['show_preview'] && $prefs->getValue('preview_enabled'));
$preview_tooltip = false;
if ($show_preview) {
    $preview_unread = $prefs->getValue('preview_show_unread');
    $preview_maxlen = $prefs->getValue('preview_maxlen');
    if ($preview_maxlen != -1) {
        $preview_maxlen = max(5, ($preview_maxlen - 3));
    }
    $preview_strip = $prefs->getValue('preview_strip_nl');
    if (($preview_tooltip = $prefs->getValue('preview_show_tooltip'))) {
        Horde::addScriptFile('tooltip.js', 'horde');
    }
}

$title = IMP::getLabel();

require IMP_TEMPLATES . '/common-header.inc';
if ($preview_tooltip) {
    echo '<div id="tooltip" style="position: absolute; visibility: hidden;"></div>';
}
if ($browser->hasFeature('javascript')) {
    require IMP_TEMPLATES . '/mailbox/javascript.inc';
}
IMP::menu();
IMP::status();

/* Print 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) {
        $quotaDriver->quotaHTML();
    }
}

/* Build the array of message information. */
$mailboxOverview = $imp_mailbox->buildMailboxArray($pageOb->begin, $pageOb->index, $pageOb->end, $imp_mailbox->getSorted(), $imp_mailbox->getSortedMbox());

/* Are we currently in the trash mailbox? */
$preamble = IMP::preambleString();
$use_trash = $prefs->getValue('use_trash');
$trashMbox = ($use_trash && ($imp['mailbox'] == ($preamble . $prefs->getValue('trash_folder'))));

/* Is this a search mailbox? */
$search_mbox = ($imp['mailbox'] == IMP_SEARCH_MBOX);

/* Show the [black|white]list link if we have functionality enabled. */
$show_blacklist_link = $registry->hasMethod('mail/blacklistFrom');
$show_whitelist_link = $registry->hasMethod('mail/whitelistFrom');

require IMP_TEMPLATES . '/mailbox/header.inc';

/* If there is more than 15 messages , cache the actions output. */
if ($pageOb->msgcount != 0) {
    $navform = 1;
    require IMP_TEMPLATES . '/mailbox/navbar.inc';
    if ($pageOb->msgcount > 15) {
        ob_start();
        require IMP_TEMPLATES . '/mailbox/actions.inc';
        $actions_output = ob_get_contents();
        ob_end_clean();
        echo $actions_output;
    } else {
        require IMP_TEMPLATES . '/mailbox/actions.inc';
    }
} elseif ($pageOb->anymsg && isset($deleted_prompt)) {
    /* Show 'Show Deleted' prompt if mailbox has no viewable message but
       has hidden, deleted messages. */
    require IMP_TEMPLATES . '/mailbox/actions_deleted.inc';
}

/* Define some variables now so we don't have to keep redefining in the
   foreach() loop or the templates. */
$bgcolors = array();
$curr_time = time();
$curr_time -= $curr_time % 60;
$drafts_sm_folder = $imp_mailbox->isSpecialFolder();
$lastMbox = '';
$messages = array();

/* Determine sorting preferences. */
$sortby = $imp_mailbox->sortby();
$thread_sort = ($sortby == SORTTHREAD);
$sortlimit = $imp_mailbox->aboveSortLimit();

/* Don't show header row if this is a search mailbox or if no messages in the
   current mailbox. */
if (!$search_mbox && ($pageOb->msgcount != 0)) {
    require IMP_TEMPLATES . '/mailbox/message_headers.inc';
}

/* Cache some repetitively used variables. */
$datefmt = $prefs->getValue('date_format');
$timefmt = $prefs->getValue('time_format');
$maxfrom = $prefs->getValue('max_from_chars');
$maxsubj = $prefs->getValue('max_subj_chars');
$fromlinkstyle = $prefs->getValue('from_link');

/* Display message information. */
foreach ($mailboxOverview as $msgIndex => $message) {
    if ($search_mbox) {
        if (empty($lastMbox) || ($message['mbox'] != $lastMbox)) {
            $folder_link = Horde::url(Horde::addParameter('mailbox.php', 'mailbox', $message['mbox']));
            $folder_link = Horde::link($folder_link, sprintf(_("View messages in %s"), IMP::displayFolder($message['mbox'])), 'smallheader') . IMP::displayFolder($message['mbox']) . '</a>';
            require IMP_TEMPLATES . '/mailbox/searchfolder.inc';
            require IMP_TEMPLATES . '/mailbox/message_headers.inc';
        }
        $lastMbox = $message['mbox'];
    }

    /* Initialize the header fields. */
    $msg = array();
    $msg['color'] = (isset($message['color'])) ? $message['color'] : '';
    $msg['date'] = '&nbsp;';
    $msg['from'] = '&nbsp;';
    $msg['preview'] = '';
    $msg['to'] = '';
    $msg['size'] = '?';
    $msg['subject'] = _("[No Subject]");
    $attachment = false;
    $from_adr = null;
    $mailto_link = false;

    /* Now pull the IMAP header values into them, decoding them at
       the same time. */
    $h = $message['header'];
    $messages[] = $h->uid;

    /* Formats the header date string nicely. */
    if (!empty($h->date) && ($udate = strtotime($h->date, $curr_time)) != -1) {
        if ((date('Y') != @date('Y', $udate)) ||
            (date('M') != @date('M', $udate)) ||
            (date('d') != @date('d', $udate))) {
            /* Not today, use the date. */
            $msg['date'] = @strftime($datefmt, $udate);
        } else {
            /* Else, it's today, use the time. */
            $msg['date'] = @strftime($timefmt, $udate);
        }
    }

    /* Format the from header. */
    if (isset($h->from)) {
        $tmp = array_shift(imap_rfc822_parse_adrlist($h->from, ''));
        $from_adr = IMP::bareAddress($h->from);

        if (isset($tmp->personal)) {
            $msg['from'] = trim(MIME::decode($tmp->personal), '"');
            if (!trim($msg['from'], chr(160) . ' ')) {
                $msg['from'] = $from_adr;
            }
        } else {
            $msg['from'] = $from_adr;
        }
    }

    if (!is_null($from_adr) && $identity->hasAddress($from_adr)) {
        if (isset($h->to)) {
            $tmp = array_shift(imap_rfc822_parse_adrlist($h->to, ''));
            if (isset($tmp->personal)) {
                $msg['to'] = MIME::decode($tmp->personal);
            } else {
                $msg['to'] = IMP::bareAddress($h->to);
            }
        } else {
            $msg['to'] = _("Undisclosed Recipients");
        }
        if ($drafts_sm_folder) {
            $msg['from'] = $msg['to'];
        } else {
            $msg['from'] = _("To") . ': ' . $msg['to'];
        }
        $mailto_link = true;
    }

    if (String::length($msg['from']) > $maxfrom) {
        $msg['from'] = String::substr($msg['from'], 0, $maxfrom) . '...';
    }

    if (!empty($h->subject)) {
        $msg['subject'] = strtr(MIME::decode($h->subject), "\t", ' ');
    }
    $msg['fullsubject'] = $msg['subject'];

    if (isset($h->size)) {
        $msg['size'] = ($h->size > 1024)
            ? sprintf(_("%.0fkb"), $h->size / 1024)
            : $h->size;
    }

    if ($thread_sort || $search_mbox) {
        if (String::length($msg['subject']) > $maxsubj) {
            $msg['subject'] = String::substr($msg['subject'], 0, $maxsubj) . '...';
        }
    } else {
        $maxlen = $maxsubj - (3 * $imp_mailbox->getThreadIndent($h->uid));
        if ($maxlen < 5) {
            $maxlen = 5;
        }
        if (String::length($msg['subject']) > $maxlen) {
            $msg['subject'] = String::substr($msg['subject'], 0, $maxlen) . '...';
        }
    }

    /* Filter the subject text, if requested. */
    $msg['subject'] = IMP::filterText($msg['subject']);
    $msg['fullsubject'] = IMP::filterText($msg['fullsubject']);

    if (isset($message['structure'])) {
        if (!empty($message['structure']->subtype)) {
            if (String::lower($message['structure']->subtype) == 'signed' ||
                String::lower($message['structure']->subtype) == 'encrypted') {
                $attachment = 'signed';
            } elseif (String::lower($message['structure']->subtype) == 'alternative') {
                $attachment = 'alternative';
            } elseif (isset($message['structure']->parts) &&
                      is_array($message['structure']->parts) &&
                      count($message['structure']->parts) > 0) {
                $attachment = 'attachment';
            } elseif ((!empty($message['structure']->type) &&
                       $message['structure']->type != TYPETEXT) ||
                      !empty($message['structure']->subtype) &&
                      String::lower($message['structure']->subtype) != 'plain') {
                $attachment = 'attachment';
            }
        }
    }

    /* Generate the target link. */
    $msgMbox = isset($message['mbox']) ? $message['mbox'] : '';
    $target = IMP_Search::generateSearchUrl('message.php', $msgMbox);
    $target = Horde::addParameter($target, 'index', $h->uid);

    /* Get all the flag information. */
    $bg = 'text';
    $flagbits = 0;
    $status = '';
    $style = array();
    $xprio = false;

    /* Check for X-Priority information. */
    if ($conf['mailbox']['show_xpriority']) {
        require_once IMP_BASE . '/lib/Headers.php';
        $imp_headers = &new IMP_Headers($h->uid);
        $imp_headers->buildHeaders();
        $imp_headers->buildFlags();
        if (($priority = $imp_headers->getValue('x-priority'))) {
            if (preg_match('/\s*(\d+)\s*/', $priority, $matches)) {
                if (($matches[1] == '1') || ($matches[1] == '2')) {
                    $xprio = true;
                }
            }
        }
    }

    if ($imp['base_protocol'] != 'pop3') {
        if (!empty($h->to) && $identity->hasAddress(IMP::bareAddress($h->to))) {
            $status .= Horde::img('personal.gif', _("Personal"));
            $flagbits |= IMP_PERSONAL;
        }
        if (!$h->seen) {
            $flagbits |= IMP_UNSEEN;
            $status .= Horde::img('unseen.gif', _("Unread"));
            $style[] = 'b';
            $bg = 'unseen';
        }
        if ($h->answered) {
            $flagbits |= IMP_ANSWERED;
            $status .= Horde::img('answered.gif', _("Answered"));
            $bg = 'answered';
        }
        if ($h->draft) {
            $flagbits |= IMP_DRAFT;
            $status .= Horde::img('draft.gif', _("Draft"));
            $target = IMP::composeLink(array(), array('actionID' => 'draft', 'mailbox' => $imp['mailbox'], 'index' => $h->uid));
        }
        if ($xprio) {
            $flagbits |= IMP_FLAGGED;
            $status .= Horde::img('important.gif', _("Important"));
            $style[] = 'i';
            $bg = 'important';
        }
        if ($h->flagged) {
            $flagbits |= IMP_FLAGGED;
            $status .= Horde::img('important.gif', _("Important"));
            $style[] = 'i';
            $bg = 'important';
        }
        if ($h->deleted) {
            $flagbits |= IMP_DELETED;
            $status .= Horde::img('deleted.gif', _("Deleted"));
            $style[] = 'strike';
            $bg = 'deleted';
        }
        $flags[] = $flagbits;
    } else {
        $flags[] = 0;
    }
    $bgcolors[] = $css['.' . $bg]['background-color'];
    $bgcolors[] = $css['.' . $bg . '-hi']['background-color'];

    if ($conf['mailbox']['show_attachments'] && $attachment) {
        $status .= Horde::img($attachment . '.gif', _("Attachment"));
    }

    /* Apply styles */
    $styledat = _stylize($msg['date'], $style);
    $stylefrm = _stylize(htmlspecialchars($msg['from']), $style);
    $stylesub = _stylize(Text::htmlSpaces($msg['subject']), $style);
    if ($thread_sort && !$search_mbox) {
        $indentLevel = $imp_mailbox->getThreadIndent($h->uid);
        $stylesub = (($indentLevel > 2) ? Horde::img('folders/spacer.gif', '', 'height="1" width="' . ($indentLevel - 2) * 20 . '"') : '') . (($indentLevel > 1) ? Horde::img('thread.gif', '-', 'width="14" height="14" border="0" align="absmiddle"') . '&nbsp;&nbsp;' : '') . $stylesub;
    }

    /* Set the message number. */
    $msg['number'] = $h->msgno;

    /* Decide what to do in the from column (after we've possibly applied
       styles to $from). */
    if ($fromlinkstyle == 1) {
        $from_uri = IMP_Search::generateSearchUrl('message.php', $msgMbox);
        $from_uri = Horde::addParameter($from_uri, 'index', $h->uid);
        $from_link = Horde::link($from_uri, $msg['from']) . $stylefrm . '</a>';
    } elseif ($fromlinkstyle == 0) {
        $extra = array('actionID' => 'mailto', 'mailbox' => $imp['mailbox'], 'index' => $h->uid, 'mailto' => $mailto_link);
        if ($search_mbox) {
            $extra['thismailbox'] = $mailboxOverview[$msgIndex]['mbox'];
        }
        $from_link = Horde::link(IMP::composeLink(array(), $extra), sprintf(_("Compose Message (%s)"), $msg['from'])) . $stylefrm . '</a>';
    } else {
        $from_link = $stylefrm;
    }

    /* We now want to fetch the first X lines of the body text, to display
       the summary below the subject text for each mail. */
    if ($show_preview) {
        if (!$preview_unread || ($bg == 'unseen')) {

            $msg['preview'] = trim(imap_fetchbody($imp['stream'], $h->msgno, 1));
            $msg['preview'] = Text::toHTML($msg['preview'], TEXT_HTML_NOHTML, '', '');

            if (($preview_maxlen != -1) &&
                (String::length($msg['preview']) > $preview_maxlen)) {
                $msg['preview'] = String::substr($msg['preview'], 0, $preview_maxlen) . '...';
            }

            $msg['preview'] = trim($msg['preview']);
            if ($preview_strip) {
                $msg['preview'] = str_replace('<br />', ' ', $msg['preview']);
            } else {
               $msg['preview'] = preg_replace('/<br \/>(<br \/>)+/', '<br />', $msg['preview']);
            }

            $msg['preview'] = trim($msg['preview']);
        }
    }

    require IMP_TEMPLATES . '/mailbox/message_summaries.inc';
}

if (empty($pageOb->end)) {
    if ($search_mbox) {
        require IMP_TEMPLATES . '/mailbox/message_headers.inc';
    }
    require IMP_TEMPLATES . '/mailbox/empty_mailbox.inc';
}

/* Don't output this information if the mailbox is empty. */
if ($pageOb->msgcount != 0) {
    require IMP_TEMPLATES . '/mailbox/message_footers.inc';
    if ($prefs->getValue('show_legend') && ($imp['base_protocol'] != 'pop3')) {
        require IMP_TEMPLATES . '/mailbox/legend.inc';
    }
}

/* If there are 15 messages or less, don't show the actions/navbar again. */
if (isset($actions_output)) {
    echo $actions_output;
    $navform = 2;
    require IMP_TEMPLATES . '/mailbox/navbar.inc';
} else {
    echo '<tr><td class="control" colspan="6"></td></tr>';
}

require IMP_TEMPLATES . '/mailbox/footer.inc';

$newmsgs = $imp_mailbox->newMessageCount();
if ($prefs->getValue('nav_popup') && ($newmsgs > 0) && !Horde::getFormData('no_newmail_popup')) {
    require IMP_TEMPLATES . '/mailbox/alert.inc';
}

if (!empty($open_compose_window)) {
    $args = 'popup=1';
    if (isset($options)) {
        foreach ($options as $arg => $value) {
            $args .= !empty($value) ? '&' . $arg . '=' . urlencode($value) : '';
        }
    }
    foreach (IMP::getComposeArgs('array') as $arg => $value) {
        $args .= !empty($value) ? '&' . $arg . '=' . urlencode($value) : '';
    }
    echo "<script language='JavaScript' type='text/javascript'>open_compose_win('" . addslashes($args) . "');</script>";
}

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

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