<?php

/**
 * This class represent a week view of mulitple free busy information.
 *
 * $Horde: moment/lib/View/week.php,v 1.8 2003/04/29 17:03:12 chuck Exp $
 *
 * Copyright 2003 Mike Cochrane <mike@graftonhall.co.nz>
 *
 * See the enclosed file LICENCE for license information.
 *
 * @author Mike Cochrane <mike@graftonhall.co.nz>
 * @package freebusy
 */
class Moment_View_week extends Moment_View {

    var $_startStamp;
    var $_endStamp;

    function render($day = null)
    {
        global $prefs;

        require_once 'Date/Calc.php';

        if (is_null($day)) {
            list($startDate['year'], $startDate['month'], $startDate['mday']) = explode('-', Date_Calc::beginOfWeek(null, null, null, "%Y-%m-%d"));
            $day = mktime(0, 0, 0, $startDate['month'], $startDate['mday'], $startDate['year']);
        } else {
            list($startDate['year'], $startDate['month'], $startDate['mday']) = explode('-', Date_Calc::beginOfWeek(date('j', $day), date('n', $day), date('Y', $day), "%Y-%m-%d"));
            $day = mktime(0, 0, 0, $startDate['month'], $startDate['mday'], $startDate['year']);
        }
        $this->_startStamp = mktime(0, 0, 0, date('n', $day), date('j', $day), date('Y', $day));
        $this->_endStamp   = mktime(23, 59, 59, date('n', $day) + 6, date('j', $day), date('Y', $day));

        $vCal = new Horde_iCalendar();
        $required = &Horde_iCalendar::newComponent('vfreebusy', $vCal);
        foreach ($this->_requiredMembers as $member) {
            $required->merge($member, false);
        }
        $required->simplify();

        $optional = &Horde_iCalendar::newComponent('vfreebusy', $vCal);
        foreach ($this->_optionalMembers as $member) {
            $optional->merge($member, false);
        }
        $optional->simplify();

        $optimal = &Horde_iCalendar::newComponent('vfreebusy', $vCal);
        $optimal->merge($required, false);
        $optimal->merge($optional);

        $base_url = Horde::selfUrl();
        $base_url = Horde::removeParameter($base_url, 'date');
        $base_url = Horde::removeParameter($base_url, 'view');
        $base_url = Horde::addParameter($base_url, 'view', 'week');
        $template = &new Horde_Template();
        $template->set('title', strftime($prefs->getValue('date_format'), $this->_startStamp) . ' - ' .
                                strftime($prefs->getValue('date_format'), $this->_startStamp + (6 * 86400)));

        $template->set('prev_url',
                       Horde::link('', _("Previous Week"), 'menuitem', null, 'return switchDate(' . ($day - 7 *86400) . ');') .
                       Horde::img('nav/left.gif', '&lt;', null, $GLOBALS['registry']->getParam('graphics', 'horde')) . '</a>');

        $template->set('next_url',
                       Horde::link('', _("Next Week"), 'menuitem', null, 'return switchDate(' . ($day + 7 * 86400) . ');') .
                       Horde::img('nav/right.gif', '&lt;', null, $GLOBALS['registry']->getParam('graphics', 'horde')) . '</a>');

        $html = $template->fetch(MOMENT_TEMPLATES . '/view/header.tpl');

        $hours_html = '<table width="100%" cellpadding="0" cellspacing="0" style="text-align:center"><tr>';
        $dayWidth = 100 / 7;
        for ($i = 0; $i < 7; $i++) {
            $t = mktime(0, 0, 0, date('n', $day), date('j', $day) + $i, date('Y', $day));
            $day_label = strftime("%A, %d %B", $t);
            if ($i > 0) {
                $hours_html .= "<td colspan=\"3\" style=\"white-space:nowrap;overflow:hidden;border-left:1px solid black;width:$dayWidth%\">$day_label</td>";
            } else {
                $hours_html .= "<td colspan=\"3\" style=\"white-space:nowrap;overflow:hidden;width:$dayWidth%\">$day_label</td>";
            }
        }

        $hours_html .= "</tr><tr>";

        for ($i = 0; $i < 7; $i++) {
            for ($h = 9; $h < 18; $h += 3) {
                $t = mktime($h, 0, 0, date('n', $day), date('j', $day), date('Y', $day));

                $hour = intval(strftime("%I", $t)) . strftime(" %p", $t);
                if (($i + $h) > 9) {
                    $hours_html .= "<td style=\"white-space:nowrap;overflow:hidden;border-left:1px solid black;width:4%\">$hour</td>";
                } else {
                    $hours_html .= "<td style=\"white-space:nowrap;overflow:hidden;width:4%\">$hour</td>";
                }
            }
        }

        $hours_html .= '</tr></table>';

        // required to attend
        if (count($this->_requiredMembers) > 0) {
            $template = &new Horde_Template();
            $rows = '';
            foreach ($this->_requiredMembers as $member) {
                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.tpl', _("Busy"));
                $template = &new Horde_Template();
                $template->set('blocks', $blocks);
                $template->set('name', $member->getName());
                $rows .= $template->fetch(MOMENT_TEMPLATES . '/view/row.tpl');
            }

            $template = &new Horde_Template();
            $template->set('title', _("Required to attend"));
            $template->set('rows', $rows);
            $template->set('hours', $hours_html);
            $html .= $template->fetch(MOMENT_TEMPLATES . '/view/section.tpl');
        }

        // optional to attend
        if (count($this->_optionalMembers) > 0) {
            $template = &new Horde_Template();
            $rows = '';
            foreach ($this->_optionalMembers as $member) {
                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.tpl', _("Busy"));
                $template = &new Horde_Template();
                $template->set('blocks', $blocks);
                $template->set('name', $member->getName());
                $rows .= $template->fetch(MOMENT_TEMPLATES . '/view/row.tpl');
            }

            $template = &new Horde_Template();
            $template->set('title', _("Optional to attend"));
            $template->set('rows', $rows);
            $template->set('hours', $hours_html);
            $html .= $template->fetch(MOMENT_TEMPLATES . '/view/section.tpl');
        }

        // possible meeting times.
        $optimal->setAttribute('ORGANIZER', _("All Attendees"));
        $blocks = $this->_getBlocks($optimal,
                                    $optimal->getFreePeriods($this->_startStamp, $this->_endStamp),
                                    'meetingblock.tpl', _("All Attendees"));

        $template = &new Horde_Template();
        $template->set('name', _("All Attendees"));
        $template->set('blocks', $blocks);
        $rows = $template->fetch(MOMENT_TEMPLATES . '/view/row.tpl');

        // possible meeting times.
        $required->setAttribute('ORGANIZER', _("Required Attendees"));
        $blocks = $this->_getBlocks($required,
                                    $required->getFreePeriods($this->_startStamp, $this->_endStamp),
                                    'meetingblock.tpl', _("Required Attendees"));

        $template = &new Horde_Template();
        $template->set('name', _("Required Attendees"));
        $template->set('blocks', $blocks);
        $rows .= $template->fetch(MOMENT_TEMPLATES . '/view/row.tpl');

        $template = &new Horde_Template();
        $template->set('title', _("Possible Meeting Times"));
        $template->set('rows', $rows);
        $template->set('hours', $hours_html);
        $html .= $template->fetch(MOMENT_TEMPLATES . '/view/section.tpl');

        if ($prefs->getValue('show_legend')) {
            $html .= Horde::bufferOutput('require' , MOMENT_TEMPLATES . '/view/legend.inc');
        }

        return $html;

    }

    function _getBlocks($member, $periods, $blockfile, $label)
    {
        $template = &new Horde_Template();
        $template->set('label', '');

        $count = 0;
        $blocks = '';
        $dayWidth = 100 / 7;
        foreach ($periods as $start => $end) {
            if ($start < $this->_endStamp && $end > $this->_startStamp) {

                $start_day = floor(($start - $this->_startStamp) / (24 * 3600));
                $start_hour = intval(strftime('%H', $start));
                $start_min = intval(strftime('%M', $start));

                $left = $dayWidth * $start_day;
                if ($start_hour >= 9 && $start_hour < 18) {
                    $left += ($start_hour - 9) * ($dayWidth / 9);
                    $left += ($start_min / 60) * ($dayWidth / 9);
                } elseif ($start_hour >= 18) {
                    $left += $dayWidth;
                }
                $left = min(100, max(0, $left));

                $end_day = floor(($end - $this->_startStamp) / (24 * 3600));
                $end_hour = intval(strftime('%H', $end));
                $end_min = intval(strftime('%M', $end));

                $right = $dayWidth * $end_day;
                if ($end_hour >= 9 && $end_hour < 18) {
                    $right += ($end_hour - 9) * ($dayWidth / 9);
                    $right += ($end_min / 60) * ($dayWidth / 9);
                } elseif ($end_hour >= 18) {
                    $right += $dayWidth;
                }
                $right = min(100, $right);

                if (($right - $left) != 0) {
                    $template->set('left', $left);
                    $template->set('width', $right - $left);
                    $template->set('top', $count++ * 15);
                    $template->set('label', $label);

                    $blocks .= $template->fetch(MOMENT_TEMPLATES . '/view/' . $blockfile);
                }
            }
        }

        // Indicate if we don't know the free busy info for any periods
        $start = $member->getStart();
        $end   = $member->getEnd();
        if ($start > $this->_startStamp) {
            if ($start >= $this->_endStamp) {
                $right = 100;
            } else {
                $start_day = floor(($start - $this->_startStamp) / (24 * 3600));
                $start_hour = intval(strftime('%H', $start));
                $start_min = intval(strftime('%M', $start));

                $right = $dayWidth * $start_day;
                if ($start_hour >= 9 && $start_hour < 18) {
                    $right += ($start_hour - 9) * ($dayWidth / 9);
                    $right += ($start_min / 60) * ($dayWidth / 9);
                } elseif ($start_hour >= 18) {
                    $right += $dayWidth;
                }
            }
            $left  = 0;

            $template->set('left', $left);
            $template->set('width', min($right - $left, 100));
            $template->set('top', $count++ * 15);

            $blocks .= $template->fetch(MOMENT_TEMPLATES . '/view/unknownblock.tpl');
        } else if ($end <= $this->_endStamp) {
            if ($end <= $this->_startStamp) {
                $left = 0;
            } else {
                $end_day = floor(($end - $this->_startStamp) / (24 * 3600));
                $end_hour = intval(strftime('%H', $end));
                $end_min = intval(strftime('%M', $end));

                $left = $dayWidth * $end_day;
                if ($end_hour >= 9 && $end_hour < 18) {
                    $left += ($end_hour - 9) * ($dayWidth / 9);
                    $left += ($end_min / 60) * ($dayWidth / 9);
                } elseif ($end_hour >= 18) {
                    $left += $dayWidth;
                }
                $left = min(100, $left);
            }
            $right  = 100;

            $template->set('left', $left);
            $template->set('width', min($right - $left, 100));
            $template->set('top', $count++ * 15);

            $blocks .= $template->fetch(MOMENT_TEMPLATES . '/view/unknownblock.tpl');
        }

        // overlay the grid
        $template->set('top', $count++ * 15);
        $blocks .= $template->fetch(MOMENT_TEMPLATES . '/weekView/linesblock.tpl');

        return $blocks;
    }

}
