<?php

/*
 * Style sheet for expanding-collapsing tree menus.
 * 
 * You can create different styles for different menus as needed. The base style
 * class should be assigned to the menu's UL element, and the other styles
 * should follow the <base_class><suffix> format. <suffix> is defined by the
 * suffix_x, suffix_c and suffix_leaf variables in tree_menu.js. This example
 * uses "tree" as the base class, and "_x", "_c" and "_leaf" as suffixes.
 */

/*
 * I use PHP to generate this style sheet because different browsers can't deal
 * with different methods of positioning the menu "bullets". Specifically,
 * Safari can't do the absolute-positioning method, and IE for the Mac can't
 * deal with the float-with-negative-margin method, and the parent-child ">"
 * selector doesn't hide that style from it, like it does with WinIE.
 * Mozilla, of course, would work either way, but I think float-with-negative-
 * margin is considered the "right" way to do the positioning.
 */

 /*	Figure out when I was modified last, and when the client's cached copy of
	me was modified. When the client is requesting an updated page, it'll send
	the server an "http-if-modified-since" conditional get, with the modified
	date of its cached copy. */

	$my_mod_time = filemtime( $_SERVER['SCRIPT_FILENAME'] );
	$cached_mod_time = strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );

 /*	Generate the headers for the page, so the browser sees me as a normal .css
	file, appropriate for caching as desired. */
	
	header( "Content-Type: text/css" );
	header( "Last-Modified: " . gmdate( "D, d M Y H:i:s", $my_mod_time )
	        . " GMT");
	header( "Connection: close" );
	
 /*	Determine whether the document has changed since the client's cached
	version. If not, send a 304 Not Modified instead of the page.
	
	The reason we test for == instead of <= is because if the
	'http-if-modified-since' header doesn't exist, $cached_mod_time seems to
	always evaluate to midnight this morning. */
	   
	if ( $my_mod_time == $cached_mod_time )
		header( "{$_SERVER['SERVER_PROTOCOL']} 304 Not Modified" );
	else {

	 /*	Figure out which browser is being used. Note that unlike the main site
		style sheet, we don't care about text size, just positioning. So we
		only need to know about IE. I lump Safari with Mozilla, because it
		works with either, and float-with-negative-margin is
		considered the "right" way to do the positioning. */
	
		$user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
		
	 /*	Function definition: Determine whether a string is found in the user
		agent string. */
		function inAgent( $agent ) {
			global $user_agent;
		
			// Use === instead of == because strpos can return 0 on a match.
			$notAgent = strpos( $user_agent, $agent ) === false;	
			return !$notAgent;
		}

	 /*	Determine the browser making the request. */
	 
		// Internet Explorer uses absolute-positioning, and can't deal with
		// float-with-negative-margin.
		if ( inAgent('msie') )
			$browser="non-floatable";
		
		// Safari has a problem with absolute-positioning of elements, but
		// works fine with float-with-negative-margin, so I use it for
		// everything else. The script won't even run on older browsers, so
		// there's no need to treat them differently.
		else
			$browser="floatable";
		
	 /*	Buffer up the output, so we can calculate the "Content-Length"
		header. It'll be output at the bottom of the script. */
		ob_start();
?>

/*
 * Style sheet for expanding-collapsing tree menus.
 * This browser is <?php echo "$browser"; ?>.
 */
 
/* Style for tree menu. Don't show bullets (the script's tree_menu_setup
 * function will add div's to replace them). Adjust the padding-left attribute
 * to specify the indentation of each level of the menu. */
ul.tree {
	list-style: none;
	margin-left: 0px;	/* So IE won't add extra indentation to menu. */
	padding-left: 20px;
	}

/* Style for menu items. You may be able to separate this to render leaves
 * and submenus differently. */
li.tree, li.tree_leaf {
	font-size: 13px;
	line-height: 14px;
	margin-top: 6px;
	}

<?php	switch ($browser) {
		case "non-floatable": ?>
		
		 /*	For IE, the "bullets" are placed absolutely, offset from their
			items. Adjust the margin-left and margin-top properties to place
			them as desired. */
			div.tree_x, div.tree_c, div.tree_leaf {
				position: absolute;
				margin-left: -20px;
				margin-top: 0px;
				}

<?php		break;
		default: ?>

		 /*	For modern browsers, the "bullets" float with their items, with a
		 	negative margin to outdent them. Adjust the margin-left and
		 	margin-top properties to place them as desired. */
			div.tree_x, div.tree_c, div.tree_leaf {
				position: static;
				float: left;
				margin-left: -20px;
				margin-top: 0px;
				}

<?php	} ?>

/* Style for text-based "[+]" and "[-]" menu controls. */
div.tree_x a:link, div.tree_x a:visited,
div.tree_c a:link, div.tree_c a:visited {
	color: #990033;
	text-decoration: none;
	font-family: "Courier New", Courier, monospace;
	font-size: 75%;
	font-weight: bold;
	}

<?php

	 /*	Get the contents of the buffer and close it. Then calculate the
		"content-length" header and output the page! */
		
		$page = ob_get_contents();
		ob_end_clean();

		header( "Content-Length: " . strlen($page) );
		echo $page;
	}
?>
