<?php
/**
 * The IMP_MIME_Viewer_alternative class renders out messages from
 * multipart/alternative content types.
 *
 * $Horde: imp/lib/MIME/Viewer/alternative.php,v 1.35 2003/08/06 21:35:54 slusarz Exp $
 *
 * Copyright 2002-2003 Michael Slusarz <slusarz@bigworm.colorado.edu>
 *
 * See the enclosed file COPYING for license information (GPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 *
 * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
 * @version $Revision: 1.35 $
 * @since   IMP 4.0
 * @package horde.mime.viewer
 */
class IMP_MIME_Viewer_alternative extends MIME_Viewer {

    /**
     * The content-type of the preferred part.
     * Default: application/octet-stream
     *
     * @var string $_contentType
     */
    var $_contentType = 'application/octet-stream';

    /**
     * The alternative ID for this part.
     *
     * @var string $_altID
     */
    var $_altID = '-';

    /**
     * Render out the currently set contents.
     *
     * @access public
     *
     * @param array $params  An array with a reference to a MIME_Contents
     *                       object.
     *
     * @return string  The rendered text in HTML.
     */
    function render($params)
    {
        $contents = &$params[0];

        $altList = array();
        $display = null;
        $partList = $this->mime_part->getParts();

        /* Default: Nothing displayed. */
        $text = '<i>' . _("There are no alternative parts that can be displayed inline.") . '</i>';

        /* We need to override the MIME key to ensure that only one
           alternative part is displayed. */
        $this->_getAltID($contents, $partList);

        /* RFC 2046: We show the LAST choice that can be displayed inline. */
        foreach ($partList as $part) {
            if ($contents->canDisplayInline($part)) {
                $id = $part->getMIMEId();

                /* We can't assume that just because the MIME_Part is
                   viewable inline that we can display it - e.g.
                   multipart/mixed are viewable inline, but will not return
                   any data. */

                /* If the MIME_Viewer for this part returns text, this is a
                   viewable part. */
                $renderText = $contents->renderMIMEPart($part);

                /* We also must check the alternative ID MIME index to see if
                   some MIME Viewer (e.g. multipart/mixed) has stuck its
                   results there (both message text and attachments). */
                $altText = $contents->getIndex($this->_altID, 'message');
                if (empty($renderText)) {
                    if ($altText) {
                        $renderText = $altText;
                        $altList[$id] = $contents->getIndex($this->_altID, 'summary');
                    } elseif ($contents->getIndex($this->_altID, 'atc')) {
                        $altList[$id] = $contents->getIndex($this->_altID, 'summary');
                    }
                }

                /* Remove the summary, text, and attachment if present.
                   These will be reset (correctly) later. */
                $contents->removeIndex($this->_altID);

                /* If we have any text output, this is a valid, viewable
                   MIME_Part so we should mark it as the best viewable option
                   so far. */
                if (!empty($renderText)) {
                    $display = $part;
                    $text = $renderText;
                    $this->_contentType = $display->getType();
                }
            }
        }

        /* We need to set the summary here if we have a display part. */
        if (!empty($display)) {
            $contents->setSummary($display, 'part');
        }

        /* Show links to alternative parts. */
        if (count($partList) > 1) {
            /* Generate the list of summaries to use. */
            $summaryList = array();
            foreach ($partList as $part) {
                $id = $part->getMIMEId();
                if ($id && (empty($display) ||
                            ($id != $display->getMIMEId()))) {
                    /* If we have grabbed the partSummary information
                       from a MIME_Viewer that directly set it, use
                       that info now. */
                    $summary = (isset($altList[$id])) ? $altList[$id] : $contents->partSummary($part);

                    /* We don't want to show the MIME ID for alt parts. */
                    if (!empty($summary)) {
                        array_splice($summary, 1, 1);
                        $summaryList[] = $summary;
                    }
                }
            }

            /* Make sure there is at least one summary before showing the
               alternative parts. */
            if (!empty($summaryList) && !$contents->viewAsAttachment()) {
                $status = _("Alternative parts for this section:");
                if ($contents->showSummaryLinks()) {
                    $status .= '&nbsp;&nbsp;' . Help::link('imp', 'alternative-msg');
                }
                $status = $contents->formatStatusMsg($status, null, false);
                if (!empty($status)) {
                    $text .= "<p />\n";
                    $text .= '<table style="padding: 2px; border: 1px solid #000000; background-color: lightgrey;"><tr><td>';
                    $text .= $status . '</td></tr>';
                    $text .= '<tr><td><table border="0" cellspacing="1" cellpadding="1">';
                    foreach ($summaryList as $summary) {
                        $text .= '<tr valign="middle">';
                        foreach ($summary as $val) {
                            if (!empty($val)) {
                                $text .= "<td>$val&nbsp;</td>\n";
                            }
                        }
                        $text .= "</tr>\n";
                    }
                    $text .= '</td></tr></table></td></tr></table>';
                }
            }
        }

        /* No longer force the alternative MIME ID for IMP_Contents methods. */
        if (!empty($this->_altID)) {
            $contents->setMIMEKeyOverride();
        }

        return $text;
     }

    /**
     * Determine the alternative ID
     *
     * @access private
     *
     * @param object MIME_Contents &$contents  A MIME_Contents object.
     * @param array &$partList                 The list of parts in this
     *                                         alternative section.
     */
    function _getAltID(&$contents, &$partList)
    {
        $altID = null;
        $override = $contents->getMIMEKeyOverride();

        if (is_null($override)) {
            $altID = $this->mime_part->getInformation('alternative');
            if ($altID === false) {
                foreach ($partList as $part) {
                    $altID = $part->getInformation('alternative');
                    if ($altID !== false) {
                        break;
                    }
                }
            }
        }

        if ($altID !== false) {
            $contents->setMIMEKeyOverride($altID);
            $this->_altID = $altID;
        }
    }

    /**
     * Return the content-type.
     *
     * @access public
     *
     * @return string  The content-type of the message.
     *                 Returns 'application/octet-stream' until actual
     *                 content type of the message can be determined.
     */
    function getType()
    {
        return $this->_contentType;
    }

}
