<?php

# poem.php
#
# Paul Hubbard 6/15/02, PHP code to return a poem from my fortune file of same.
#

# Crank up error reporting
error_reporting(2047);
# Back to pfh code
$version = "1.0.0";               # release.function.bugs

$debug = 0;
$system_url = "http://www.phfactor.net/code/poems/poem.php";
$project_page = "http://www.phfactor.net/code/poems/";

$fortune_dir = "/home/pfh/html/code/poems/";

$fortune = new Fortune;
$poem = $fortune->quoteFromDir($fortune_dir);

?>
<html>
<body bgcolor="#FFFFFF">
<h1>Random Poem</h1>
<pre>
<? echo $poem ; ?>
</pre>
<p>
<h3>Navigation Links</h3>
<ul>
<li><a href="<?echo $system_url ; ?>">This page;
 reload to get a new poem</a></li>
<li><a href="http://www.itu.dk/~haas/quote">Home page for fortune PHP code</a></li>
<li><a href="<? echo $project_page ; ?>">Project page - about this page</a></li>
<li><a href="/">Home page</a></li>
</ul>
</html>
<?
/* 
Main methods to use:
 quoteFromDir($dir):
   Quotes from any of the fortune-files in the dir.
 getRandomQuote($file):
   Quotes from the specific file.
   
 Written by Henrik Aasted Sorensen, haas@itu.dk
 Read more at http://www.itu.dk/~haas/quote
*/

class Fortune {
    function quoteFromDir($dir) {
	$amount = 0;
	$index = 0;

	if ( $handle = opendir($dir) ) {
	    while (false !== ($file = readdir($handle))) {
			
		if ( strpos($file, ".dat") != false) {
		    $len = strlen($file);
		    if (substr($file, $len - 4) == ".dat"){										
			$number = $this->getNumberOfQuotes($dir . "/" . $file);
			$amount += $number;
			$quotes[$index] = $amount;
			$files[$index] = $file;
			$index++;					
		    }
		}			
			
	    }
	
	    srand((double)microtime()*1000000);
	    $index = rand(0, $amount);
	    $i = 0;
	
	    while ($quotes[$i] < $index)  {
		$i++;	
	    }

	    return $this->getRandomQuote($dir .$files[$i]);
	}


	return -1;
    }

    /*
	 Reads the number of quotes in the file. 
    */
    function getNumberOfQuotes($file) {
	$fd = fopen($file, "rb");
	$this->readLong($fd); // Just move over the first long. Might as well be fseek.
	$len =  $this->readLong($fd);
	fclose($fd);
	return $len;
    }
    /*
	 Picks quote number $index from the dat-file in $file.
    */
    function getExactQuote($file, $index) {
	if (is_file($file) == FALSE) {
	    echo "Input must be a file!<br/>";
	    return;
	}
	
	if ( ($fd = fopen($file, "rb")) == FALSE ) {
	    echo "Cannot open $file<br/>";	
	    return;
	}
	fseek($fd, 24 + 4 * $index);
	
	$phys_index = $this->readLong($fd);
	
	fclose($fd);
	
	$quotefile = substr($file, 0, strlen($file) - 4);

	if ( ($fd = fopen($quotefile, "rb")) == FALSE ) {
	    echo "Cannot find file $quotefile!<br/>";
	}		
	
	$res = $this->getQuote($fd, $phys_index);
	fclose($fd);
	
	return $res;	
    }

    /*
	 Returns a random quote from $file.
    */
    function getRandomQuote($file) {
	$number = $this->getNumberOfQuotes($file);

	$index = rand(0, $number);

	return $this->getExactQuote($file, $index);
    }	

    /*
	 Reads a quote from the specified index.
    */
    function getQuote($fd, $index) {
	fseek($fd, $index);
	$line=""; $res = "";
	do {
	    $res = $res . $line;		
	    $line = fgets($fd, 1024) . "<br/>";
	} while ( ($line[0] != "%") && (!feof($fd)) );

	return $res;
    }

    /*
	 Gets indexes from the file pointed to by the filedescriptor $fd.
    */
    function getIndices($fd) {
	fseek($fd, 24, SEEK_SET);
	$i = 0;
	
	while ( feof($fd) == FALSE ) {
	    $res[$i] = readLong($fd);
	    $i++;
	}
	return $res;
    }

    function readLong($fd) {
	$res = fread($fd, 4);
	$l = ord($res[3]);
	$l += ord($res[2]) << 8;
	$l += ord($res[1]) << 16;
	$l += ord($res[0]) << 24;
	return $l;
    }


    function createIndexFile($file) {
	$fd = @fopen($file, "r");
	if ($fd == false) {
	    echo "File error!";
	    exit;
	}

	$i = 1;
	$length = 0;
	$longest = 0;
	$shortest = 100000;
	$indices[0] = 0;
	while (!feof($fd)) {
	    $line = fgets($fd);
	    if ($line == "%\n") {
		$indices[$i] = ftell($fd);
		$i++;
		if ($length > $longest)
		    $longest = $length;
	
		if ($length < $shortest)
		    $shortest = $length;

		$length = 0;
	    } else {
		$length = $length + strlen($line);
	    }
	}

	fclose($fd);

	$fd = @fopen($file . ".dat", "w");

	if ($fd == false) {
	    echo "<!-- createIndexFile: Could not write to file....-->";
	    exit;
	}

	// Write header.
	$this->writeLong($fd, 2);
	$this->writeLong($fd, count($indices));
	$this->writeLong($fd, $longest);
	$this->writeLong($fd, $shortest);
	$this->writeLong($fd, 0);
	$this->writeLong($fd, 37 << 24);

	for ($i = 0 ; $i < count($indices) ; $i++) {
	    $this->writeLong($fd, $indices[$i]);
	}

	fclose($fd);
    }

    function writeLong($fd, $l) {
	fwrite($fd, chr ( ($l >> 24) & 255));
	fwrite($fd, chr ( ($l >> 16) & 255));
	fwrite($fd, chr ( ($l >> 8) & 255));
	fwrite($fd, chr ( $l & 255));
    }
} // End of class

echo "<!-- PHP Fortune - Made by haas@it-c.dk. HP: http://www.it-c.dk/~haas -->\n";

  
?>

