<?php
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']))
	die ("Please don't do that.");

//define('QUERY_TRACE',true);
define('HEADER_TEXTCOLOR','000000');
define('HEADER_IMAGE','%s/images/logo.png'); // %s is theme dir uri
define('HEADER_IMAGE_WIDTH', 480);
define('HEADER_IMAGE_HEIGHT', 110);
define('THEMENAME','caribou');

load_theme_textdomain(THEMENAME);

if (file_exists(TEMPLATEPATH .'/includes/previewimagepicker.php'))
	include_once (TEMPLATEPATH .'/includes/previewimagepicker.php');

if (file_exists(TEMPLATEPATH .'/comments/commenting.php'))
	include_once (TEMPLATEPATH .'/comments/commenting.php');

if (version_compare($wp_version,'2.5','ge')) // Older WPs will have a problems with most of this stuff so "Bye bye".
	add_action('init',create_function('','global $SpectacuLATheme;$SpectacuLATheme = new SpectacuLATheme();')); // Create the theme object when WP kicks in.

class SpectacuLATheme {
	// Changing this or the one below will wipe out settings.  Only do on major version change
	var $themeName = 'caribou';
	var $version = 1;

	var $options = array(
						 'navigationBar' => '/[0-9]/',
						 'anchorColour' => '/^#([0-9a-f]{3}|[0-9a-f]{6})$/i',
						 'bulletStyle' => null,
						 'defaultBulletColour' => '/^#([0-9a-f]{3}|[0-9a-f]{6})$/i',
						 'sectionBulletColour' => '/^#([0-9a-f]{3}|[0-9a-f]{6})$/i',
						 'logoFile' => '/^http(s){0,1}:\/\/.*?\.(jpg|jpeg|png|gif)$/i',
						 'scheme' => '/^[a-z0-9_\-]+?$/'
						 );

	var $pageLocations = array('Normal','Header tab bar','Footer','Navigation bar');

	// Some default settings
	var $scheme = null;
	var $navigationBar = 1;
	var $defaultBulletColour = '#cccccc';
	var $anchorColour = '#006090';
	var $bulletStyle = array(0 => array('colour' => '#cccccc')); // array index is the cat ID with an array of properties. [0] is the defaults

	//	Add all actions and filters here so they are called on WP init.
	function SpectacuLATheme() {
		$this->collectOptions();

		// Front end mods.
		add_action('wp',array($this,'before_headers'));

		add_action('wp_head',array($this,'extraRSSFeeds'));
		add_action('wp_head',array($this,'extraCSS'));
		add_action('wp_head',array($this,'outputScheme'));

		add_filter('body_class',array($this,'get_agent_body_class'));
		add_action('navigationBar',array($this,'navigationBar'));

		// Remove title attribute from list pages and list categories as it gets in the way of drop down menus.
		add_filter('wp_list_pages',array($this,'removeTitleAttrib'),1);
		add_filter('wp_list_categories',array($this,'removeTitleAttrib'),1);

		add_action('editor_max_image_size',create_function('','return array(448,null);'));
		if (function_exists('add_custom_image_header') && function_exists('custom_image_head') && function_exists('custom_image_admin_head')){
			add_custom_image_header('custom_image_head','custom_image_admin_head');
		}

		/*
		 Add some extra sizes to the list of standard WP image sizes.
		*/
		if (function_exists('PIPPAddImage')){
			PIPPAddImage('excerptthumb',64,64,true,'');
			PIPPAddImage('spectaculahighlight',170,150,false,'');
		}

		if (!is_taxonomy('spectaculahighlight')) {
			register_taxonomy('spectaculahighlight','post',array('update_count_callback' => '_update_post_term_count', 'hierarchical' => false));
		}
		if (function_exists("register_sidebar")) {
			register_sidebar(array(
				"name" => "300px Sidebar",
				"before_widget" => '<div class="widget widget300 %2$s">',
				"after_widget" => '</div>',
				"before_title" => '<strong class="widgetTitle">',
				"after_title" => '</strong>'
				));
			register_sidebar(array(
				"name" => '120px Sidebar',
				"before_widget" => '<div class="widget widget120 %2$s">',
				"after_widget" => '</div>',
				"before_title" => '<strong class="widgetTitle">',
				"after_title" => '</strong>'
				));
			register_sidebar(array(
				"name" => '160px Sidebar',
				"before_widget" => '<div class="widget widget160 %2$s">',
				"after_widget" => '</div>',
				"before_title" => '<strong class="widgetTitle">',
				"after_title" => '</strong>'
				));
			register_sidebar(array(
				"name" => '468x60 Banner',
				"before_widget" => '<div class="widget widgetBanner %2$s">',
				"after_widget" => '</div>',
				"before_title" => '<strong class="widgetTitle">',
				"after_title" => '</strong>'
			));
		}

		// Admin interface mods
		if (is_admin()) {
			if (function_exists('wp_enqueue_style'))
				wp_enqueue_style('spectacula_admin',get_bloginfo('template_url').'/admin.css');
			else {
				add_action('admin_head',array($this,'adminHead'));
			}

			wp_enqueue_script('farbtastic',get_bloginfo('template_url').'/js/farbtastic/farbtastic.js',array('jquery'),1.2);
			wp_enqueue_script('spectacula_admin',get_bloginfo('template_url').'/js/admin.js',array('jquery','farbtastic'),1.0);

			add_action('admin_menu', array($this,'addThemeAdminPage'));

			// Choose category section
			add_action('edit_category',array($this,'processCategoryOptions'),10,1);
			add_action('create_category',array($this,'processCategoryOptions'),10,1);
			add_action('edit_category_form',array($this,'categoryColourAndSection'),10,1);

			// Add extra options to posts and pages
			add_action('admin_menu',array($this,'addPostPageOptions'));

			add_action('save_post',array($this,'processPostOptions'),10,2);
			add_action('save_post',array($this,'processPageOptions'),10,2);

			add_action('delete_post',array($this,'cleanUp'),100,2);
			add_action('save_post',array($this,'cleanUp'),100,2);
		}

	}

	// Add some jQuery bits to the site.
	function before_headers(){
		global $wp_version;

		if (!is_admin() && version_compare($wp_version, '2.5', 'ge')) { // Only add jQuery to wp 2.5 an above.
			wp_enqueue_script('behaviour',get_bloginfo('template_url').'/js/behaviour.min.js',array('jquery'),1.0);
			wp_localize_script('behaviour','behaviourL10n',array(
				'searchError'	=> __('Oops! Try again.',THEMENAME),
				'searchPrompt'	=> __('Search',THEMENAME),
			));
		}
	}

	function adminHead(){
		// For WP < 2.6 as I can't use wp_enqueue_style
		?><link rel="stylesheet" href="<?php bloginfo("template_directory");?>/admin.css" type="text/css" media="screen"/><?php
	}

	function collectOptions () {										// Collect the options from the options table.
//		delete_option(self::themeName."OptionsVersion".self::version);
		$this->bulletStyle[0]["url"] = get_bloginfo("template_url")."/images/default.gif";
		$this->logoFile = get_bloginfo("template_url")."/images/logo.png";

		$options = get_option($this->themeName."OptionsVersion".$this->version);

		foreach (array_keys($this->options) as $option) {
			if (isset($options[$option]))
				$this->$option = $options[$option];
		}
	}

	function saveOptions () {
		global $patern;
		foreach ($this->options as $option => $patern) {
			if ($patern === null) {
				$options[$option] = $this->$option;
			} elseif (is_array($this->$option)){
				$this->$option = array_filter($_POST[$option],create_function('$a','global $patern;return preg_match($patern,$a);'));
			} elseif (preg_match($patern,$this->$option)){
				$options[$option] = $this->$option;
			}
		}
		update_option($this->themeName."OptionsVersion".$this->version,$options);
	}

	// This is in no way comprehensive but does help to ident IE for style sheet hacking.
	function get_agent_body_class($class = array()){
		$useragent = getenv('HTTP_USER_AGENT');

		if(preg_match('!gecko/\d+!i',$useragent))
			$class[] = 'gecko';
		elseif(preg_match('!(applewebkit|konqueror)/[\d\.]+!i',$useragent))
			$class[] = 'webkit';
		elseif (preg_match('!msie\s+(\d+\.\d+)!i',$useragent,$match)) {
			$class[] = 'ie';
			$version = floatval($match[1]);

			/* Add an identifier for IE versions. */
			if ($version >= 9)						array_push($class,'ienew');
			if ($version >= 8 &&	$version < 9)	array_push($class,'ie8');
			if ($version >= 7 &&	$version < 8)	array_push($class,'ie7');
			if ($version >= 6 &&	$version < 7)	array_push($class,'ie6');
			if ($version >= 5.5 &&	$version < 6)	array_push($class,'ie55');
			if ($version >= 5 &&	$version < 5.5)	array_push($class,'ie5');
			if ($version < 5) 						array_push($class,'ieold');
		}

		return $class;
	}

	function extraRSSFeeds() {
		global $post, $wp_version,$post;
		if (version_compare($wp_version, '2.8', 'ge')) // WP 2.8 Does this for me so I don't need this anymore.
			return;

		if ((comments_open() || get_comments_number() > 0) && (!is_attachment() && (is_single() || is_page()))) {
		?>	<link rel="alternate" type="application/rss+xml" title="<?php bloginfo("name");_e(' comments feed',THEMENAME);?>" href="<?php echo get_post_comments_feed_link();?>"/><?php
		} elseif (is_search()) {
			$search = attribute_escape(get_search_query());
			if (!empty($search))
		?>	<link rel="alternate" type="application/rss+xml" title="<?php bloginfo("name");echo " &raquo; search &quot;".$search."&quot; ";?>" href="<?php echo get_search_feed_link()?>"/><?php
		} elseif(is_category()) {
			global $cat;
		?>	<link rel="alternate" type="application/rss+xml" title="<?php bloginfo("name");echo " &raquo; category &quot;".get_catname($cat)."&quot; ";?>" href="<?php echo get_category_feed_link($cat)?>"/><?php
		} elseif(is_tag()) {
			global $tag;
			$term = is_term($tag,"post_tag");
		?>	<link rel="alternate" type="application/rss+xml" title="<?php bloginfo("name");echo " &raquo; tag &quot;$tag&quot; ";?>" href="<?php echo get_tag_feed_link($term["term_id"])?>"/><?php
		}

		return true;
	}

	function extraCSS() {
		global $post;?>
<style type="text/css" media="screen">
<!--
a{color:<?php echo (isset($this->anchorColour) ? $this->anchorColour : "#006090")?>}<?php

if ($this->bulletStyle[0]['colour'] != "#cccccc" )
	echo ".bullet,#importantPages .page_item a,.page_item,.cat-item {background-image:url({$this->bulletStyle[0]['url']})}";

foreach((array)$this->bulletStyle["cat"] as $cat => $style) {
	echo "\n.cat-item".($cat != 0 ? "-{$cat}" : ",.bullet")."{background-image:url({$style["url"]});border-color:{$style["colour"]}}";
}
foreach((array)$this->bulletStyle["page"] as $page => $style) {
	echo "\n.page-item".($page != 0 ? "-{$page},#importantPages .page-item-{$page} a" : ",.bullet")." {background-image:url({$style["url"]});}";
}
if (is_singular() && !in_array((int)$post->ID,array_keys((array)$this->bulletStyle["page"]))) {
	$catWithStyle = $this->getFirstCatWithStyle($post->ID);
	echo "\n.underline{border-color:".($catWithStyle && isset($this->bulletStyle["cat"][$catWithStyle]) ? $this->bulletStyle["cat"][$catWithStyle]["colour"] : $this->bulletStyle[0]["colour"])."}";
} else {
	echo "\n.underline{border-color:".(isset($this->bulletStyle["page"][$post->ID]) ? $this->bulletStyle["page"][$post->ID]["colour"] : $this->bulletStyle[0]["colour"])."}";
}
echo "\n";?>
-->
</style>
<?php
		return true;
	}

	function navigationBar() {

		switch ($this->navigationBar) {
			case 9:
				return false;
				break;
			case 1:
				$output = wp_list_categories("title_li=&echo=0");
				break;
			case 2:
				$output = wp_list_pages("title_li=&echo=0");
				break;
			case 3:
				$output = wp_list_pages("title_li=&meta_key=_wp_page_template&meta_value=sectiontemplate.php&echo=0");
				break;
			case 4:
				$output = wp_list_pages("title_li=&hierarchical=1&meta_key=page-location&meta_value=3&echo=0");
				break;
		}
		echo ($output ? "<div id=\"navigation\"><ul id=\"navList\">$output</ul><span class=\"clear\"></span></div>" : "");
	}

	function removeTitleAttrib($content = "") {
		$content = preg_replace("/(<a [^<>]*)(title=\"[^\"]*\")([^<>]*>)/iUs","$1$3",$content);
		return($content);
	}

	function addPostPageOptions(){
		if( function_exists("add_meta_box")) {
			add_meta_box("themePostOptions","Theme options",array($this,"singlePostOptions"),"post");
			add_meta_box("themePageOptions","Theme options",array($this,"singlePageOptions"),"page");
		}
	}

	function htmlColour2RGB ($colour = "#c0c0c0") {						// Convert HTML colours #abc or #a0b1c2 to RGB values
		if (preg_match("/^#[a-f0-9]{6}$/i",$colour)) {
			$r = hexdec($colour[1].$colour[2]);
			$g = hexdec($colour[3].$colour[4]);
            $b = hexdec($colour[5].$colour[6]);
		} elseif (preg_match("/^#[a-f0-9]{3}$/i",$colour)) {
			$r = hexdec($colour[1].$colour[1]);
			$g = hexdec($colour[2].$colour[2]);
            $b = hexdec($colour[3].$colour[3]);
		} else {
			return false;
		}
		return array($r,$g,$b);
	}

	function createBullet ($colour = "#c0c0c0",$description = null,$parent = 0) {
		if (!function_exists("wp_generate_attachment_metadata")) {
			echo "This function can only be called from the admin side of WP";
			return false;
		}

		$uploads = wp_upload_dir();

		// If there is a problem with the uploads folder we'll drop out.
		if ($uploads["error"])
			return false;

		// Convert the colour to RGB.
		if ((list ($r,$g,$b) = $this->htmlColour2RGB($colour)) === false)
			return false;

		if (preg_match("/^#C{3,6}$/i",$colour))
			return array(0,get_bloginfo("template_url")."/images/default.gif");

		//Search for an existing attachment with this colour.
//		$existingBullets = get_posts("post_type=attachment&meta_key=_bullet&meta_value=$colour"); // WP2.5 causes this to fail
		$existingBullets = $this->getBullets($colour);

		if (is_array($existingBullets) && count($existingBullets) != 0)
			return array($existingBullets[0]["id"],$existingBullets[0]["url"]);

		// Create the image resource or drop out if fail.
		if (($bullet = @imagecreate(7,7)) === false)
			return false;

		$fillColour = imagecolorallocate($bullet,$r,$g,$b);
		imagefilledrectangle($bullet, 0, 0, 6, 6, $fillColour);

		// Create the file content
		if (function_exists("imagegif")) {
			$filename = wp_unique_filename($uploads["path"],"bullet-$colour.gif");
			$newFile = "{$uploads["path"]}/$filename";
			$type = "image/gif";
			$itWorked = imagegif($bullet,$newFile);
		} else {
			$filename = wp_unique_filename($uploads["path"],"bullet-$colour.png");
			$newFile = "{$uploads["path"]}/$filename";
			$type = "image/png";
			$itWorked = imagepng($bullet,$newFile);
		}
		imagedestroy($bullet);

		if (!$itWorked)
			return false;

		// Set the file permissions
		$stat = stat(dirname($newFile));
		$perms = $stat["mode"] & 0000666;
		@chmod($newFile,$perms);

		// Compute the URL
		$url = $uploads["url"]. "/$filename";
		apply_filters("wp_handle_upload",array("file"=>$newFile,"url"=>$url,"type"=>$type));

		// Create a post for the attachment
		$object = array(
			"post_title" => $colour,
			"post_content" => ($description != null ? $description : "Automatically created bullet point with solid colour of red = $r, green = $g and blue = $b. hex = $colour"),
			"post_mime_type" => $type,
			"guid" => $url,
		);

		$id = wp_insert_attachment($object, $newFile, $parent);

		// If we're not given and ID then delete the file and return
		if (!$id){
			unlink ($newFile);
			return false;
		}

		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata($id,$newFile));
		do_action("wp_create_file_in_uploads", $newFile, $id);

		// Add some post meta to make this easy to find again later.
		if(!update_post_meta($id,"_bullet",$colour)) add_post_meta($id,"_bullet",$colour);

		return array($id,$url);
	}

	function cleanUp($postID = 0,$postContent = null) {					//	Remove any orphaned terms and post meta for thumbs

		$taxonomy = "spectaculahighlight";
		$validTerms = array();
		foreach((array)$this->getSections() as $section) {
			array_push($validTerms,$section["term_name"]);
		}
		foreach(get_terms($taxonomy) as $term){
			if (!in_array($term->name,$validTerms)) {
				wp_delete_term($term->term_id,$taxonomy);
			}
		}
	}

	function isInTerm($postID,$term,$taxonomy = "spectaculahighlight") {
		$postID = (int) $postID;
		if (!$postID) return false;

		if ($termData = is_term($term,$taxonomy)) {
			$postTaxonomies = wp_get_object_terms($postID,$taxonomy,array("fields" => "ids"));
			if (in_array((int) $termData["term_id"],(array)$postTaxonomies)) {
				return true;
			}
		}
		return false;
	}

	function getSections() {											// Return a list of pages that are using the section template.
		global $wpdb;
		$query =
			"SELECT ID, post_title, menu_order, post_status
			FROM $wpdb->posts
			LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id )
			WHERE post_type = 'page'
				AND $wpdb->postmeta.meta_key = '_wp_page_template'
				AND $wpdb->postmeta.meta_value = 'sectiontemplate.php'
			ORDER BY menu_order ASC";

		$sectionPages = $wpdb->get_results($query);

		foreach ((array)$sectionPages as $sectionPage) {
			$sections[$sectionPage->ID] = array(
												"title" => $sectionPage->post_title,
												"term_name" => "page-".$sectionPage->ID,
												"live" => ($sectionPage->post_status == "publish" ? true : false)
												);
		}

		if (count($sections))
			return $sections;
		else
			return false;
	}

	function singlePageOptions($post = ""){								// The options displayed at the bottom of a page.
		$locations = $this->pageLocations;

		if ($post->ID)
			$currentLocation = intval(get_post_meta($post->ID,"page-location",true));?>

		<p><strong>Choose an additional location to list this page.</strong></p>
		<?php
		foreach ($locations as $key => $location) {?>
			<p><input <?php echo ($key == $currentLocation ? "checked=\"checked\" " : ""); ?>type="radio" name="pagelocation" value="<?php echo $key;?>" id="pageLocation<?php echo $key;?>"/>
			<label for="pageLocation<?php echo $key;?>"><?php echo $location;?></label>
			</p>
			<?php
		}?>
		<p>The Navigation bar option will, surprise surprise, list it in the Navigation bar. However you'll need to change the settings for Navigation bar to reflect your desire, otherwise it'll act as a normal page.<br/>
		You'll find the <strong>Navigation Bar</strong> option in the <strong>customise this theme</strong> section under the presentation/design admin page.</p>
		<?php
	}

	function singlePostOptions() {										// The options displayed at the bottom of a post.
		global $post;

		echo '<h2>'.__('Choose sections to highlight this post in.',THEMENAME).'</h2>';
		if (($sections = $this->getSections()) !== false) {
			foreach ($sections as $key => $section) {
				if ($post->ID && $this->isInTerm($post->ID,"page-{$key}"))
					$checked = " checked=\"checked\"";
				else
					unset($checked);
					if (!$section["live"]) $message = " ".__('(unpublished or private)',THEMENAME); else unset($message);
echo <<<SELECTION
<label for="page-{$key}">
	<input id="page-{$key}" name="highlightsection[{$key}]" type="checkbox" value="1" $checked/>
	<strong>&nbsp;{$section["title"]}$message</strong>
</label><br/><br/>
SELECTION;
			}
		} else {
			echo '<p>You need to create a page and set the page template to section.</p>';
			// TODO: Proper help text.
		}

		echo '<input type="hidden" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" name="checkhighlights"/>';

	}

	function getSectionCategories($postID){								// Get the post meta from the passed ID and clean it up.
		$postID = (int) $postID;
		if (!$postID)
			return false;

		// Collect a list of all category IDs.
		$allCategoryID = array_map(create_function('$a','return $a->term_id;'),get_categories("hide_empty=0"));

		$showCats = array_filter((array)explode(",",get_post_meta($postID,"categories",true)),create_function('$a','return is_numeric($a);'));

		$return = array_intersect($allCategoryID,$showCats); // Return the the IDs set in the meta data that are in the category ID array

		if ($return)
			return $return;
		else
			return false;
	}

	function processCategoryOptions($catID) {
		if (!current_user_can("manage_categories"))
			return false;

		if (!(intval($catID) > 0))
			return false;

		// Sort out sectioning.
		$addToSection = array_keys((array)$_POST["addToSection"]);

		if (($sections = $this->getSections()) !== false) {
			foreach (array_keys((array)$sections) as $key) {
				$sectionCategories[$key] = $this->getSectionCategories($key);
				// If this is from the edit category section and the page is the section but is not ticked then remove it.
				if (($offset = array_search($catID,(array)$sectionCategories[$key])) !== false && !in_array($key,(array)$addToSection)) {
					unset($sectionCategories[$key][$offset]);
					$newList = implode(",",$sectionCategories[$key]);
					if (!update_post_meta($key,"categories",$newList)) add_post_meta($key,"categories",$newList);

				// If this category is not in the section but is ticked then add it.
				} elseif (!in_array($catID,(array)$sectionCategories[$key]) && in_array($key,(array)$addToSection)) {
					$sectionCategories[$key][] = $catID;
					$newList = implode(",",$sectionCategories[$key]);
					if (!update_post_meta($key,"categories",$newList)) add_post_meta($key,"categories",$newList);
				}
			}
		}

		if (strtoupper($this->bulletStyle[0]["colour"]) != strtoupper($_POST["categoryColour"]) && (list($id,$url) = $this->createBullet(strtoupper($_POST["categoryColour"]))) !== false){
			$this->bulletStyle["cat"][$catID]["colour"] = strtoupper($_POST["categoryColour"]);
			$this->bulletStyle["cat"][$catID]["url"] = $url;
			$this->bulletStyle["cat"][$catID]["id"] = $id;

			// Time to save
			$this->saveOptions();
		} else {
			unset($this->bulletStyle["cat"][$catID]);
			$this->saveOptions();
		}

		// If we got this far then all went well.
		return true;
	}

	function getFirstCatWithStyle($postID = 0) {						// Returns the ID of the first category to have style from the posts categories.
		global $post;

		if (!in_the_loop() && $postID == 0)
			return false;

		if (is_attachment() && $post->post_parent)
			$postID = $post->post_parent;

		if ($postID != 0)
			$thisPost = get_post($postID);

		if (($postID == 0 && $post->post_type != "post") || ($postID != 0 && $thisPost->post_type != "post"))
			return false;

		$categories = array_map(create_function('$cat','return (int) $cat->term_id;'),get_the_category(($postID ? $postID : "")));
		$allWithStyle = array_intersect((array)array_keys((array)$this->bulletStyle["cat"]),(array)$categories);
		$first = array_shift($allWithStyle);

		if ($first)
			return $first;
		else
			return false;
	}

	function categoryColourAndSection($categoryData = null){			// HTML Output at the bottom of the edit/create category page.
		if (!current_user_can("manage_categories"))
			return false;

		global $action,$wp_db_version;

		if ($action == "addcat" && $wp_db_version < 9000) {
			// WP 2.6 has a problem with the create_category hook when using ajax. So I don't know how to hook into that bit. Works in 2.7 trunk however.
			return false;
		}

		if (($sections = $this->getSections()) !== false) {	?>
			<div class="form-field<?php echo ($wp_db_version < 9000? " oldVersion" : " newVersion")?>"><?php
				foreach ((array)$sections as $key => $section) {?>
					<label class="addCategorySection" for="<?php echo sanitize_title("{$section["title"]}-{$key}");?>">
						<input type="checkbox" name="addToSection[<?php echo $key;?>]" id="<?php echo sanitize_title("{$section["title"]}-{$key}");?>"<?php echo (in_array($categoryData->term_id,(array)$this->getSectionCategories($key)) && $categoryData->term_id ? " checked=\"checked\"" : "");?>/>
						<?php echo get_the_title($key).(!$section["live"] ? " ".__('(unpublished or private)',THEMENAME) : "");?>
					</label>
					<?php
				}?>
				<p><?php _e("Choose the sections you'd like this categories latest posts to show up under.");?></p>
			</div><?php
		}?>
		<div class="form-field<?php echo ($wp_db_version < 9000? " oldVersion" : " newVersion")?>">
			<label for="categoryColour"><?php _e('Bullet and underline colour',THEMENAME);?></label>
			<?php $colour = ($this->bulletStyle["cat"][$categoryData->term_id]["colour"] ? $this->bulletStyle["cat"][$categoryData->term_id]["colour"] : $this->bulletStyle[0]["colour"]);?>
			<?php $this->colourPickerBlock("categoryColour",$colour,"categoryColour");?>
		</div>
		<?php
		return true;
	}

	function processPageOptions($postID,$postContent) {					// This is executed everytime a page is saved.

		// If the user isn't an Editor don't bother.
		if (!current_user_can("level_7"))
			return false;

		// Get the actual post ID and check that this is really a post.
		if ($postContent->post_type == "revision") {
			$postID = $postContent->post_parent;
			$postContent = get_post($postID);
		}

		if (strtolower($postContent->post_type) != "page")
			return false;

		$locations = $this->pageLocations;

		if ($postID)
			$currentLocation = intval(get_post_meta($postID,"page-location",true));

		if (intval($_POST["pagelocation"]) != $currentLocation)
			if (!update_post_meta($postID,"page-location",intval($_POST["pagelocation"])))
				add_post_meta($postID,"page-location",intval($_POST["pagelocation"]));

	}

	function processPostOptions($postID,$postContent) {							// This is executed everytime a post is saved.

		if (!current_user_can('edit_posts'))									// If the user isn't an Editor don't bother.
			return false;

		// Get the actual post ID and check that this is really a post.
		if ($postContent->post_type == 'revision') {
			$postID = $postContent->post_parent;
			$postContent = get_post($postID);
		}

		if (strtolower($postContent->post_type) != 'post')
			return false;

		// If the postID has somehow been set to something other than a numeric value we'll stop.
		$postID = (int) $postID;
		if (!$postID)
			return false;

		// If the save button wasn't hit die.
		if (!wp_verify_nonce($_POST['checkhighlights'], plugin_basename(__FILE__)))
			return false;

		// Add the term taxonomy for each section that was ticked in the post admin page.
		if ((count((array) $_POST["highlightsection"]) >= 1) && is_taxonomy("spectaculahighlight")) {
			$terms = array();
			foreach ((array)$_POST["highlightsection"] as $key => $addHighlight) {
				if ($addHighlight == 1) {
					if (!is_term("page-".$key,"spectaculahighlight"))
						wp_insert_term("page-".$key,"spectaculahighlight");
					array_push($terms,"page-".$key);
				}
			}
			wp_set_object_terms($postID,$terms,'spectaculahighlight');

		// If nothing was ticked we'll remove this post from all highlight terms.
		} elseif (is_taxonomy('spectaculahighlight')) {
			wp_set_object_terms($postID,array(),'spectaculahighlight');

		} else {	// This should never come about but just in case.
			return new WP_Error("invalid_taxonomy", __('spectaculahighlight taxonomy is invalid or something odd happened.',THEMENAME));
		}

		return true;
	}

	function addThemeAdminPage() {
		if ($_GET['page'] == basename(__FILE__)) {

			// Process post
			if (wp_verify_nonce($_POST['admin_nonce'], plugin_basename(__FILE__))) {
				$options = get_option($this->themeName."Options");

				global $patern;
				foreach ($this->options as $option => $patern) {
					if (is_array($_POST[$option])){

						$this->$option = array_filter($_POST[$option],create_function('$a','global $patern;return preg_match($patern,$a);'));
						if (array_diff((array)$_POST[$option],(array)$this->$option)) {
							$this->errors[] = "Error in: $option";
						}
					} elseif ($patern != null && preg_match($patern,$_POST[$option])) {
						$this->$option = $_POST[$option];
					} elseif ($patern != null && isset($_POST[$option]) &&!preg_match($patern,$_POST[$option])) {
						$this->errors[] = "Error in: $option";
					}
				}

				$sections = array_keys((array)$this->getSections());

				foreach ((array)$this->sectionBulletColour as $page => $colour){
					if (in_array($page,$sections) && strtolower($colour) != strtolower($this->bulletStyle[0]["colour"])) {
						if ((list($id,$url) = $this->createBullet($colour)) !== false) {
							$this->bulletStyle["page"][$page]["colour"] = $colour;
							$this->bulletStyle["page"][$page]["url"] = $url;
							$this->bulletStyle["page"][$page]["id"] = $id;
						} else {
							$this->errors[] = "Invalid colour submission";
						}
					} else {
						unset($this->bulletStyle["page"][$page]);
					}
				}

				foreach (array_keys((array)$this->bulletStyle["page"]) as $page) {
					if (!in_array($page,(array)$sections))
						unset($this->bulletStyle["page"][$page]);
				}

				if (strtolower($this->defaultBulletColour) != strtolower($this->bulletStyle[0]["colour"])) {
					if ((list($id,$url) = $this->createBullet(strtoupper($this->defaultBulletColour))) !== false) {
						$this->bulletStyle[0]["colour"] = strtoupper($this->defaultBulletColour);
						$this->bulletStyle[0]["url"] = $url;
						$this->bulletStyle[0]["id"] = $id;
					}
				}

				$this->saveOptions();
			}
		}
		add_theme_page(__('Change theme settings',THEMENAME), __('Customise the theme',THEMENAME), "edit_themes", basename(__FILE__), array($this,"themeAdminPage")); /* Add my HTML to the back end.*/
	}

	function getBullets($metaValue = ""){
		global $wpdb;

		$query = "SELECT $wpdb->posts.*
			FROM $wpdb->posts
				LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
				WHERE 1=1
					AND $wpdb->posts.post_type = 'attachment'
					AND $wpdb->posts.post_status = 'inherit'
					AND $wpdb->postmeta.meta_key = '_bullet'
					".(preg_match('/^#[0-f]{3,6}$/i',$metaValue)? " AND $wpdb->postmeta.meta_value = '$metaValue' " :"")."
				ORDER BY $wpdb->posts.post_date DESC";

		$bullets = $wpdb->get_results($query);

		$existingBullets = array_map(create_function('$a','$colour = get_post_meta($a->ID,"_bullet",true);return array("colour" => $colour, "url" => clean_url($a->guid),"id" => $a->ID);'),(array)$bullets);

		if ($metaValue == "")
			array_unshift($existingBullets,array("colour" => "#cccccc","url" => get_bloginfo("template_url")."/images/default.gif","id" => 0));

		return $existingBullets;
	}

	function colourPickerBlock($name,$value,$blockID = ""){?>

		<input class="colourInput" type="text" name="<?php echo $name ?>" value="<?php echo $value ?>"<?php echo (!empty($blockID) ? " id=\"$blockID\"" : "")?>/>
		<div class="pickerBlock">
			<div class="picker">JavaScript seems to be missing.</div>
			<div style="margin-left:210px;">
				<strong><?php _e('Defined colours',THEMENAME);?></strong>

				<?php
				$bullets = $this->getBullets();
				foreach($bullets as $bullet) {
					?><a rel="<?php echo ($bullet["colour"] ? $bullet["colour"] : "#000000");?>" class="bulletColour"><img src="<?php echo $bullet["url"];?>" alt="bullet"/>&nbsp;<?php echo $bullet["colour"];?></a><?php
				}?>

				<div style="clear:both"></div>
			</div>
			<strong class="farbToggle"><a>[-]</a></strong>
		</div>
		<?php
	}

	function outputScheme(){
		if ($this->scheme)
			echo '<link rel="stylesheet" href="'.get_bloginfo('template_url').'/schemes/'.$this->scheme.'/scheme.css" type="text/css" media="screen" />';
	}

	function findSchemes () {
		if (isset($this->colourSchemes) && $this->colourSchemes !== "")
			return $this->colourSchemes;

		$schemesRoot = TEMPLATEPATH."/schemes";
		$schemes = @opendir($schemesRoot);

		if (!$schemes)
			return false;

		while (($schemeFolder = readdir($schemes)) !== false ) {
			if (is_dir($schemesRoot . "/" . $schemeFolder) && is_readable($schemesRoot . "/" . $schemeFolder)) {
				if ($schemeFolder{0} == "." || $schemeFolder == ".." || $schemeFolder == "CSV"  )
					continue;

				$schemeFolderContent = @opendir($schemesRoot . "/" . $schemeFolder);

				while (($schemeFile = readdir($schemeFolderContent)) !== false) {
					if($schemeFile == "scheme.css")
						$this->colourSchemes[] = $schemeFolder;
				}
				@closedir($schemeFolderContent);
			}
		}
		@closedir($schemesRoot);

		return($this->colourSchemes);
	}

	function themeAdminPage() {
		if ($this->errors) {
			echo '<div id="message" class="error fade" style="background-color: rgb(255,0,0)">';
			foreach ($this->errors as $error){
				echo ($firstDone ? "<br/>" : "").$error;
				$firstDone = true;
			}
			echo '</div>';
		}?>

		<div class="wrap">
		<h2><?php _e('Theme options',THEMENAME); ?></h2>
		<form method="post" action="" id="ICITThemeOptions" enctype="multipart/form-data">
			<table class="form-table">
				<tr valign="top">
					<th scope="row">Navigation bar</th>
					<td>
						<label for="navigationBar1"><input type="radio" name="navigationBar" id="navigationBar1" value="1"<?php echo ($this->navigationBar == 1 ? " checked=\"checked\"" : "");?>/> All Categories</label><br/>
						<label for="navigationBar2"><input type="radio" name="navigationBar" id="navigationBar2" value="2"<?php echo ($this->navigationBar == 2 ? " checked=\"checked\"" : "");?>/> All Pages</label><br/>
						<label for="navigationBar3"><input type="radio" name="navigationBar" id="navigationBar3" value="3"<?php echo ($this->navigationBar == 3 ? " checked=\"checked\"" : "");?>/> Section pages</label><br/>
						<label for="navigationBar4"><input type="radio" name="navigationBar" id="navigationBar4" value="4"<?php echo ($this->navigationBar == 4 ? " checked=\"checked\"" : "");?>/> Chosen pages</label><br/>
						<label for="navigationBar9"><input type="radio" name="navigationBar" id="navigationBar9" value="9"<?php echo ($this->navigationBar == 9 ? " checked=\"checked\"" : "");?>/> Disabled</label><br/>
					</td>
				</tr>
				<tr>
					<th scope="row">Colour scheme</th>
					<td>
						<label for="schemeDefault"><input id="schemeDefault" type="radio" name="scheme" value="0"<?php echo (!isset($this->scheme) || $this->scheme == 0 ? ' checked="checked"' : "");?>/>&nbsp;default</label><br/>
						<?php
						if($colourSchemes = $this->findSchemes())
							foreach($colourSchemes as $scheme) {?>
								<label for="scheme<?php echo $scheme;?>"><input id="scheme<?php echo $scheme;?>" type="radio" name="scheme" value="<?php echo $scheme;?>"<?php echo ($scheme == $this->scheme ? ' checked="checked"' : "");?>/>&nbsp;<?php echo $scheme;?></label><br/>
							<?php
							}?>
					</td>
				</tr>
				<tr>
					<th scope="row">Anchor Colour</th>
					<td><?php $this->colourPickerBlock("anchorColour",($this->anchorColour ? $this->anchorColour : "#990000"));	?></td>
				</tr>
				<tr>
					<th scope="row"><?php _e('Default bullet colour',THEMENAME);?></th>
					<td><?php $this->colourPickerBlock("defaultBulletColour",($this->defaultBulletColour ? $this->defaultBulletColour : $this->bulletStyle[0]["colour"]));?></td>
				</tr>
				<?php
				$sections = $this->getSections();
				if (is_array($sections)) {?>

				<tr>
					<th scope="row">Section pages colour</th>
					<td>
						<?php
						foreach((array)$sections as $id => $section) {
							echo "<strong>".$section["title"]."</strong>".(!$section["live"] ? " (unpublished or private)" : "")."<br/>";
							$this->colourPickerBlock("sectionBulletColour[".$id."]",($this->bulletStyle["page"][$id]["colour"] ? strtolower($this->bulletStyle["page"][$id]["colour"]) : strtolower($this->bulletStyle[0]["colour"])));?>
							<br/><br/><?php
						}
						?>
					</td>
				</tr>
				<?php }?>

			</table>

			<p class="submit">
				<input type="submit" value="Save Changes"/>

				<input type="hidden" value="<?php echo wp_create_nonce(plugin_basename(__FILE__))?>" name="admin_nonce"/>
			</p>
		</form>
	</div>
	<?php
	}
}

if (!function_exists('getFirstCatWithStyle')) {
	function getFirstCatWithStyle($post = 0) {
		global $SpectacuLATheme;
		if (is_object($SpectacuLATheme))
			return $SpectacuLATheme->getFirstCatWithStyle($post);
	}
}

/*
 I call this from within the body tag to add a couple of classes to it to help
 me with the CSS in certain browsers, namely IE.
 Seems this function has been added to wp2.8. I've split out the user agent
 sniffing into another function and added that to the new filter.
*/
if (!function_exists('body_class')) {
	function body_class() {
		if (is_page())			$class[] = 'page';
		if (is_home())			$class[] = 'home';
		if (is_single())		$class[] = 'single';
		if (is_category())		$class[] = 'category';
		if (is_author())		$class[] = 'author';
		if (is_search())		$class[] = 'search';
		if (is_date())			$class[] = 'date';
		if (is_year())			$class[] = 'year';
		if (is_month())			$class[] = 'month';
		if (is_day())			$class[] = 'day';
		if (is_time())			$class[] = 'time';
		if (is_404())			$class[] = 'error404';
		if (is_paged())			$class[] = 'paged';
		if (is_attachment())	$class[] = 'attachment';
		if (is_archive() && !is_category()) $class[] = 'archive';

		$class = apply_filters('body_class',$class);

		$class = implode(' ',$class);
		if (!empty($class)) {
			echo " class=\"$class\"";
		}
	}
}

if (!function_exists('get_search_query')) {
	function get_search_query(){
		return get_query_var('s');
	}
}

if (!function_exists('custom_image_admin_head')) {
	function custom_image_admin_head(){?>

	<style type="text/css" media="screen">
	<!--
		#headimg {
			position:relative;
			height: 110px;
			background: no-repeat 0 0 #F0F0F5;
			margin-bottom: 2em;
			padding:10px;
			border:solid 1px #999;
		}
		#headimg h1 {
			width:480px;
			font-style:oblique;
			margin:0;
			position:absolute;
			line-height:60px;
			top:23px;
			left:10px;
			z-index:2;
			font-size:4em;
			letter-spacing:-0.05em;
			font-weight:normal;
			font-family: georgia,serif;
		}
		#headimg #desc{
			position:absolute;
			width:480px;
			top:80px;
			left:10px;
			text-indent:1em;
			letter-spacing:0.05em;
			z-index:2;
			color:#666;
			font-style:italic;
		}
		#headimg #desc,
		#headimg h1 a,
		#headimg h1 {
			text-decoration:none;
			<?php
			echo get_header_textcolor() != 'blank' ? 'color:#'.get_header_textcolor().';':'display:none';
			?>
		}
	-->
	</style>

	<?php
	}
}

if (!function_exists('custom_image_head')){
	function custom_image_head() {?>

		<style type="text/css" media="screen">
			<!--
			#logo .description,
			#logo h1,
			#logo h1 a {
				<?php echo (get_header_textcolor() != "blank" ? "color: #".get_header_textcolor().";":"display:none");?>
			}
			-->
		</style>
		<?php
		$headerImage = get_header_image();

		//If it's a png we're going to have to fix it for anything less than IE7.
		echo (strtolower(substr($headerImage,-3)) == 'png' ? "<!--[if lt IE 7]>\n\t<style>\n\t\t#logo img{visibility:hidden}#logo{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=image,src={$headerImage}}\n\t</style>\n\t<![endif]-->\n" : '');
	}
}
?>