<?php
/*
Copyright (C) 2004 Paul Marks
http://www.pmarks.net/

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/

    
function weekWrap($t)
    {
        return (
$t 10080) % 10080;
    }

    function 
timeInRange($time$min$max)
    {
        
// returns true if MIN <= TIME < MAX, wrapped through 0-10079

        
$time weekWrap($time);
        
$min weekWrap($min);
        
$max weekWrap($max);

        if (
$min $max)
        {
            return (
$time >= $min && $time $max);
        }
        elseif (
$min $max)
        {
            return (
$time >= $min || $time $max);
        }
        return 
false;
    }

    function 
timeConvert($time)
    {
        list(
$h,$m) = explode(':'$time);
        
$ampm strtolower(substr($time,-2));
        if (
$ampm == 'am' && $h == 12)
        {
            
$h 0;
        }
        elseif (
$ampm == 'pm' && $h != 12)
        {
            
$h += 12;
        }

        return (
$h 60 + (int)$m);        // return number of minutes after midnight
    
}

    function 
startElement($parser$name$attr)
    {
        global 
$curHallData$curBlockData;
        
$GLOBALS['curElement'] = $name;

        switch (
$name)
        {
            case 
'HALL':
                
$curHallData = array('hallid'=>$attr['ID'], 'hallname'=>'''x1'=>0'y1'=>0'x2'=>0'y2'=>0);
                break;
            case 
'TIMEBLK':
                
$GLOBALS['inblock'] = true;
                
$curBlockData = array('name'=>'''type'=>strtolower($attr['TYPE']), 'days'=>array(), 'open'=>0'close'=>0);
                break;
        }
    }

    function 
characterData($parser$data)
    {
        global 
$curHallData$curBlockData;
        switch (
$GLOBALS['curElement'])
        {
            case 
'NAME':
                if (
$GLOBALS['inblock'])
                    
$curBlockData['name'] = $data;
                else
                    
$curHallData['name'] = $data;
                break;
            case 
'X1':
                
$curHallData['x1'] = $data;
                break;
            case 
'Y1':
                
$curHallData['y1'] = $data;
                break;
            case 
'X2':
                
$curHallData['x2'] = $data;
                break;
            case 
'Y2':
                
$curHallData['y2'] = $data;
                break;
            case 
'OPEN':
                
$curBlockData['open'] = timeConvert($data);
                break;
            case 
'CLOSE':
                
$curBlockData['close'] = timeConvert($data);
                break;
            case 
'DAY':
                
$curBlockData['days'][] = array_search(strtolower(substr($data,0,3)),array('sun','mon','tue','wed','thu','fri','sat'));
                break;
        }
    }

    function 
endElement($parser$name)
    {
        
$GLOBALS['curElement'] = "";

        if (
$name == 'TIMEBLK')
        {
            global 
$curBlockData$curHallData$allBlocks$wkTime$mode$selBlock;
            
$GLOBALS['inblock'] = false;

            if (
$mode == $curBlockData['type'])
            {
                
$state 0;

                foreach (
$curBlockData['days'] as $day)
                {
                    
$wkOpen $day*1440 $curBlockData['open'];
                    
$wkClose $day*1440 $curBlockData['close'];

                    if (
$wkClose <= $wkOpen$wkClose += 1440;

                    
$wkCloseSoon $wkClose 15;
                    if (
$wkCloseSoon $wkOpen$wkCloseSoon $wkOpen;

                    if (
timeInRange($wkTime$wkOpen-30$wkOpen)) $state 1;            // opening soon
                    
elseif (timeInRange($wkTime$wkOpen$wkCloseSoon)) $state 2;    // open
                    
elseif (timeInRange($wkTime$wkCloseSoon$wkClose)) $state 3;    // closing soon

                    
if ($state)
                    {
                        if (@
$_GET['id'] == $curHallData['hallid'])
                        {
                            
$selBlock = array('hallid'=>$curHallData['hallid'], 'name'=>$curHallData['name'], 'blockname'=>$curBlockData['name'], 'open'=>$wkOpen'close'=>$wkClose'state'=>$state);
                        }
                        
$allBlocks[] = array_merge($curHallData, array('state'=>$state));
                        break;
                    }
                }
            }
        }
    }

    function 
parseFile($filename)
    {
        
$xml_parser xml_parser_create();
        
xml_set_element_handler($xml_parser'startElement','endElement');
        
xml_set_character_data_handler($xml_parser'characterData');

        
$fp fopen($filename,'r');
        if (!
$fp) exit ("Can't open dining hall information file.");

        while (
$data fread($fp,4096))
        {
            if (!
xml_parse($xml_parser$datafeof($fp)))
            {
                exit(
sprintf("XML error at line %d column %d "xml_get_current_line_number($xml_parser), xml_get_current_column_number($xml_parser)));
            }
        }

        
xml_parser_free($xml_parser);
    }

    function 
jsArray($varname,$items)
    {
        if (
count($items) == 1)
        {
            echo 
"var $varname = new Array(1); " $varname "[0] = " $items[0] . ";\n";
        }
        else
        {
            echo 
"var $varname = new Array(" implode(',',$items) . ");\n";
        }
    }

    function 
remainTime($time)
    {
        
$time weekWrap($time);
        
$out '';
        
$h floor($time 60);
        
$m $time 60;

        if (
$h == 1)
            
$out .= '1 Hour';
        elseif (
$h 1)
            
$out .= $h ' Hours';

        if (
$h && $m 0)
            
$out .= ', ';

        if (
$m == 1)
            
$out .= '1 Minute';
        elseif (
$m || $h 0)
            
$out .= $m ' Minutes';

        return 
$out;
    }

    function 
getMenu($id)
    {
        
$date date('n/j/Y'$GLOBALS['utc_time']);
        
$cfile 'menu_cache/' $id;

        
$menu_html '';

        
$menuf fopen($cfile'r');
        if (
$menuf && $date == trim(fgets($menuf)))
        {
            
$menu_html fgets($menuf16384);
            
fclose($menuf);
        }
        else
        {
            
fclose($menuf);
            
// 2019-03-02 -- Put this fetch out of its misery.
            //$menuwww = @fopen('http://www.housing.purdue.edu/menus/menu.aspx?hallID=' . $id . '&date=' . $date, 'r');

            
$menu_html "";
            if (
$menuwww)
            {
                while (
$line fgets($menuwww65536))
                {
                    if (
strstr($lineMENU_DIVIDER))
                    {
                        
$menu_html .= trim($line);
                    }
                }
                
fclose($menuwww);

                if (
$menu_html)
                {
                    
$menuf fopen($cfile'w');
                    
fwrite($menuf"$date\n$menu_html");
                    
fclose($menuf);
                }
            }
            else
            {
                echo 
'<div style="color:red; font-weight:bold;">Error Opening HFS Menu Page!</div>';
            }
        }

        return 
$menu_html;
    }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // Purdue's time zone.
    
date_default_timezone_set("America/New_York");

    
define ('MENU_DIVIDER''<div id="mealStation" class="meal">');

    
$mode = @$_GET['mode'];
    if (
$mode != 'dining' && $mode != 'other'$mode 'dining';

    
$curElement "";
    
$inblock false;

    
$map_file 'map.png';

    
$menu_url "";
    
$menu_types = array('lunch'=>0'dinner'=>0);
    
$menuf null;

    
$curHallData = array();
    
$curBlockData = array();
    
$allBlocks = array();
    
$selBlock null;

    
srand((double)microtime() * 1000000);

    if (@
$_GET['time'])
    {
        
$utc_time $_GET['time'];
    }
    else
    {
        
$utc_time time();
    }

    
$t getdate($utc_time);
    
$wkTime $t['wday']*1440 $t['hours']*60 $t['minutes'];

    
parseFile('halldata.xml');

    
$blockCount count($allBlocks);
    
$fadeOffsets = array();
    
$colorList = array();

    for (
$i=0$i<$blockCount$i++)
    {
        
$fadeOffsets[$i] = $i;
        
$colorList[$i] = $allBlocks[$i]['state'];
    }

    
shuffle($fadeOffsets);
?>
<html>
<head>
<title>Purdue Findfood</title>
<meta name="Description" content="See a live map of which Purdue University dining halls are currently open, and what's on their menus.">
<meta http-equiv="refresh" content="<?=61-date('s')?>">
<style type="text/css">
<!--

#container ul {
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-size: 12px; margin: 0 75px 0 75px;
    padding: 0 0 0 0;
    text-align: center;
    margin: 0 0 0 0; /*removes indent IE and Opera*/
    padding: 0 0 0 0; /*removes indent Mozilla and NN7*/
    list-style-type: none; /*turns off display of bullet*/
}

#mealStation {
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-size: 12px; font-weight: bold;
    text-transform: uppercase;
    color: #000;
    background-color: #F5E0AF;
    text-align: center;
    padding: 3px;
    margin: 20px 0px 5px 0px;
}

.menuBox {
    background-color: #FEFAF2;
    margin: 30px 0px 0px 5px;
}

.menuHeader {
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-weight: bold;
    margin: 0px 5px 0px 5px;
}

.footLink {
    color: #FFFFFF;
    text-decoration: none;
}
.menuLink {
    color: #000000;
    text-decoration: underline;
}
-->
</style>

<script language="JavaScript">
var angle = 0;
var twoPi = Math.PI * 2;
var hexChars = "0123456789ABCDEF";
<?php jsArray('color',$colorList); ?>
<?php jsArray
('offset',$fadeOffsets); ?>
var total = <?=$blockCount?>;

function makeColor(col, brt)
{
    var hex = hexChars.charAt(Math.floor(brt/16)) + hexChars.charAt(brt % 16);
    switch(col)
    {
        case 1: return('#0000'+hex);
        case 2: return('#00'+hex+'00');
        case 3: return('#'+hex+'0000');
    }
}

function changeColor()
{
    angle += 0.3;
    if (angle > twoPi) angle -= twoPi;
    for (var i=0; i<total; i++)
        document.getElementById('hall'+i).style.borderColor = makeColor(color[i], Math.round(48 * Math.sin(angle + offset[i]*twoPi/total) + 207));
}
</script>

</head>
<body>
<table><tr>
<td valign="top">
    <table border="0" cellpadding="0" cellspacing="0">
        <tr><td><img src="header.png" alt="Purdue Findfood - Created by Paul Marks"></td></tr>
        <tr><td><table width="100%" border="0" cellpadding="5" cellspacing="0">
            <tr><td bgcolor="#F5E0AF"><font face="Arial, Helvetica, sans-serif">
            <?php

            
if ($selBlock)
            {
                if (
$mode == 'dining')
                {
                    
$menu_mealname $selBlock['blockname'];
                    
$menu_hallname $selBlock['name'];

                    foreach (
array_keys($menu_types) as $key)
                    {
                        if (
strpos(strtolower($menu_mealname), $key) !== FALSE)
                            
$menu_types[$key] = 1;
                    }

                    
$menu_id $selBlock['hallid'];
                    
$menu_url 'http://www.housing.purdue.edu/menus/menu.aspx?hallID=' $menu_id '&date=' date('n/j/Y'$utc_time);
                }
            
?>
            <strong>Hall:</strong> <?=$selBlock['name']?> - <?=$selBlock['blockname']?><br>
            <strong>Time:</strong> <?=gmdate('g:ia',$selBlock['open']*60)?> - <?=gmdate('g:ia',$selBlock['close']*60)?><br>
            <?php
                
if ($selBlock['state'] == 1)
                {
                    echo 
'Opens in ' remainTime($selBlock['open'] - $wkTime);
                }
                else
                {
                    echo 
'Closes in ' remainTime($selBlock['close'] - $wkTime);
                }
                echo 
"<br>\n";
            }
            elseif (
$blockCount)
            {
                echo 
"<center>Click a hall below for details.</center>\n";
            }
            else
            {
                echo 
"<center>No halls of the selected type are open now.</center>\n";
                
$map_file $mode '_closed.png';
            }
            
?>
            </font></td></tr>
        </table></td></tr>
        <tr><td>
            <div style="position:relative"><img src="<?=$map_file?>" width="500" height="523"><?php
                $brdColor 
= array(1=>'0000FF',2=>'00FF00',3=>'FF0000');
                
$selBlock 0;
                for (
$i=0$i<$blockCount$i++)
                {
                    
$b $allBlocks[$i];
                    
?><a href="?mode=<?=$mode?>&id=<?=$b['hallid']?>" title="<?=$b['name']?>"><img src="spacer.gif" alt="<?=$b['name']?>" id="hall<?=$i?>" width="<?=$b['x2']-$b['x1']-3?>" height="<?=$b['y2']-$b['y1']-3?>" border="3" style="position:absolute; left:<?=$b['x1']-1?>; top:<?=$b['y1']-1?>; border-color:#<?=$brdColor[$b['state']]?>;"></a><?php
                
}
                
?></div>
            <script language="JavaScript">
            setInterval('changeColor()', 75);
            </script>
        </td></tr>
        <tr><td>
            <table width="100%" border="0" cellpadding="5" cellspacing="0" bgcolor="#000000">
                <tr>
                    <td align="left" valign="top"><font color="#FFFFFF" size="-1" face="Courier New, Courier, mono"><?=gmdate('l g:ia',$wkTime*60+259200)?></font></td>
                    <td align="right" valign="top"><font color="#FFFFFF" size="-1" face="Arial, Helvetica, sans-serif"><?php
                    
if ($mode == 'dining')
                        echo 
'<font color="#FFFF00"><strong>Dining</strong></font>';
                    else
                        echo 
'<a href="?mode=dining" class="footLink">Dining</a>';

                    echo 
' | ';

                    if (
$mode == 'other')
                        echo 
'<font color="#FFFF00"><strong>Take-out</strong></font>';
                    else
                        echo 
'<a href="?mode=other" class="footLink">Take-out</a>';
                    
?></font></td>
                </tr>
            </table>
        </td></tr>
    </table>
    <br>
    <a href="source.php">PHP Source Code</a>
</td>

<td valign="top" align="center">
<?php
if ($menu_url) {
?>

<div class="menuBox">

<span class="menuHeader"><?=$menu_mealname?> Menu For <a class="menuLink" href="<?=$menu_url?>"><?=$menu_hallname?></a>:</span>

<?php

$menu_html 
'';
$items explode(MENU_DIVIDERgetMenu($menu_id));        // split up line based on the div tags

foreach ($items as $item)
{
    foreach (
$menu_types as $key=>$value)
    {
        if (
$value && strtolower(substr($item,0,strlen($key))) == $key)
        {
            
$menu_html .= MENU_DIVIDER $item;
            break;
        }
    }
}

if (
$menu_html)
    echo 
$menu_html;
else
    echo 
'<br><br>&lt;Menu Not Available>';

if (
$menuffclose($menuf);

echo 
'</div>';

}
else
{
    echo 
'<br><br><a href="http://www.mozilla.org/products/firefox/"><img src="firefox.png" img alt="Get Firefox!" title="Get Firefox!" border="0"></a>';
}

echo 
'</td>';
?>
</table>

</body>
</html>