<?php /*

 ocPortal
 Copyright (c) ocProducts, 2004-2012

 See text/EN/licence.txt for full licencing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license		http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright	ocProducts Ltd
 * @package		core_themeing
 */

/**
 * Module page class.
 */
class Module_admin_themes
{

	/**
	 * Standard modular info function.
	 *
	 * @return ?array	Map of module info (NULL: module is disabled).
	 */
	function info()
	{
		$info=array();
		$info['author']='Chris Graham';
		$info['organisation']='ocProducts';
		$info['hacked_by']=NULL;
		$info['hack_version']=NULL;
		$info['version']=4;
		$info['locked']=true;
		$info['update_require_upgrade']=1;
		return $info;
	}

	/**
	 * Standard modular uninstall function.
	 */
	function uninstall()
	{
		$GLOBALS['SITE_DB']->drop_if_exists('theme_images');

		delete_config_option('templates_store_revisions');
		delete_config_option('templates_number_revisions_show');

		$langs=find_all_langs(true);
		foreach (array_keys($langs) as $lang)
		{
			deldir_contents(get_custom_file_base().'/themes/default/templates_cached/'.$lang,true);
		}
		//deldir_contents(get_custom_file_base().'/themes/default/images_custom',true);
		//deldir_contents(get_file_base().'/themes',true);
		// templates_custom, css_custom purposely left
	}

	/**
	 * Standard modular install function.
	 *
	 * @param  ?integer	What version we're upgrading from (NULL: new install)
	 * @param  ?integer	What hack version we're upgrading from (NULL: new-install/not-upgrading-from-a-hacked-version)
	 */
	function install($upgrade_from=NULL,$upgrade_from_hack=NULL)
	{
		require_code('themes2');

		$themes=find_all_themes(); // Find all images for all themes

		/*if ($upgrade_from==2)
		{
			foreach (array_keys($themes) as $theme)
			{
				if ($theme!='default')
				{
					// Make it so it'll now import from the default theme to get anything that is currently missing
					$_dir=opendir(get_file_base().'/themes/default/css');
					while (false!==($file=readdir($_dir)))
					{
						if (strtolower(substr($file,-4,4))=='.css')
						{
							$path=get_file_base().'/themes/'.$theme.'/css/'.$file;
							$new_css_file=(($file=='no_cache.css')?'':"@import url(../../../default/css/$file);\n\n").file_get_contents($path);
							$myfile=@fopen($path,'wt');
							if ($myfile===false) intelligent_write_error($path);
							fwrite($myfile,$new_css_file);
							fclose($myfile);
							fix_permissions($path);
						}
					}
					closedir($_dir);

					// Rename all their modified templates, because they've probably changed. They'll need to redo them :(
					$path=get_file_base().'/themes/'.$theme.'/templates_custom/';
					$_dir=opendir($path);
					if ($_dir!==false)
					{
						while (false!==($file=readdir($_dir)))
						{
							if (substr($file,-4,4)=='.tpl')
								rename($path.$file,$path.$file.'.from_'.strval($upgrade_from));
						}
						closedir($_dir);
					}
					$path=get_file_base().'/themes/'.$theme.'/templates/';
					$_dir=opendir($path);
					if ($_dir!==false)
					{
						while (false!==($file=readdir($_dir)))
						{
							if (substr($file,-4,4)=='.tpl')
								rename($path.$file,$path.$file.'.from_'.strval($upgrade_from));
						}
						closedir($_dir);
					}
				}
			}
		}*/

		if (is_null($upgrade_from))
		{
			$GLOBALS['SITE_DB']->create_table('theme_images',array(
				'id'=>'*SHORT_TEXT',
				'theme'=>'*MINIID_TEXT',
				'path'=>'URLPATH',
				'lang'=>'*LANGUAGE_NAME'
			));
			$GLOBALS['SITE_DB']->create_index('theme_images','theme',array('theme','lang'));

			add_config_option('STORE_REVISIONS','templates_store_revisions','tick','return \'1\';','ADMIN','EDIT_TEMPLATES');
			add_config_option('SHOW_REVISIONS','templates_number_revisions_show','integer','return \'5\';','ADMIN','EDIT_TEMPLATES');

			/*$langs=find_all_langs(true); // Find all images for all themes
			foreach (array_keys($themes) as $theme)
			{
				require_code('themes3');
				regen_theme_images($theme,$langs);
			}

			// Now add in any default theme images missing in other themes
			$images=find_images_do_dir('default','',$langs);
			foreach (array_keys($themes) as $theme)
			{
				foreach ($images as $id=>$path)
				{
					foreach (array_keys($langs) as $lang)
					{
						$test=$GLOBALS['SITE_DB']->query_value_null_ok('theme_images','path',array('theme'=>$theme,'lang'=>$lang,'id'=>$id));
						if (is_null($test))
						{
							$GLOBALS['SITE_DB']->query_insert('theme_images',array('id'=>$id,'theme'=>$theme,'lang'=>$lang,'path'=>$path));
						}
					}
				}
			}*/
		}

		if ((is_null($upgrade_from)) || ($upgrade_from<4))
		{
			$GLOBALS['SITE_DB']->query_insert('theme_images',array(
				'id'=>'favicon',
				'theme'=>'default',
				'path'=>'favicon.ico',
				'lang'=>fallback_lang()
			),false,true);

			$GLOBALS['SITE_DB']->query_insert('theme_images',array(
				'id'=>'appleicon',
				'theme'=>'default',
				'path'=>'appleicon.png',
				'lang'=>fallback_lang()
			),false,true);
		}
	}

	/**
	 * Standard modular entry-point finder function.
	 *
	 * @return ?array	A map of entry points (type-code=>language-code) (NULL: disabled).
	 */
	function get_entry_points()
	{
		return array('misc'=>'THEMES','add_theme'=>'ADD_THEME');
	}

	/**
	 * Standard modular run function.
	 *
	 * @return tempcode	The result of execution.
	 */
	function run()
	{
		require_lang('themes');
		require_code('view_modes');
		require_code('themes2');
		require_lang('zones');

		require_css('themes_editor');

		require_javascript('javascript_themeing');

		$type=get_param('type','misc');

		$GLOBALS['HELPER_PANEL_PIC']='pagepics/themes';
		$GLOBALS['HELPER_PANEL_TUTORIAL']='tut_themes';

		if ($type=='misc') return $this->manage_themes();
		if ($type=='choose_css') return $this->choose_css();
		if ($type=='edit_css') return $this->edit_css();
		if ($type=='_edit_css') return $this->_edit_css();
		if ($type=='edit_templates') return $this->edit_templates();
		if ($type=='_edit_templates') return $this->_edit_templates();
		if ($type=='__edit_templates') return $this->__edit_templates();
		if ($type=='manage_images') return $this->manage_images();
		if ($type=='edit_image') return $this->edit_image();
		if ($type=='_edit_image') return $this->_edit_image();
		if ($type=='add_image') return $this->add_image();
		if ($type=='_add_image') return $this->_add_image();
		if ($type=='add_theme') return $this->add_theme();
		if ($type=='_add_theme') return $this->_add_theme();
		if ($type=='edit_theme') return $this->edit_theme();
		if ($type=='_edit_theme') return $this->_edit_theme();
		if ($type=='list') return $this->list_screen_previews();
		if ($type=='view') return $this->view_screen_preview();

		return new ocp_tempcode();
	}

	/**
	 * The UI to manage themes.
	 *
	 * @return tempcode		The UI
	 */
	function manage_themes()
	{
		$title=get_screen_title('MANAGE_THEMES');

		$GLOBALS['HELPER_PANEL_TEXT']=comcode_lang_string('DOC_THEMES');

		$zones=$GLOBALS['SITE_DB']->query_select('zones',array('*'),NULL,'ORDER BY zone_title',50/*reasonable limit; zone_title is sequential for default zones*/);

		require_css('do_next');

		// Show all themes
		$_themes=find_all_themes(true);
		$site_default_theme=$GLOBALS['FORUM_DRIVER']->_get_theme(true);
		$themes=new ocp_tempcode();
		$theme_default_reason=do_lang_tempcode('DEFAULT_THEME_BY_DEFAULT');
		foreach ($_themes as $theme=>$details)
		{
			if (is_integer($theme)) $theme=strval($theme);

			// Get URLs
			$css_url=build_url(array('page'=>'_SELF','type'=>'choose_css','theme'=>$theme),'_SELF');
			$templates_url=build_url(array('page'=>'_SELF','type'=>'edit_templates','theme'=>$theme),'_SELF');
			$images_url=build_url(array('page'=>'_SELF','type'=>'manage_images','theme'=>$theme),'_SELF');
			$deletable=($theme!='default');
			$edit_url=build_url(array('page'=>'_SELF','type'=>'edit_theme','theme'=>$theme),'_SELF');
			$delete_url=build_url(array('page'=>'_SELF','type'=>'delete_theme','theme'=>$theme),'_SELF');
			$screen_preview_url=build_url(array('page'=>'_SELF','type'=>'list','keep_theme'=>$theme),'_SELF');

			// Theme date
			$date=filemtime(($theme=='default')?(get_file_base().'/themes/default'):(get_custom_file_base().'/themes/'.$theme));
			$_date=($theme=='default')?do_lang_tempcode('NA_EM'):protect_from_escaping(escape_html(get_timezoned_date($date,false)));

			// Where the theme is used
			$zone_list=new ocp_tempcode();
			if ($theme==$site_default_theme)
			{
				$zone_list->attach(do_lang_tempcode('THEME_DEFAULT_FOR_SITE'));

				// Why is this the site-default theme?
				if ($theme==preg_replace('#[^\w\-\.\d]#','_',get_site_name()))
				{
					$theme_default_reason=do_lang_tempcode('DEFAULT_THEME_BY_SITENAME');
				}
				elseif ($theme!='default')
				{
					$theme_default_reason=do_lang_tempcode('DEFAULT_THEME_BY_FORUM');
				}
			}
			foreach ($zones as $zone)
			{
				if ($zone['zone_theme']==$theme)
				{
					if ((get_option('collapse_user_zones')=='1') && ($zone['zone_name']=='site')) continue;

					if (!$zone_list->is_empty())
						$zone_list->attach(do_lang_tempcode('LIST_SEP'));
					$zone_list->attach($zone['zone_name']);
				}
			}
			if (!$zone_list->is_empty())
				$theme_usage=do_lang_tempcode('THEME_USED_ON',$zone_list);
			else $theme_usage=new ocp_tempcode();

			// Render
			$seed=NULL;
			if (addon_installed('themewizard'))
			{
				require_code('themewizard');
				$seed=find_theme_seed($theme);
			}
			$themes->attach(do_template('THEME_MANAGE',array('_GUID'=>'c65c7f3f87d62ad425c7a104a6018840','SEED'=>$seed,'THEME_USAGE'=>$theme_usage,'DATE'=>$_date,'RAW_DATE'=>strval($date),'NAME'=>$theme,'DESCRIPTION'=>$details['description'],'AUTHOR'=>$details['author'],'TITLE'=>$details['title'],'CSS_URL'=>$css_url,'TEMPLATES_URL'=>$templates_url,'IMAGES_URL'=>$images_url,'DELETABLE'=>$deletable,'EDIT_URL'=>$edit_url,'DELETE_URL'=>$delete_url,'SCREEN_PREVIEW_URL'=>$screen_preview_url)));
		}

		$zones=find_all_zones(false,true);
		require_lang('zones');

		return do_template('THEME_MANAGE_SCREEN',array('_GUID'=>'1dc277f18562976f6a23facec56a98e8','TITLE'=>$title,'THEMES'=>$themes,'THEME_DEFAULT_REASON'=>$theme_default_reason,'ZONES'=>$zones));
	}

	/**
	 * Get standard form input fields for inputting a theme.
	 *
	 * @param  string			The name of the theme
	 * @param  string			The theme title
	 * @param  string			The theme description
	 * @param  ?string		The theme author (NULL: current member)
	 * @param  string			Comma-separated list mobile-supporting pages (blank: all do)
	 * @param  BINARY			Whether the theme supports 'wide' screens
	 * @param  boolean		Whether to use this theme on all zones
	 * @return tempcode		The fields
	 */
	function get_theme_fields($name='',$title='',$description='',$author=NULL,$mobile_pages='',$supports_wide=1,$use_on_all_zones=false)
	{
		if (is_null($author)) $author=$GLOBALS['FORUM_DRIVER']->get_username(get_member());

		require_code('form_templates');
		require_code('permissions2');

		$fields=new ocp_tempcode();
		$site_default_theme=preg_replace('#[^\w\-\.\d]#','_',get_site_name());
		if ($name!='default') $fields->attach(form_input_codename(do_lang_tempcode('CODENAME'),do_lang_tempcode(file_exists(get_custom_file_base().'/themes/'.$site_default_theme)?'DESCRIPTION_CODENAME_THEME':'DESCRIPTION_CODENAME_THEME_HELPER',escape_html($site_default_theme)),'theme',$name,true));
		$fields->attach(form_input_line(do_lang_tempcode('TITLE'),do_lang_tempcode('DESCRIPTION_TITLE'),'title',$title,true));
		$fields->attach(form_input_line(do_lang_tempcode('DESCRIPTION'),do_lang_tempcode('DESCRIPTION_DESCRIPTION'),'description',$description,false));
		$fields->attach(form_input_line(do_lang_tempcode('AUTHOR'),do_lang_tempcode('DESCRIPTION_AUTHOR_THEME'),'author',$author,true));
		$fields->attach(form_input_tick(do_lang_tempcode('SUPPORTS_WIDE'),do_lang_tempcode('DESCRIPTION_SUPPORTS_WIDE'),'supports_wide',$supports_wide==1));
		$fields->attach(form_input_line(do_lang_tempcode('MOBILE_PAGES'),do_lang_tempcode('DESCRIPTION_MOBILE_PAGES'),'mobile_pages',$mobile_pages,false));
		if ($name!='default') $fields->attach(get_category_permissions_for_environment('theme',$name,NULL,NULL,($name=='')));
		$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
		$fields->attach(form_input_tick(do_lang_tempcode('USE_ON_ZONES'),do_lang_tempcode('DESCRIPTION_USE_ON_ZONES'),'use_on_all',$use_on_all_zones));

		// Mapping
		if (method_exists($GLOBALS['FORUM_DRIVER'],'get_skin_list'))
		{
			$map=file_exists(get_file_base().'/themes/map.ini')?better_parse_ini_file(get_file_base().'/themes/map.ini'):array();
			$default_selection=array();
			$mapping=new ocp_tempcode();
			$all_skins=$GLOBALS['FORUM_DRIVER']->get_skin_list();
			foreach ($map as $key=>$val)
			{
				if ($val==$name) $default_selection[]=$key;
			}
			foreach ($all_skins as $key)
			{
				$mapping->attach(form_input_list_entry($key,in_array($key,$default_selection)));
			}
			$fields->attach(form_input_multi_list(do_lang_tempcode('THEME_MAPPING'),do_lang_tempcode('DESCRIPTION_THEME_MAPPING'),'mapping',$mapping));
		}

		return $fields;
	}

	/**
	 * Common theme change saving for adding and editing themes.
	 *
	 * @param  ID_TEXT			The name of the theme
	 */
	function save_theme_changes($theme)
	{
		if (!file_exists((($theme=='default')?get_file_base():get_custom_file_base()).'/themes/'.filter_naughty($theme).'/theme.ini'))
			warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		if (post_param_integer('use_on_all',0)==1)
		{
			$GLOBALS['SITE_DB']->query('UPDATE '.get_table_prefix().'zones SET zone_theme=\''.db_escape_string($theme).'\' WHERE '.db_string_not_equal_to('zone_name','cms').' AND '.db_string_not_equal_to('zone_name','adminzone'));
		}
		persistent_cache_empty();

		$before=better_parse_ini_file((($theme=='default')?get_file_base():get_custom_file_base()).'/themes/'.filter_naughty($theme).'/theme.ini');
		$myfile=@fopen((($theme=='default')?get_file_base():get_custom_file_base()).'/themes/'.filter_naughty($theme).'/theme.ini','wt') OR intelligent_write_error(get_custom_file_base().'/themes/'.filter_naughty($theme).'/theme.ini');
		if (fwrite($myfile,'title='.post_param('title').chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		if (fwrite($myfile,'description='.post_param('description').chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		foreach ($before as $key=>$val)
		{
			if (($key!='title') && ($key!='description') && ($key!='author') && ($key!='mobile_pages') && ($key!='supports_wide'))
				fwrite($myfile,$key.'='.$val.chr(10));
		}
		if (fwrite($myfile,'author='.post_param('author').chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		if (fwrite($myfile,'mobile_pages='.post_param('mobile_pages').chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		if (fwrite($myfile,'supports_wide='.strval(post_param_integer('supports_wide',0)).chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		fclose($myfile);
		sync_file((($theme=='default')?get_file_base():get_custom_file_base()).'/themes/'.filter_naughty($theme).'/theme.ini');

		require_code('permissions2');
		set_category_permissions_from_environment('theme',$theme);

		$map=file_exists(get_file_base().'/themes/map.ini')?better_parse_ini_file(get_file_base().'/themes/map.ini'):array();
		$new_map=array();
		foreach ($map as $key=>$val)
		{
			if ($val!=$theme) $new_map[$key]=$val;
		}
		if (array_key_exists('mapping',$_POST))
		{
			foreach ($_POST['mapping'] as $val)
			{
				if (get_magic_quotes_gpc()) $val=stripslashes($val);
				$new_map[$val]=$theme;
			}
		}
		$myfile=@fopen(get_file_base().'/themes/map.ini','wt') OR intelligent_write_error(get_file_base().'/themes/map.ini');
		foreach ($new_map as $key=>$val)
		{
			if (fwrite($myfile,$key.'='.$val.chr(10))==0) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		}
		fclose($myfile);
		sync_file('themes/map.ini');
	}

	/**
	 * The UI to add a theme.
	 *
	 * @return tempcode		The UI
	 */
	function add_theme()
	{
		$title=get_screen_title('ADD_THEME');

		$fields=$this->get_theme_fields();

		$post_url=build_url(array('page'=>'_SELF','type'=>'_add_theme'),'_SELF');
		$submit_name=do_lang_tempcode('ADD_THEME');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('THEMES'))));

		if (addon_installed('themewizard'))
		{
			$theme_wizard_url=build_url(array('page'=>'admin_themewizard','type'=>'misc'),get_module_zone('admin_themewizard'));
			$text=do_lang_tempcode('DESCRIPTION_ADD_THEME_MANUAL',escape_html($theme_wizard_url->evaluate()));
		} else $text=new ocp_tempcode();

		require_javascript('javascript_ajax');
		$script=find_script('snippet');
		$javascript="
			var form=document.getElementById('main_form');
			form.old_submit=form.onsubmit;
			form.onsubmit=function()
				{
					document.getElementById('submit_button').disabled=true;
					var url='".addslashes($script)."?snippet=exists_theme&name='+window.encodeURIComponent(form.elements['theme'].value);
					if (!do_ajax_field_test(url))
					{
						document.getElementById('submit_button').disabled=false;
						return false;
					}
					document.getElementById('submit_button').disabled=false;
					if (typeof form.old_submit!='undefined' && form.old_submit) return form.old_submit();
					return true;
				};
		";

		return do_template('FORM_SCREEN',array('_GUID'=>'08b45be04f4035c7595458a719260bd9','HIDDEN'=>'','JAVASCRIPT'=>$javascript,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to add a theme.
	 *
	 * @return tempcode		The UI
	 */
	function _add_theme()
	{
		$title=get_screen_title('ADD_THEME');

		$theme=post_param('theme');
		require_code('type_validation');
		if (!is_alphanumeric($theme))
		{
			$theme=preg_replace('#[^\w\-\.\d]#','_',$theme);
//			warn_exit(do_lang_tempcode('BAD_CODENAME'));
		}
		actual_add_theme($theme);

		$this->save_theme_changes($theme);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$theme,'','theme',$theme);
	}

	/**
	 * The UI to edit/rename a theme.
	 *
	 * @return tempcode		The UI
	 */
	function edit_theme()
	{
		$title=get_screen_title('EDIT_THEME');

		$theme=get_param('theme',false,true);

		$ini_file=(($theme=='default')?get_file_base():get_custom_file_base()).'/themes/'.$theme.'/theme.ini';
		if (!file_exists($ini_file)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		$details=better_parse_ini_file($ini_file);
		if (!array_key_exists('title',$details)) $details['title']='?';
		if (!array_key_exists('description',$details)) $details['description']='?';
		if (!array_key_exists('author',$details)) $details['author']='?';
		if (!array_key_exists('mobile_pages',$details)) $details['mobile_pages']='';
		if (!array_key_exists('supports_wide',$details)) $details['supports_wide']='1';
		$fields=$this->get_theme_fields($theme,$details['title'],$details['description'],$details['author'],$details['mobile_pages'],intval($details['supports_wide']),false);
		if ($theme!='default')
		{
			$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
			$fields->attach(form_input_tick(do_lang_tempcode('COPY_THEME'),do_lang_tempcode('DESCRIPTION_COPY_THEME',escape_html($theme)),'copy',false));
			$fields->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
		}

		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_theme','old_theme'=>$theme),'_SELF');
		$submit_name=do_lang_tempcode('EDIT_THEME');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('THEMES'))));

		$javascript='var themee=document.getElementById(\'theme\'), themet=document.getElementById(\'title\'), copy=document.getElementById(\'copy\'); if (copy) copy.onchange=function() { if (copy.checked && themee.value.indexOf(\'-copy\')==-1) { themee.value+=\'-copy\'; themet.value+=\' copy\'; } };';

		return do_template('FORM_SCREEN',array('_GUID'=>'2734c55cd4d7cfa785d307d932ce8af1','JAVASCRIPT'=>$javascript,'HIDDEN'=>'','TITLE'=>$title,'TEXT'=>'','URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to edit/rename a theme.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_theme()
	{
		if (post_param_integer('delete',0)==1)
		{
			$title=get_screen_title('DELETE_THEME');

			$theme=get_param('old_theme',false,true);
			require_code('themes3');
			actual_delete_theme($theme);

			$to='';
		} elseif (post_param_integer('copy',0)==1)
		{
			$title=get_screen_title('COPY_THEME');

			$theme=get_param('old_theme',false,true);
			$to=post_param('theme',$theme); // Can't rename the default theme, so there's no such field for it
			if ($theme==$to) warn_exit(do_lang_tempcode('ALREADY_EXISTS',escape_html($to)));

			require_code('themes3');
			actual_copy_theme($theme,$to);

			$this->save_theme_changes($to);
		} else
		{
			$title=get_screen_title('EDIT_THEME');

			$theme=get_param('old_theme',false,true);
			$to=post_param('theme',$theme); // Can't rename the default theme, so there's no such field for it
			if ($theme!=$to)
			{
				require_code('type_validation');
				if (!is_alphanumeric($to))
				{
					$to=preg_replace('#[^\w\-\.\d]#','_',$to);
					//warn_exit(do_lang_tempcode('BAD_CODENAME'));
				}

				if (!file_exists(get_custom_file_base().'/themes/'.$theme))
					warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

				require_code('themes3');
				actual_rename_theme($theme,$to);
			}

			$this->save_theme_changes($to);
		}

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$to,'','theme',$to);
	}

	/**
	 * The do-next manager for after download content management.
	 *
	 * @param  tempcode			The title (output of get_screen_title)
	 * @param  tempcode			Some description to show, saying what happened
	 * @param  ID_TEXT			The theme that was just handled
	 * @param  ?LANGUAGE_NAME  The language we were working in (NULL: autodetect) (blank: autodetect)
	 * @param  ID_TEXT			Code to determine what kind of links to show
	 * @param  ID_TEXT			ID of file that an edit link should load (blank: N/A)
	 * @return tempcode			The UI
	 */
	function do_next_manager($title,$description,$theme,$lang,$type,$file)
	{
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		if (is_null($lang)) $lang='';

		switch ($type)
		{
			case 'css':
				$add_one=NULL;
				$edit_this=array('_SELF',array('type'=>'edit_css','file'=>str_replace('/css/','/css_custom/',$file),'theme'=>$theme),'_SELF');
				$edit_one=array('_SELF',array('type'=>'choose_css','theme'=>$theme),'_SELF');
				$section_title=do_lang_tempcode('CSS');
				break;

			case 'templates':
				$add_one=NULL;
				$edit_this=array('_SELF',array('type'=>'_edit_templates','f0file'=>file_exists(get_custom_file_base().'/'.str_replace('/templates/','/templates_custom/',$file))?str_replace('/templates/','/templates_custom/',$file):$file,'theme'=>$theme),'_SELF');
				$edit_one=array('_SELF',array('type'=>'edit_templates','theme'=>$theme),'_SELF');
				$section_title=do_lang_tempcode('TEMPLATES');
				break;

			case 'image':
				$add_one=array('_SELF',array('type'=>'add_image','theme'=>$theme,'lang'=>$lang),'_SELF');
				$edit_this=array('_SELF',array('type'=>'edit_image','id'=>$file,'theme'=>$theme,'lang'=>$lang),'_SELF');
				$edit_one=array('_SELF',array('type'=>'manage_images','theme'=>$theme,'lang'=>$lang),'_SELF');
				$section_title=do_lang_tempcode('THEME_IMAGES');
				break;

			default:
				$add_one=NULL;
				$edit_this=NULL;
				$edit_one=NULL;
				$section_title=NULL;
				break;
		}

		require_code('templates_donext');
		return do_next_manager($title,$description,
						NULL,
						NULL,
						/*		TYPED-ORDERED LIST OF 'LINKS'		*/
						/*	 page	 params				  zone	  */
						$add_one,								 // Add one
						$edit_this,								 // Edit this
						$edit_one,																						// Edit one
						NULL,																						// View this
						NULL,																						// View archive
						NULL,																						// Add to category
						NULL,																						// Add one category
						NULL,																						// Edit one category
						NULL,																						// Edit this category
						NULL,																						// View this category
						/*	  SPECIALLY TYPED 'LINKS'				  */
						array(),
						array(),
						array(
							/*	 type							  page			 params													 zone	  */
							array('add_one',array('_SELF',array('type'=>'add_theme'),'_SELF'),do_lang_tempcode('ADD_THEME')),								 // Add one
							is_null($theme)?NULL:array('edit_this',array('_SELF',array('type'=>'edit_theme','theme'=>$theme),'_SELF'),do_lang_tempcode('EDIT_THEME')),
							is_null($theme)?NULL:array('edit_css',array('_SELF',array('type'=>'choose_css','theme'=>$theme),'_SELF')),
							is_null($theme)?NULL:array('edit_templates',array('_SELF',array('type'=>'edit_templates','theme'=>$theme),'_SELF')),
							is_null($theme)?NULL:array('manage_images',array('_SELF',array('type'=>'manage_images','theme'=>$theme,'lang'=>$lang),'_SELF')),
							array('manage_themes',array('_SELF',array('type'=>'misc'),'_SELF'))
						),
						do_lang('THEMES'),
						NULL,
						$section_title
		);
	}

	/**
	 * The UI to choose a theme.
	 *
	 * @param  tempcode		The title to show when choosing a theme
	 * @param  boolean		Whether to also choose a language
	 * @return tempcode		The UI
	 */
	function choose_theme($title,$lang_too=false)
	{
		$themes=new ocp_tempcode();
		$_themes=find_all_themes();
		require_code('form_templates');
		foreach ($_themes as $theme=>$theme_title)
		{
			$themes->attach(form_input_list_entry($theme,($theme==$GLOBALS['FORUM_DRIVER']->get_theme()),$theme_title));
		}
		$fields=form_input_list(do_lang_tempcode('THEME'),'','theme',$themes,NULL,true);

		if ($lang_too) // We also need the language
		{
			$langs=nice_get_langs();
			$fields->attach(form_input_list(do_lang_tempcode('LANGUAGE'),do_lang_tempcode('DESCRIPTION_LANGUAGE'),'lang',$langs,NULL,true));
		}

		$post_url=get_self_url(false,false,NULL,false,true);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('CHOOSE'));

		return do_template('FORM_SCREEN',array('_GUID'=>'01030dc8f338138ac36ff4f59c7892fc','GET'=>true,'SKIP_VALIDATION'=>true,'HIDDEN'=>'','SUBMIT_NAME'=>do_lang_tempcode('CHOOSE'),'TITLE'=>$title,'FIELDS'=>$fields,'URL'=>$post_url,'TEXT'=>''));
	}

	/**
	 * The UI to choose a CSS file to edit.
	 *
	 * @return tempcode		The UI
	 */
	function choose_css()
	{
		$title=get_screen_title('EDIT_CSS');

		require_code('form_templates');

		$theme=get_param('theme',false,true);
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		$css=new ocp_tempcode();
		$files=array();
		$_dir=opendir(get_file_base().'/themes/default/css');
		while (false!==($file=readdir($_dir)))
		{
			if (strtolower(substr($file,-4,4))=='.css')
				$files[]=$file;
		}
		closedir($_dir);
		$_dir=opendir(get_file_base().'/themes/default/css_custom');
		while (false!==($file=readdir($_dir)))
		{
			if ((strtolower(substr($file,-4,4))=='.css') && (!in_array($file,$files)))
				$files[]=$file;
		}
		closedir($_dir);
		sort($files);
		foreach ($files as $file)
		{
			$css->attach(form_input_list_entry($file,$file=='global.css'));
		}
		$fields=form_input_list(do_lang_tempcode('FILE'),'','file',$css,NULL,true);

		$post_url=build_url(array('page'=>'_SELF','type'=>'edit_css','theme'=>$theme),'_SELF',array(),false,true);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('CHOOSE'));

		return do_template('FORM_SCREEN',array('_GUID'=>'16dfd6f0d77889f2438c2371e90738a3','GET'=>true,'SKIP_VALIDATION'=>true,'HIDDEN'=>'','SUBMIT_NAME'=>do_lang_tempcode('CHOOSE'),'TITLE'=>$title,'FIELDS'=>$fields,'URL'=>$post_url,'TEXT'=>do_lang_tempcode('CSS_CHOOSE_TO_EDIT')));
	}

	/**
	 * The UI to edit a CSS file.
	 *
	 * @return tempcode		The UI
	 */
	function edit_css()
	{
		$file=filter_naughty(get_param('file','global.css'));

		$title=get_screen_title('_EDIT_CSS',true,array($file));

		if (get_option('editarea')=='1')
		{
			$GLOBALS['EXTRA_HEAD']->attach(make_string_tempcode('
				<script language="javascript" type="text/javascript" src="'.get_base_url().'/data/editarea/edit_area_full.js"></script>
				<script type="text/javascript">// <![CDATA[
				editAreaLoader.init({
					id : "css"
					,syntax: "css"
					,start_highlight: true
					,language: "'.(file_exists(get_file_base().'/data/editarea/langs/'.strtolower(user_lang()))?strtolower(user_lang()):'en').'"
					,allow_resize: true
					,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, reset_highlight, word_wrap"
				});
				//]]></script>'));
		}

		$GLOBALS['HELPER_PANEL_TEXT']=comcode_lang_string('DOC_CSS');
		$GLOBALS['HELPER_PANEL_TUTORIAL']='tut_markup';

		require_javascript('javascript_ajax');

		$theme=get_param('theme','');
		if ($theme=='') return $this->choose_theme($title);
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		$url=build_url(array('page'=>'_SELF','file'=>$file,'type'=>'_edit_css'),'_SELF');

		if (get_param('restore_from','')!='') $file.='.'.get_param('restore_from');
		$path=get_custom_file_base().'/themes/'.filter_naughty($theme).'/css_custom/'.$file;
		if (!file_exists($path)) $path=get_custom_file_base().'/themes/'.filter_naughty($theme).'/css/'.$file;
		if (!file_exists($path)) $path=get_custom_file_base().'/themes/default/css_custom/'.$file;
		if (!file_exists($path)) $path=get_file_base().'/themes/default/css/'.$file;
		$css=unixify_line_format(file_get_contents($path));
		$file=preg_replace('#\.\d+#','',$file);

		$old_contents=@file_get_contents(get_file_base().'/themes/default/css/'.$file);
		if ($old_contents===false) $old_contents='';

		$GLOBALS['SEO_TITLE']=$file;

		$entries=new ocp_tempcode();

		$advanced_mode=get_param_integer('advanced_mode',0);
		if ($advanced_mode==1)
		{
			require_javascript('javascript_theme_colours');

			global $CSS_MATCHES;
			$CSS_MATCHES=array();
			$css=preg_replace_callback('#\#[\da-f][\da-f][\da-f][\da-f][\da-f][\da-f]#i','css_preg',$css);

			foreach ($CSS_MATCHES as $id=>$color)
			{
				$pos=strpos($css,'<color-'.$id.'>');
				$section_start=$pos;
				do
				{
					$section_start=strrpos(substr($css,0,$section_start),'{');
					if ($section_start===false || $section_start<5) break;
				}
				while (($css[$section_start-2]=='*') || ($css[$section_start-1]!=' '));
				$section_line_start=strrpos(substr($css,0,$section_start),chr(10));
				$line_start=strrpos(substr($css,0,$pos),chr(10));
				$context1=substr($css,$section_line_start,$section_start-$section_line_start);
				$context2=substr($css,$line_start,$pos-$line_start);
				$context=$context1.'=>'.trim($context2);
				$entries->attach(do_template('THEME_COLOUR_CHOOSER',array('_GUID'=>'a42ef9daa06a95f5bb9d715aab1bd887','COLOR'=>$color,'NAME'=>'c'.strval($id),'CONTEXT'=>trim($context))));

	//			break;
			}
		}

		$switch_string=($advanced_mode==1)?do_lang_tempcode('SWITCH_TO_SIMPLE_MODE'):do_lang_tempcode('SWITCH_TO_ADVANCED_MODE');
		$switch_icon=($advanced_mode==1)?'page/simple':'page/advanced';
		$switch_url=build_url(array('page'=>'_SELF','type'=>'edit_css','file'=>$file,'theme'=>$theme,'advanced_mode'=>1-$advanced_mode),'_SELF');

		// Revision history
		$filesarray=$this->get_css_revisions($theme,get_param('file','global.css'));
		rsort($filesarray);

		$i=0;
		$revision_history=new ocp_tempcode();
		$max=intval(get_option('number_revisions_show'));
		$last_path=$path;
		foreach ($filesarray as $time)
		{
			// Find who did the revision
			$editor=$GLOBALS['SITE_DB']->query_value_null_ok('adminlogs','the_user',array('date_and_time'=>$time,'the_type'=>'EDIT_CSS','param_a'=>$theme));
			if (is_null($editor))
			{
				$editor=do_lang('UNKNOWN');
			}
			else
			{
				$editor=$GLOBALS['FORUM_DRIVER']->get_username($editor);
				if (is_null($editor)) $editor=do_lang('UNKNOWN');
			}
			$date=is_null($time)?do_lang('UNKNOWN'):get_timezoned_date(intval($time));
			$url2=get_custom_base_url().'/themes/'.$theme.'/css_custom/'.$file.'.'.$time;
			$old_file=get_custom_file_base().'/themes/'.$theme.'/css_custom/'.$file.'.'.$time;
			$size=filesize($old_file);
			$restore_url=build_url(array('page'=>'_SELF','type'=>'edit_css','file'=>$file,'theme'=>$theme,'restore_from'=>$time),'_SELF');
			require_code('diff');
			if (function_exists('diff_simple'))
			{
				$rendered_diff=diff_simple($old_file,$last_path);
				$last_path=$old_file;
				$revision_history->attach(do_template('REVISION_HISTORY_LINE',array('_GUID'=>'dba0110692775615152be1da850bc1d4','RENDERED_DIFF'=>$rendered_diff,'EDITOR'=>$editor,'DATE'=>$date,'DATE_RAW'=>$time,'RESTORE_URL'=>$restore_url,'URL'=>$url2,'SIZE'=>clean_file_size($size))));
				$i++;
			}

			if ($i==$max) break;
		}
		if (($i!=0) && (get_param('restore_from','')==''))
			$revision_history=do_template('REVISION_HISTORY_WRAP',array('_GUID'=>'330a153101f131ff63445a694aa149c4','CONTENT'=>$revision_history));
		elseif ($i!=0) $revision_history=do_template('REVISION_RESTORE');

		require_code('form_templates');
		list($warning_details,$ping_url)=handle_conflict_resolution($file);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:choose_css:theme='.$theme,do_lang_tempcode('CHOOSE'))));

		return do_template('THEME_EDIT_CSS_SCREEN',array('_GUID'=>'3e34b2f44d7a73202f1bb475fd4ac593','PING_URL'=>$ping_url,'OLD_CONTENTS'=>$old_contents,'WARNING_DETAILS'=>$warning_details,'REVISION_HISTORY'=>$revision_history,'SWITCH_ICON'=>$switch_icon,'SWITCH_STRING'=>$switch_string,'SWITCH_URL'=>$switch_url,'TITLE'=>$title,'THEME'=>$theme,'CSS'=>$css,'URL'=>$url,'FILE'=>$file,'ENTRIES'=>$entries));
	}

	/**
	 * The actualiser to edit a CSS file.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_css()
	{
		$title=get_screen_title('EDIT_CSS');

		$file=filter_naughty(get_param('file','global.css'));

		$css=post_param('css');

		$theme=post_param('theme');
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		$i=0;
		$color=post_param('c'.strval($i),'');
		while ($color!='')
		{
			$css=str_replace('<color-'.strval($i).'>','#'.$color,$css);
			$i++;

			$color=post_param('c'.strval($i),'');
		}

		$custom_path=get_custom_file_base().'/themes/'.filter_naughty($theme).'/css_custom/'.$file;
		$path_backup=$custom_path.'.'.strval(time());
		if (file_exists($custom_path))
		{
			@copy($custom_path,$path_backup) OR intelligent_write_error($custom_path);
			sync_file($path_backup);
		}
		fix_permissions($path_backup);
		$myfile=@fopen($custom_path,'wt');
		if ($myfile===false) intelligent_write_error($custom_path);
		if (fwrite($myfile,$css)<strlen($css))
		{
			fclose($myfile);
			unlink($custom_path);
			warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
		}
		fclose($myfile);
		sync_file($custom_path);

		// Make base-hash-thingy
		$myfile=@fopen($custom_path.'.editfrom','wt');
		if ($myfile===false) intelligent_write_error($custom_path);
		$base_path=get_file_base().'/themes/default/css/'.$file;
		if (is_file($base_path))
		{
			$hash=file_get_contents($base_path);
			if (fwrite($myfile,$hash)<strlen($hash)) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
			fclose($myfile);
			fix_permissions($custom_path.'.editfrom');
			sync_file($custom_path.'.editfrom');
		}

		erase_cached_templates();

		log_it('EDIT_CSS',$theme,$file);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:edit_css:theme='.$theme,do_lang_tempcode('CHOOSE')),array('_SELF:_SELF:_edit_css:file='.$file,do_lang_tempcode('EDIT_CSS'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		if (get_param_integer('save_and_stay',0)==1)
		{
			return inform_screen($title,protect_from_escaping('
				<script type="text/javascript">// <![CDATA[
					window.fauxmodal_alert(\''.addslashes(do_lang('SUCCESS')).'\');
				//]]></script>
			'));
		}

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$theme,'','css',$file);
	}

	/**
	 * Get all the revisions for a CSS file in a certain theme.
	 *
	 * @param  ID_TEXT		The theme to find for
	 * @param  string			The file to find revisions of
	 * @return array			A map of the revisions (file=>timestamp)
	 */
	function get_css_revisions($theme,$find_for)
	{
		$filesarray=array();
		$dir=get_custom_file_base().'/themes/'.filter_naughty($theme).'/css_custom';
		if (!file_exists($dir)) return array();
		$_dir=opendir($dir);

		// Find all the comcode pages
		while (false!==($file=readdir($_dir)))
		{
			if ((substr($file,0,strlen($find_for)+1)==$find_for.'.') && (substr($file,-9)!='.editfrom'))
			{
				$temp=explode('.',$file,3);
				$filesarray[$file]=$temp[2];
			}
		}

		closedir($_dir);
		return $filesarray;
	}

	/**
	 * Get all the templates for a theme (optionally, revisions of a single template).
	 *
	 * @param  ID_TEXT		The theme to search for
	 * @param  string			The file to find revisions of (blank: we're not looking for revisions)
	 * @param  boolean		Just for this theme
	 * @return array			A map of the files (for revisions, file=>timestamp, generally, file=>path)
	 */
	function get_template_files_array($theme,$find_for='',$this_theme_only=false)
	{
		$out=array();
		if (($theme=='default') || (!$this_theme_only))
		{
			$out=array_merge($out,$this->get_template_revisions(get_file_base(),'default/templates',$find_for));
			$out=array_merge($out,$this->get_template_revisions(get_custom_file_base(),'default/templates_custom',$find_for));
		}
		if ($theme!='default')
		{
			$out=array_merge($out,$this->get_template_revisions(get_custom_file_base(),$theme.'/templates',$find_for));
			$out=array_merge($out,$this->get_template_revisions(get_custom_file_base(),$theme.'/templates_custom',$find_for));
		}
		ksort($out);

		return $out;
	}

	/**
	 * Get all the revisions for a template file in a certain directory.
	 *
	 * @param  PATH			The path to search relative to
	 * @param  PATH			The subdirectory to search
	 * @param  string			The file to find revisions of
	 * @return array			A map of the revisions (file=>timestamp)
	 */
	function get_template_revisions($base_dir,$subdir,$find_for)
	{
		$_dir=@opendir($base_dir.'/themes/'.$subdir);
		if ($_dir!==false)
		{
			// Find all the themes
			$filesarray=array();
			while (false!==($file=readdir($_dir)))
			{
				if ($find_for=='')
				{
					if (strtolower(substr($file,-4,4))=='.tpl')
					{
						$filesarray[$file]=$subdir.'/'.$file;
					}
				}
				else
				{
					//$current=$subdir.'/'.$file;
					if ((substr($file,0,strlen($find_for)+1)==$find_for.'.') && (substr($file,-9)!='.editfrom'))
					//if (substr($current,0,strlen($find_for)+1)==$find_for.'.')
					{
						$temp=explode('.',$file,3);
						if (is_numeric($temp[2])) $filesarray[$file]=intval($temp[2]);
					}
				}
			}
			closedir($_dir);
			return $filesarray;
		}
		return array();
	}

	/**
	 * The UI to choose a template to edit.
	 *
	 * @return tempcode		The UI
	 */
	function edit_templates()
	{
		$title=get_screen_title('EDIT_TEMPLATES');

		$GLOBALS['HELPER_PANEL_TUTORIAL']='tut_markup';
		$GLOBALS['HELPER_PANEL_TEXT']=comcode_lang_string('DOC_TEMPLATES');

		require_javascript('javascript_ajax');

		$theme=get_param('theme','');
		if ($theme=='') return $this->choose_theme($title);
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		$filesarray=$this->get_template_files_array($theme);
		require_code('form_templates');
		$temp=form_input_list_entry('',false,do_lang_tempcode('NA_EM'));
		$files='';
		$files_tmp='';
		$stub='';
		foreach ($filesarray as $file)
		{
			if ((!is_null($GLOBALS['CURRENT_SHARE_USER'])) && (strpos($file,'BANNER_TYPED')!==false)) continue;

			$new_stub=dirname($file);
			if ($stub!=$new_stub)
			{
				if ($files_tmp!='')
				{
					$temp=form_input_list_group($new_stub,make_string_tempcode($files_tmp));
					$files.=$temp->evaluate(); // XHTMLXHTML
				}
				$files_tmp='';
				$stub=$new_stub;
			}
			$_file=substr($file,strrpos($file,'/')+1);
			$temp=form_input_list_entry($_file,false,/*'- '.*/basename($file));
			$files_tmp.=$temp->evaluate(); // XHTMLXHTML
		}
		$temp=form_input_list_group($new_stub,make_string_tempcode($files_tmp));
		$files.=$temp->evaluate(); // XHTMLXHTML
		$fields=new ocp_tempcode();

		$set_name='template';
		$required=true;
		$set_title=do_lang_tempcode('TEMPLATE');
		$field_set=alternate_fields_set__start($set_name);

		$field_set->attach(form_input_multi_list(do_lang_tempcode('EXISTING'),'','f0file',make_string_tempcode($files),NULL,35));

		$field_set->attach(form_input_line(do_lang_tempcode('SEARCH'),do_lang_tempcode('DESCRIPTION_TEMPLATES_SEARCH'),'search','',false));

		$field_set->attach(form_input_codename(do_lang_tempcode('NEW'),do_lang_tempcode('NEW_TEMPLATE'),'f0file2','',false));

		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));

		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_templates','theme'=>$theme),'_SELF');
		$edit_form=do_template('FORM',array('_GUID'=>'b26747b4a29281baf83b31167c63582a','GET'=>true,'HIDDEN'=>'','TEXT'=>'','URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>do_lang_tempcode('CHOOSE')));

		list($warning_details,$ping_url)=handle_conflict_resolution(''); // Intentionally blank, because only one person should edit any of all templates at any time (because they depend on each other)

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('CHOOSE'));

		return do_template('TEMPLATE_MANAGE_SCREEN',array('_GUID'=>'529cd009f85a84f60b7934b5e969c55b','THEME'=>$theme,'PING_URL'=>$ping_url,'WARNING_DETAILS'=>$warning_details,'TITLE'=>$title,'EDIT_FORM'=>$edit_form));
	}

	/**
	 * The UI to edit a template.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_templates()
	{
		$theme=get_param('theme');
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		$title=get_screen_title('EDIT_TEMPLATES');

		$GLOBALS['HELPER_PANEL_TEXT']=comcode_lang_string('DOC_MARKUP');
		$GLOBALS['HELPER_PANEL_TUTORIAL']='tut_themes';

		// Searching for something, which will provide links that loop back to the proper version of this page
		$search=get_param('search','',true);
		if ($search!='')
		{
			$filesarray=$this->get_template_files_array($theme);
			$results=new ocp_tempcode();
			foreach ($filesarray as $file)
			{
				$full_path=((strpos($file,'/default/templates/')!==false)?get_file_base():get_custom_file_base()).'/themes/'.$file;
				$contents=file_get_contents($full_path);
				if ((strpos(strtolower($contents),strtolower($search))!==false) || (strpos(strtolower($file),strtolower($search))!==false))
				{
					$_url=build_url(array('page'=>'_SELF','type'=>'_edit_templates','theme'=>$theme,'f0file'=>$file),'_SELF');
					$results->attach(do_template('INDEX_SCREEN_ENTRY',array('_GUID'=>'ed744a45728f3d7c1082a3dda893f352','URL'=>$_url,'NAME'=>$file)));
				}
			}
			return do_template('INDEX_SCREEN',array('_GUID'=>'286a7ae3add44f935a9a2018dde3ccaf','TITLE'=>$title,'PRE'=>do_lang_tempcode('_RESULTS'),'POST'=>'','CONTENT'=>$results));
		}

		require_javascript('javascript_editing');

		$post_url=build_url(array('page'=>'_SELF','type'=>'__edit_templates'),'_SELF');
		$preview_url=get_param('preview_url','');

		// We support multi-list for getting here, so f0file can be an array, in which case we change that
		if (array_key_exists('f0file',$_GET))
		{
			if (is_array($_GET['f0file']))
			{
				foreach ($_GET['f0file'] as $i=>$f)
				{
					$_GET['f'.strval($i).'file']=$f;
				}
			}
		}

		$template_editors=new ocp_tempcode();
		$templates=array();

		$files_seen=array();

		if (get_option('editarea')=='1')
		{
			$GLOBALS['EXTRA_HEAD']->attach(make_string_tempcode('
				<script language="javascript" type="text/javascript" src="'.get_base_url().'/data/editarea/edit_area_full.js"></script>
			'));
		}

		$count=0;
		$first_id='';
		foreach (array_keys($_GET) as $_i)
		{
			$matches=array();
			if (preg_match('#f(\d+)file#',$_i,$matches)!=0)
			{
				$i=$matches[1];
			} else continue;

			// The file we're editing
			$file=filter_naughty(get_param('f'.$i.'file',''));
			if ($file=='')
			{
				$file=filter_naughty(get_param('f'.$i.'file2',''));
			}
			if ($file=='') continue;
			if ((substr($file,-4)!='.tpl') && (substr($file,-4)!='.css')) $file.='.tpl';

			if (get_param('preview_url','')=='')
			{
				if ((substr($file,-4)!='.tpl') && (substr($file,-4)!='.css')) $file.='.tpl';
				require_code('lorem');
				$all_previews=find_all_previews__by_template();
				if (array_key_exists(basename($file),$all_previews))
				{
					$_preview_url=build_url(array('page'=>'_SELF','type'=>'view','id'=>basename($file),'hook'=>$all_previews[basename($file)][0],'function'=>$all_previews[basename($file)][1],'arg'=>'','keep_theme'=>$theme,'keep_wide_high'=>1),'_SELF');
					$preview_url=$_preview_url->evaluate();
				}
			}

			if (in_array($file,$files_seen)) continue;
			$files_seen[]=$file;
			if ((!is_null($GLOBALS['CURRENT_SHARE_USER'])) && (strpos($file,'BANNER_TYPED')!==false)) warn_exit(do_lang_tempcode('INTERNAL_ERROR'));
			if ($file[0]=='!') warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD'));

			$syntax='html';
			if (substr($file,-4)=='.css') $syntax='css';
			elseif (substr($file,0,11)=='JAVASCRIPT_') $syntax='js';

			if (get_option('editarea')=='1')
			{
				$GLOBALS['EXTRA_HEAD']->attach('
					<script type="text/javascript">// <![CDATA[
					editAreaLoader.init({
						id : "f'.$i.'_new"
						,syntax: "'.$syntax.'"
						,start_highlight: true
						,language: "'.(file_exists(get_file_base().'/data/editarea/langs/'.strtolower(user_lang()))?strtolower(user_lang()):'en').'"
						,allow_resize: true
						,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, reset_highlight, word_wrap"
					});
					//]]></script>
				');
			}

			// Support searching
			if (strpos($file,'/')===false)
			{
				$codename=$file;
				if (substr($file,-4)=='.css')
				{
					$file=$theme.'/css_custom/'.$codename;
					if (!file_exists(get_custom_file_base().'/themes/'.$file)) $file='default/css_custom/'.$codename;
					if (!file_exists(get_custom_file_base().'/themes/'.$file)) $file='default/css/'.$codename;
				} else
				{
					$file=$theme.'/templates_custom/'.$codename;
					if (!file_exists(get_custom_file_base().'/themes/'.$file)) $file=$theme.'/templates/'.$codename;
					if (!file_exists(get_custom_file_base().'/themes/'.$file)) $file='default/templates_custom/'.$codename;
					if (!file_exists(get_custom_file_base().'/themes/'.$file)) $file='default/templates/'.$codename;
				}
			} else $codename=basename($file);

			// The file we're LOADING from for edit (maybe $file, maybe some old versions being restored)
			$restore_from=filter_naughty(get_param('restore_from',$file));
			if (file_exists(get_file_base().'/themes/'.$restore_from))
			{
				$path=get_file_base().'/themes/'.$restore_from;
				$contents=file_get_contents($path);
				$last_path=$path;
			}
			elseif (file_exists(get_custom_file_base().'/themes/'.$restore_from))
			{
				$path=get_custom_file_base().'/themes/'.$restore_from;
				$contents=file_get_contents($path);
				$last_path=$path;
			} else
			{
				$contents='';
				$last_path=NULL;
			}

			// Revision history
			$filesarray=$this->get_template_files_array($theme,basename($file),true);
			rsort($filesarray);
			$j=0;
			$revision_history=new ocp_tempcode();
			$max=intval(get_option('number_revisions_show'));
			foreach ($filesarray as $time)
			{
				// Find who did the revision
				$editor=$GLOBALS['SITE_DB']->query_value_null_ok('adminlogs','the_user',array('date_and_time'=>$time,'the_type'=>'EDIT_TEMPLATES','param_a'=>$file));
				if (is_null($editor))
				{
					$editor=do_lang('UNKNOWN');
				}
				else
				{
					$editor=$GLOBALS['FORUM_DRIVER']->get_username($editor);
					if (is_null($editor)) $editor=do_lang('UNKNOWN');
				}
				$date=is_null($time)?do_lang('UNKNOWN'):get_timezoned_date($time);
				$url=get_custom_base_url().'/themes/'.str_replace('templates/','templates_custom/',$file).'.'.strval($time);
				$old_file=get_custom_file_base().'/themes/'.str_replace('templates/','templates_custom/',$file).'.'.strval($time);
				if (!file_exists($old_file)) // Probably restoring the default theme file into our custom theme
				{
					$url=get_custom_base_url().'/themes/'.str_replace('default/',$theme.'/',str_replace('templates/','templates_custom/',$file)).'.'.strval($time);
					$old_file=get_custom_file_base().'/themes/'.str_replace('default/',$theme.'/',str_replace('templates/','templates_custom/',$file)).'.'.strval($time);
				}
				$size=filesize($old_file);
				$restore_url=build_url(array('page'=>'_SELF','type'=>'_edit_templates','theme'=>$theme,'f0file'=>basename($file),'restore_from'=>str_replace('templates/','templates_custom/',$file).'.'.strval($time)),'_SELF');
				require_code('diff');
				if (function_exists('diff_simple'))
				{
					$rendered_diff=is_null($last_path)?'':diff_simple($old_file,$last_path);
					$last_path=$old_file;
					$revision_history->attach(do_template('REVISION_HISTORY_LINE',array('_GUID'=>'f0cb02bfa3692ed431b69b8d9dc0b2f8','RENDERED_DIFF'=>$rendered_diff,'EDITOR'=>$editor,'DATE'=>$date,'DATE_RAW'=>strval($time),'RESTORE_URL'=>$restore_url,'URL'=>$url,'SIZE'=>clean_file_size($size))));
					$j++;
				}

				if ($j==$max) break;
			}
			$orig_version=str_replace('/templates_custom/','/templates/',$file);
			$orig_version=str_replace('/css_custom/','/css/',$orig_version);
			if (!file_exists(get_file_base().'/themes/'.$orig_version))
			{
				$orig_version='default'.substr($orig_version,strpos($orig_version,'/'));
			}
			if (((strpos($file,'/templates_custom/')!==false) || (strpos($file,'/css_custom/')!==false)) && (file_exists(get_file_base().'/themes/'.$orig_version)))
			{
				$restore_url=build_url(array('page'=>'_SELF','type'=>'_edit_templates','theme'=>$theme,'f0file'=>basename($file),'restore_from'=>$orig_version),'_SELF');
				$url=get_base_url().'/themes/'.$orig_version;
				$date=do_lang_tempcode('ORIGINAL_EM');
				$size=filesize(get_custom_file_base().'/themes/'.$file);
				$editor=do_lang('UNKNOWN');
				require_code('diff');
				if (function_exists('diff_simple'))
				{
					$rendered_diff=diff_simple(get_custom_file_base().'/themes/'.$file,$last_path);
					$revision_history->attach(do_template('REVISION_HISTORY_LINE',array('_GUID'=>'7ba03fe98a20330fc64ad742d2fb74fa','RENDERED_DIFF'=>$rendered_diff,'EDITOR'=>$editor,'DATE'=>$date,'DATE_RAW'=>'0','RESTORE_URL'=>$restore_url,'URL'=>$url,'SIZE'=>clean_file_size($size))));
					$j++;
				}
			}
			if (($j!=0) && (get_param('restore_from','')==''))
				$revision_history=do_template('REVISION_HISTORY_WRAP',array('_GUID'=>'435e050dd2f38187d757e792ceb2f2f5','CONTENT'=>$revision_history));
			elseif ($j!=0) $revision_history=do_template('REVISION_RESTORE');

			$_file=substr($file,strrpos($file,'/')+1);
			if (substr($_file,-4)=='.css')
			{
				$old_contents=@file_get_contents(get_file_base().'/themes/default/css/'.$_file);
			} else
			{
				$old_contents=@file_get_contents(get_file_base().'/themes/default/templates/'.$_file);
			}
			if ($old_contents===false) $old_contents='';

			$matches=array();
			$cnt=preg_match_all('#\{([\w][\w\_]*)\}#',$old_contents,$matches);
			$parameters=new ocp_tempcode();
			$p_done=array();
			for ($j=0;$j<$cnt;$j++)
			{
				if (array_key_exists($matches[1][$j],$p_done)) continue;
				$p_done[$matches[1][$j]]=1;
				$parameters->attach(form_input_list_entry($matches[1][$j].'__0',false,$matches[1][$j]));
			}
			$parameters=do_template('TEMPLATE_EDIT_SCREEN_DROPDOWN',array('_GUID'=>'50f31c49c99b864c1719fb51ed426274','ID'=>$i,'PARAMETERS'=>$parameters,'NAME'=>'ppparameter','LANG'=>do_lang_tempcode('INSERT_PARAMETER')));

			$_directives=array(
											array('BOX','1'),
											array('WHILE','1'),
											array('IF_NON_EMPTY','1'),
											array('IF_EMPTY','1'),
											array('IF','1'),
											array('IF_ADJACENT','1'),
											array('SET','1'),
											array('LOOP','1'), // To simplify things, we won't throw all options at the user
									);
			$directives=$this->generate_from($_directives,'DIRECTIVE',$i);

			$_programmatic_symbols=array(
											array('RAND','0'),
											array('SET_RAND','0+'),
											array('CYCLE','1+'),
											array('INIT','1'),
											array('SET','2'),
											array('GET','1'),
											array('INC','1'),
											array('DEC','1'),
											);
			$programmatic_symbols=$this->generate_from($_programmatic_symbols,'PROGRAMMATIC_SYMBOL',$i);

			$_abstraction_symbols=array(
											array('IMG','1'),
											array('PAGE_LINK','1'),
											array('MAILTO','0'),
											array('BLOCK','2'),
											array('THUMBNAIL','2'),
											array('LOAD_PAGE','1'),
											array('LOAD_PANEL','1'),
											);
			$abstraction_symbols=$this->generate_from($_abstraction_symbols,'ABSTRACTION_SYMBOL',$i);

			$_symbols=array(
											array('THEME','0'),
											array('LANG','0'),
											array('BASE_URL','0'),
											array('MOBILE','0'),
											array('SITE_NAME','0'),
											array('STAFF_ADDRESS','0'),
											array('USER','0'),
											array('DATE_AND_TIME','0'),
											array('DATE','0'),
											array('TIME','0'),
											array('USERNAME','0-1'),
											array('IS_STAFF','0'),
											array('MATCH_KEY_MATCH','1'),
											);
			$symbols=$this->generate_from($_symbols,'SYMBOL',$i);

			$_arithmetical_symbols=array(
											array('MAX','2'),
											array('MIN','2'),
											array('REM','2'),
											array('DIV','2'),
											array('SUBTRACT','2'),
											array('ADD','2'),
											array('ROUND','2'),
											array('MULT','2'),
											);
			$arithmetical_symbols=$this->generate_from($_arithmetical_symbols,'ARITHMETICAL_SYMBOL',$i);

			$_formatting_symbols=array(
											array('WCASE','1'),
											array('LCASE','1'),
											array('UCASE','1'),
											array('REPLACE','3'),
											array('AT','2'),
											array('SUBSTR','3'),
											array('LENGTH','1'),
											array('WORDWRAP','2'),
											array('TRUNCATE_LEFT','2'),
											array('TRUNCATE_SPREAD','2'),
											);
			$formatting_symbols=$this->generate_from($_formatting_symbols,'FORMATTING_SYMBOL',$i);

			$_logical_symbols=array(
											array('NOT','1'),
											array('OR','2'),
											array('AND','2'),
											array('EQ','2'),
											array('NEQ','2'),
											array('LT','2'),
											array('GT','2'),
											);
			$logical_symbols=$this->generate_from($_logical_symbols,'LOGICAL_SYMBOL',$i);

			$guid=get_param('f'.$i.'guid','?');
			if ($guid=='?') $guid='';

			$guids=array();
			$file_bits=explode('/',$file);
			$clean_file=str_replace('.tpl','',$file_bits[count($file_bits)-1]);
			$_guids=@unserialize(@file_get_contents(get_file_base().'/data/guids.dat'));
			if (($_guids!==false) && (array_key_exists($clean_file,$_guids)))
			{
				foreach ($_guids[$clean_file] as $_guid)
				{
					$guids[]=array('FILENAME'=>$_guid[0],'LINE'=>integer_format($_guid[1]),'THIS_GUID'=>$_guid[2]);
				}
			}

			$templates[]=array('I'=>$i,'FILE'=>$file);

			$display=($count==0)?'block':'none';
			if ($count==0) $first_id=$i;
			$template_editors->attach(do_template('TEMPLATE_EDIT_SCREEN_EDITOR',array(
				'_GUID'=>'9d3b75215c34c2b4b366118605b4cd59',
				'PREVIEW_URL'=>$preview_url,
				'CODENAME'=>str_replace('.tpl','',$codename),
				'I'=>$i,
				'DISPLAY'=>$display,
				'GUIDS'=>$guids,
				'GUID'=>$guid,
				'ARITHMETICAL_SYMBOLS'=>$arithmetical_symbols,
				'FORMATTING_SYMBOLS'=>$formatting_symbols,
				'LOGICAL_SYMBOLS'=>$logical_symbols,
				'ABSTRACTION_SYMBOLS'=>$abstraction_symbols,
				'PARAMETERS'=>$parameters,
				'DIRECTIVES'=>$directives,
				'PROGRAMMATIC_SYMBOLS'=>$programmatic_symbols,
				'SYMBOLS'=>$symbols,
				'FILE'=>$file,
				'FILE_SAVE_TARGET'=>str_replace('default/',$theme.'/',$file),
				'OLD_CONTENTS'=>$old_contents,
				'CONTENTS'=>$contents,
				'REVISION_HISTORY'=>$revision_history
			)));

			$count++;
		}

		if ($count==1)
		{
			$GLOBALS['SEO_TITLE']=$files_seen[0];
		}

		if ($template_editors->is_empty()) warn_exit(do_lang_tempcode('NO_TEMPLATES_SELECTED'));

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:edit_templates:theme='.$theme,do_lang_tempcode('CHOOSE'))));

		return do_template('TEMPLATE_EDIT_SCREEN',array('_GUID'=>'cbcd6d18c2456f94f72624e1a39a36a5','MULTIPLE'=>$count>1,'FIRST_ID'=>$first_id,'THEME'=>$theme,'TEMPLATES'=>$templates,'TITLE'=>$title,'URL'=>$post_url,'TEMPLATE_EDITORS'=>$template_editors));
	}

	/**
	 * Helper function to get tempcode for insertion of symbols.
	 *
	 * @param  array			A list of pairs (symbol name,arity)
	 * @param  string			The "stub" that determines what language codes to lookup for the given symbols, and generally, the collective naming strategy
	 * @param  string			The ID of the actual template editor we are working with
	 * @return tempcode		The tempcode
	 */
	function generate_from($array,$stub,$id)
	{
		$out=new ocp_tempcode();
		foreach ($array as $x)
		{
			list($op,$arity)=$x;
			$lang=do_lang_tempcode($stub.'__'.$op);
			$out->attach(form_input_list_entry($op.'__'.$arity,false,$lang));
		}
		return do_template('TEMPLATE_EDIT_SCREEN_DROPDOWN',array('_GUID'=>'c6d24f278ec874a4b6abff8c359f80ba','ID'=>$id,'PARAMETERS'=>$out,'NAME'=>'pp'.strtolower($stub),'LANG'=>do_lang_tempcode('INSERT_'.$stub)));
	}

	/**
	 * The actualiser to edit a template. Always saves to the most overridden version.
	 *
	 * @return tempcode		The UI
	 */
	function __edit_templates()
	{
		// Erase cache
		$theme=filter_naughty(post_param('theme'));
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
		erase_cached_templates();
		require_code('view_modes');
		erase_tempcode_cache();

		$title=get_screen_title('EDIT_TEMPLATES');

		foreach (array_keys($_REQUEST) as $_i)
		{
			$matches=array();
			if (preg_match('#f(\d+)file#',$_i,$matches)!=0)
			{
				$i=$matches[1];
			} else continue;

			$_file=substr(str_replace('/default/','/'.$theme.'/','/'.filter_naughty(post_param('f'.$i.'file',''))),1);
			if ($_file=='') continue;

			if ((!is_null($GLOBALS['CURRENT_SHARE_USER'])) && (strpos($_file,'BANNER_TYPED')!==false)) warn_exit(do_lang_tempcode('INTERNAL_ERROR'));

			$file=str_replace('templates/','templates_custom/',$_file);
			$file=str_replace('css/','css_custom/',$file);
			$fullpath=get_custom_file_base().'/themes/'.$file;

			// Make backup
			if ((file_exists($fullpath)) && (get_option('templates_store_revisions')=='1'))
			{
				@copy($fullpath,$fullpath.'.'.strval(time())) OR intelligent_write_error($fullpath.'.'.strval(time()));
				fix_permissions($fullpath.'.'.strval(time()));
				sync_file($fullpath.'.'.strval(time()));
			}

			// Save
			$new=post_param('f'.$i.'_new',false,true);
			$fullpath_orig=preg_replace('#/themes/[^/]*/(.*)(\_custom)?/#U','/themes/default/${1}/',$fullpath);
			if ((file_exists($fullpath_orig)) && ($new==file_get_contents($fullpath_orig)))
			{
				if (file_exists($fullpath))
				{
					unlink($fullpath);
					sync_file($fullpath);
				}
				if (file_exists($fullpath.'.editfrom'))
				{
					unlink($fullpath.'.editfrom');
					sync_file($fullpath.'.editfrom');
				}
				$_file=preg_replace('#[^/]*/(.*)(\_custom)?/#U','default/${1}/',$_file);

				$file=$_file;
			} else
			{
				$myfile=@fopen($fullpath,'wt');
				if ($myfile===false) intelligent_write_error($fullpath);
				if (fwrite($myfile,$new)<strlen($new))
				{
					fclose($myfile);
					unlink($fullpath);
					warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
				}
				fclose($myfile);
				fix_permissions($fullpath);
				sync_file($fullpath);

				if (file_exists(get_file_base().'/themes/'.post_param('f'.$i.'file')))
				{
					// Make base-hash-thingy
					$myfile=@fopen($fullpath.'.editfrom','wt');
					if ($myfile===false) intelligent_write_error($fullpath);
					$hash=file_get_contents(get_file_base().'/themes/'.post_param('f'.$i.'file'));
					if (fwrite($myfile,$hash)<strlen($hash)) warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE'));
					fclose($myfile);
					fix_permissions($fullpath.'.editfrom');
					sync_file($fullpath.'.editfrom');
				}
			}
			log_it('EDIT_TEMPLATES',$file,$theme);
		}

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:edit_templates:theme='.$theme,do_lang_tempcode('CHOOSE')),array('_SELF:_SELF:_edit_templates:theme='.$theme.':file='.$file,do_lang_tempcode('EDIT_TEMPLATES'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		if (get_param_integer('save_and_stay',0)==1)
		{
			return inform_screen($title,protect_from_escaping('
				<script type="text/javascript">// <![CDATA[
					window.fauxmodal_alert(\''.addslashes(do_lang('SUCCESS')).'\');
				//]]></script>
			'));
		}

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$theme,'','templates',$file);
	}

	/**
	 * Get tempcode for a theme image adding/editing form.
	 *
	 * @param  ID_TEXT			The theme the theme image is in
	 * @param  LANGUAGE_NAME	The language the theme image is for
	 * @param  SHORT_TEXT		The theme image ID
	 * @param  URLPATH			The URL to the theme image
	 * @return array				A pair: the tempcode for the visible fields, and the tempcode for the hidden fields
	 */
	function get_image_form_fields($theme,$lang,$id='',$path='')
	{
		$fields=new ocp_tempcode();
		$hidden=new ocp_tempcode();
		require_code('form_templates');
		$hidden->attach(form_input_hidden('theme',$theme));
		$hidden->attach(form_input_hidden('lang',$lang));
		$fields->attach(form_input_line(do_lang_tempcode('CODENAME'),do_lang_tempcode('DESCRIPTION_THEME_IMAGE_NAME'),'id',$id,true));
	/*	
		$list=combo_get_image_paths($path,get_base_url().'/themes/'.rawurlencode($theme).'/images/',get_file_base().'/themes/'.filter_naughty($theme).'/images/');
		$list->attach(combo_get_image_paths($path,get_base_url().'/themes/'.rawurlencode($theme).'/images_custom/',get_file_base().'/themes/'.filter_naughty($theme).'/images_custom/'));
		if ($theme!='default')
		{
			$list->attach(combo_get_image_paths($path,get_base_url().'/themes/default/images/',get_file_base().'/themes/default/images/'));
			$list->attach(combo_get_image_paths($path,get_base_url().'/themes/default/images_custom/',get_file_base().'/themes/default/images_custom/'));
		}*/
		handle_max_file_size($hidden,'image');

		$set_name='image';
		$required=true;
		$set_title=do_lang_tempcode('IMAGE');
		$field_set=alternate_fields_set__start($set_name);

		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
	//	$fields->attach(form_input_radio(do_lang_tempcode('CHOOSE'),'',$list));

		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','path',$path,false));

		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));

		return array($fields,$hidden);
	}

	/**
	 * The UI to add a theme image.
	 *
	 * @return tempcode		The UI
	 */
	function add_image()
	{
		$title=get_screen_title('ADD_THEME_IMAGE');

		$theme=get_param('theme');
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
		$lang=get_param('lang',user_lang());
		if ($lang=='') $lang=user_lang();
		list($fields,$hidden)=$this->get_image_form_fields($theme,$lang);
		$fields->attach(form_input_tick(do_lang_tempcode('USE_ALL_THEMES'),do_lang_tempcode('DESCRIPTION_USE_ALL_THEMES'),'use_all_themes',false));
		$fields->attach(form_input_tick(do_lang_tempcode('USE_ALL_LANGS'),do_lang_tempcode('DESCRIPTION_USE_ALL_LANGS'),'use_all_langs',true));

		$post_url=build_url(array('page'=>'_SELF','type'=>'_add_image','uploading'=>1),'_SELF');
		$submit_name=do_lang_tempcode('ADD_THEME_IMAGE');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES'))));

		$text=new ocp_tempcode();
		require_code('images');
		$max=floatval(get_max_image_size())/floatval(1024*1024);
		if ($max<3.0)
		{
			require_code('files2');
			$config_url=get_upload_limit_config_url();
			$text->attach(paragraph(do_lang_tempcode(is_null($config_url)?'MAXIMUM_UPLOAD':'MAXIMUM_UPLOAD_STAFF',escape_html(($max>10.0)?integer_format(intval($max)):float_format($max)),escape_html($config_url))));
		}

		return do_template('FORM_SCREEN',array('_GUID'=>'7b8066b63002cda0a7628ddadddd9962','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to add a theme image.
	 *
	 * @return tempcode		The UI
	 */
	function _add_image()
	{
		require_code('uploads');

		$title=get_screen_title('ADD_THEME_IMAGE');

		$theme=post_param('theme');
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
		$lang=post_param('lang');
		$id=post_param('id');
		$use_all_themes=post_param_integer('use_all_themes',0);
		$use_all_langs=post_param_integer('use_all_langs',0);

		$path=get_url('path','file','themes/'.(($use_all_themes==1)?'default':$theme).'/images_custom');
		if ($path[0]=='') return warn_screen($title,do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD'));

		$theme_list=array_keys(find_all_themes());
		$lang_list=find_all_langs(true);

		if (($use_all_themes==1) && ($use_all_langs==1))
			foreach ($theme_list as $theme)
				foreach (array_keys($lang_list) as $lang)
					actual_add_theme_image($theme,$lang,$id,$path[0],true);
		elseif ($use_all_themes==1)
			foreach ($theme_list as $theme)
				actual_add_theme_image($theme,$lang,$id,$path[0],true);
		elseif ($use_all_langs==1)
			foreach (array_keys($lang_list) as $lang)
				actual_add_theme_image($theme,$lang,$id,$path[0],true);
		else actual_add_theme_image($theme,$lang,$id,$path[0]);

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:add_image:theme='.post_param('theme'),do_lang_tempcode('CHOOSE'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		persistent_cache_delete('THEME_IMAGES');
		erase_cached_templates();

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$theme,$lang,'image',$id);
	}

	/**
	 * The UI to select a theme image to edit.
	 *
	 * @return tempcode		The UI
	 */
	function manage_images()
	{
		$title=get_screen_title('MANAGE_THEME_IMAGES');

		if (function_exists('set_time_limit')) @set_time_limit(300);

		$lang=choose_language($title,true,true);
		if (is_object($lang)) return $lang;

		$theme=get_param('theme','');
		if ($theme=='') return $this->choose_theme($title,true);
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));

		require_code('themes3');
		regen_theme_images($theme);
		if ($theme!='default') regen_theme_images('default',NULL,$theme);

		// Choose image to edit
		require_code('form_templates');
		/*$where_map=array('theme'=>$theme);
		if ($lang!='') $where_map['lang']=$lang;
		$images=$GLOBALS['SITE_DB']->query_select('theme_images',array('DISTINCT id'),$where_map);
		$list='';
		foreach ($images as $row)
		{
			$temp=form_input_list_entry($row['id'],false);
			$list.=$temp->evaluate(); // XHTMLXHTML
		}
		$fields=form_input_huge_list(do_lang_tempcode('CODENAME'),'','id',make_string_tempcode($list),NULL,true,true,725);*/
		require_code('themes2');
		$ids=get_all_image_ids_type('',true,$GLOBALS['SITE_DB'],$theme);
		$fields=form_input_theme_image(do_lang_tempcode('CODENAME'),'','id',$ids,NULL,NULL,NULL,false,NULL,$theme,$lang,true,true);
		$hidden=form_input_hidden('theme',$theme);
		$post_url=build_url(array('page'=>'_SELF','type'=>'edit_image','lang'=>$lang),'_SELF');
		$edit_form=do_template('FORM',array('_GUID'=>'48b3218750fcea21e0bf3be31ae58296','HIDDEN'=>$hidden,'TEXT'=>do_lang_tempcode('CHOOSE_EDIT_LIST'),'GET'=>true,'URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>do_lang_tempcode('CHOOSE')));

		$add_url=build_url(array('page'=>'_SELF','type'=>'add_image','theme'=>$theme,'lang'=>$lang),'_SELF');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES'))));
		breadcrumb_set_self(do_lang_tempcode('CHOOSE'));

		return do_template('THEME_IMAGE_MANAGE_SCREEN',array('_GUID'=>'4e760b0aa59b1bbb6fcf289c0b93ec46','ADD_URL'=>$add_url,'TITLE'=>$title,'FORM'=>$edit_form));
	}

	/**
	 * The UI to edit a theme image.
	 *
	 * @return tempcode		The UI
	 */
	function edit_image()
	{
		$title=get_screen_title('EDIT_THEME_IMAGE');

		$lang=choose_language($title,true,true);
		if (is_object($lang)) return $lang;

		$url=get_param('url','');
		if ($url!='')
		{
			$url=preg_replace('#\.pagespeed\..*$#','',$url); // Support for working around https://developers.google.com/speed/docs/mod_pagespeed/filter-cache-extend

			$theme=get_param('theme',''); // Editing like this happens in the theme the user is using
			if ($theme=='') $theme=$GLOBALS['FORUM_DRIVER']->get_theme('');
			if (substr($url,0,strlen(get_base_url()))==get_base_url()) $url=substr($url,strlen(get_base_url()));
			$pos=strpos($url,'themes/');
			if ($pos===false) warn_exit(do_lang_tempcode('NOT_THEME_IMAGE'));
			$path=substr($url,$pos);
			$id=$GLOBALS['SITE_DB']->query_value_null_ok('theme_images','id',array('path'=>$path,'theme'=>$theme));
			if (is_null($id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
		} else
		{
			$id=get_param('id');
			$theme=get_param('theme');
		}
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
		$where_map=array('theme'=>$theme,'id'=>$id);
		if ($lang!='') $where_map['lang']=$lang;
		$path=$GLOBALS['SITE_DB']->query_value_null_ok('theme_images','path',$where_map);
		if (is_null($path)) $path=$GLOBALS['SITE_DB']->query_value_null_ok('theme_images','path',array('theme'=>$theme,'lang'=>get_site_default_lang(),'id'=>$id));
		if (is_null($path)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));

		$GLOBALS['SEO_TITLE']=$id;

		$unmodified=(strpos($path,'themes/default/images/')!==false);

		$from_file=@file_get_contents(($unmodified?get_file_base():get_custom_file_base()).'/'.rawurldecode($path));
		$width=do_lang_tempcode('UNKNOWN_EM');
		$height=do_lang_tempcode('UNKNOWN_EM');
		if (($from_file!==false) && (function_exists('imagecreatefromstring')))
		{
			$source=@imagecreatefromstring($from_file);
			unset($from_file);
			if ($source!==false)
			{
				$width=make_string_tempcode(strval(imagesx($source)));
				$height=make_string_tempcode(strval(imagesy($source)));
				imagedestroy($source);
			}
		}

		$url=($unmodified?get_base_url():get_custom_base_url()).'/'.$path;
		$text=do_template('THEME_IMAGE_PREVIEW',array('_GUID'=>'c71817851526064e738d5076dcd1bce1','WIDTH'=>$width,'HEIGHT'=>$height,'URL'=>$url,'UNMODIFIED'=>$unmodified));

		list($fields,$hidden)=$this->get_image_form_fields($theme,$lang,$id,$path);
		$hidden->attach(form_input_hidden('old_id',$id));
		if (strpos($path,'images_custom')!==false)
		{
			$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
			$fields->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE_THEME_IMAGE'),'delete',false));
		}

		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_image','uploading'=>1),'_SELF',NULL,false,true);
		$submit_name=do_lang_tempcode('SAVE');

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:manage_images:theme='.$theme,do_lang_tempcode('CHOOSE'))));

		require_code('images');
		$max=floatval(get_max_image_size())/floatval(1024*1024);
		if ($max<3.0)
		{
			require_code('files2');
			$config_url=get_upload_limit_config_url();
			$text->attach(paragraph(do_lang_tempcode(is_null($config_url)?'MAXIMUM_UPLOAD':'MAXIMUM_UPLOAD_STAFF',escape_html(($max>10.0)?integer_format(intval($max)):float_format($max)),escape_html($config_url))));
		}

		return do_template('FORM_SCREEN',array('_GUID'=>'b0e178ad1f840a07c4967f3c266c750b','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name));
	}

	/**
	 * The actualiser to edit a theme image.
	 *
	 * @return tempcode		The UI
	 */
	function _edit_image()
	{
		require_code('uploads');

		$title=get_screen_title('EDIT_THEME_IMAGE');

		$lang=choose_language($title,true,true);
		if (is_object($lang)) return $lang;

		$theme=post_param('theme');
		//if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
		$id=post_param('id');
		$old_id=post_param('old_id');

		if (post_param_integer('delete',0)==1)
		{
			require_code('themes3');
			actual_delete_theme_image($old_id,$theme,$lang);
		} else
		{
			$path=get_url('path','file','themes/'.$theme.'/images_custom');

			if ((url_is_local($path[0])) && (!file_exists(((substr($path[0],0,15)=='themes/default/')?get_file_base():get_custom_file_base()).'/'.rawurldecode($path[0]))))
				warn_screen($title,do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD'));

			if ($path[0]=='') return warn_screen($title,do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD'));
			actual_edit_theme_image($old_id,$theme,$lang,$id,$path[0]);
		}
		persistent_cache_delete('THEME_IMAGES');

		erase_cached_templates();

		breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_THEMES')),array('_SELF:_SELF:manage_images:theme='.$theme,do_lang_tempcode('CHOOSE')),array('_SELF:_SELF:edit_theme_image:id='.$id,do_lang_tempcode('EDIT_THEME_IMAGE'))));
		breadcrumb_set_self(do_lang_tempcode('DONE'));

		return $this->do_next_manager($title,do_lang_tempcode('SUCCESS'),$theme,$lang,'image',$id);
	}

	/**
	 * Shows the list of templates
	 *
	 * @return tempcode		The UI
	 */
	function list_screen_previews()
	{
		$title=get_screen_title('SCREEN_PREVIEWS');

		$GLOBALS['HELPER_PANEL_PIC']='';
		$GLOBALS['HELPER_PANEL_TUTORIAL']='';

		if (function_exists('set_time_limit')) @set_time_limit(120);
		require_code('lorem');

		// Find all templates
		$templates=array();
		$dh=opendir(get_file_base().'/themes/default/templates');
		while (($f=readdir($dh))!==false)
		{
			if (strtolower(substr($f,-4))=='.tpl') $templates[]=$f;
		}
		sort($templates);

		// Find all previews (map of templates to previews)
		$all_previews=find_all_previews__by_template();
		// And by screen
		$all_previews__by_screen=find_all_previews__by_screen();

		// Find other things we may want to preview
		$comcode_files=find_comcodes();
		$html_files=find_html();

		// Loop over to display it all
		$displayed_already=array();
		$lis=new ocp_tempcode();
		$lis_admin=new ocp_tempcode();
		foreach ($templates as $t)
		{
			// If we have a preview for it
			if (array_key_exists($t,$all_previews))
			{
				if (!array_key_exists($all_previews[$t][1],$displayed_already))
				{
					$func=$all_previews[$t][1];

					$preview_url=build_url(array('page'=>'_SELF','type'=>'view','id'=>$t,'hook'=>$all_previews[$t][0],'function'=>$func),'_SELF');

					$template_used="(".implode(', ',$all_previews__by_screen[$func]).")";

					$tpl_x=do_template('TEMPLATE_LIST',array('_GUID'=>'1f27f619db553dfcb8d427e70a736226','URL'=>$preview_url,'COLOR'=>'green','TEMPLATE'=>preg_replace('#^tpl_preview\_\_#','',$func),'LIST'=>$template_used));
					if (preg_match('#^tpl_preview\_\_administrative\_\_#',$func)!=0)
					{
						$lis_admin->attach($tpl_x);
					} else
					{
						$lis->attach($tpl_x);
					}

					$displayed_already[$func]=true;
				}
			} elseif ((substr($t,0,11)!='JAVASCRIPT_') && ($t!='JAVASCRIPT.tpl')) // Oh dear
			{
				$tpl_x=do_template('TEMPLATE_LIST',array('URL'=>'','COLOR'=>'red','TEMPLATE'=>$t,'LIST'=>''));
				$lis->attach($tpl_x);
			}
		}

		// Prepare all to display...

		$post=new ocp_tempcode();

		/* $lis (the main previews) will be displayed in the main INDEX_SCREEN content */

		/* LISTING ADMIN PREVIEWS */
		$post->attach(do_template('TEMPLATE_LIST_WRAP',array('_GUID'=>'1e847f3c75998f2276765bc0c8ab6b78','LI'=>$lis_admin,'TITLE'=>do_lang('ADMIN_SCREENS'))));

		/* LISTING COMCODE FILES   */
		$com_li=new ocp_tempcode();
		foreach($comcode_files as $zone=>$pages)
		{
			if($zone=='pages')
				$zone="";
			foreach($pages as $page=>$type)
			{
				if (!is_string($page)) $page=strval($page);

				$file=$page.'.txt';
				$url=build_url(array('page'=>$page),$zone);
				$com_li->attach(do_template('TEMPLATE_LIST',array('_GUID'=>'9db6fa9333470137ccf9bb752fd9b19e','URL'=>$url,'COLOR'=>'','TEMPLATE'=>$file,'LIST'=>'')));
			}
		}
		$post->attach(do_template('TEMPLATE_LIST_WRAP',array('_GUID'=>'adf69728048cbdbc3a0d9a2e2485a234','LI'=>$com_li,'TITLE'=>do_lang('COMCODE_PAGES'))));

		/* LISTING HTML FILES   */
		$htm_li=new ocp_tempcode();
		foreach($html_files as $zone=>$pages)
		{
			foreach($pages as $page=>$type)
			{
				$file=$page.'.htm';
				$url=build_url(array('page'=>$page),$zone);

				$htm_li->attach(do_template('TEMPLATE_LIST',array('_GUID'=>'16d1c1c5dc5556254f7a3f28a44fdb52','URL'=>$url,'COLOR'=>'','TEMPLATE'=>$file,'LIST'=>'')));
			}
		}
		$post->attach(do_template('TEMPLATE_LIST_WRAP',array('_GUID'=>'2220938b443ecdb7d3f2d869665b3a4e','LI'=>$htm_li,'TITLE'=>do_lang('HTML_PAGES'))));

		return do_template('INDEX_SCREEN',array('_GUID'=>'6137f107de679580a6aafe36af427cdd','TITLE'=>$title,'CONTENT'=>$lis,'POST'=>$post,'PRE'=>''));
	}

	/**
	 * Shows the preview of a screen
	 *
	 * @return tempcode		The UI
	 */
	function view_screen_preview()
	{
		$GLOBALS['HELPER_PANEL_PIC']='';
		$GLOBALS['HELPER_PANEL_TUTORIAL']='';
		$GLOBALS['SCREEN_TEMPLATE_CALLED']='';

		require_code('lorem');

		global $LOREM_AVOID_GLOBALISE;
		$LOREM_AVOID_GLOBALISE=true;

		$template=get_param('id');
		$hook=get_param('hook');
		$function=get_param('function');

		//get_screen_title('SCREEN_PREVIEW',true,array(escape_html($function))); // Affects breadcrumbs etc
		get_screen_title($function,false); // Affects breadcrumbs etc
		breadcrumb_set_parents(array(array('_SELF:_SELF:list',do_lang_tempcode('SCREEN_PREVIEWS'))));

		return render_screen_preview($template,$hook,$function);
	}
}


