<?php
/**
 * Coppermine Photo Gallery
 *
 * v1.0 originally written by Gregory Demar
 *
 * @copyright  Copyright (c) 2003-2023 Coppermine Dev Team
 * @license    GNU General Public License version 3 or later; see LICENSE
 *
 * install.php
 * @since  1.6.24
 */

########################
####Install Main Code###
########################
define('IN_COPPERMINE', true);
define('INSTALL_PHP', true);
define('VERSIONCHECK_PHP', true);

define('INFORMATION', 1);
define('ERROR', 2);
define('CRITICAL_ERROR', 3);

//Define installation steps
define('STEP_INIT_AND_LANG', 1);
define('STEP_VERSIONCHECK', 2);
define('STEP_FOLDER_PERMISSIONS', 3);
define('STEP_SELECT_IMG_PROC', 4);
define('STEP_TEST_IMG_PROC', 5);
define('STEP_DB_INFO', 6);
define('STEP_DB_SELECT', 7);
define('STEP_DB_INIT', 8);
define('STEP_SET_ADMIN', 9);
define('STEP_FINALISE', 10);

// Set global vars
$LINEBREAK = "\r\n"; // For compatibility both on Windows as well as *nix

// Set required versions
$required_php_version = '5.4.0';

// Set the parameters that normally get populated by the option form
$displayOption_array = array(
	'errors_only' => 1,
	'do_not_connect_to_online_repository' => 1,
);

// Populate the $CONFIG vars if they are empty
$CONFIG = array(
	'fullpath' => 'albums/',
	'userpics' => 'userpics/',
);

if (!defined('COPPERMINE_VERSION')) { // we need to define the constant COPPERMINE_VERSION that normally get's populated by include/init.inc.php, as we check the repository against that version number
	$handle = @fopen('include/init.inc.php', 'r');
	if ($handle == FALSE) {
		$page_title = 'Could not fopen';
		html_header();
		echo 'Could not open the file include/init.inc.php for reading. Make sure it exists and is readable, then try again.';
		html_footer();
		die;
	}
	$found = 0;
	while (!feof($handle) && $found != 1) {
		$buffer = fgets($handle, 4096);
		if (strpos($buffer, "define('COPPERMINE_VERSION', '") === FALSE) {
			$found = 0;
		} else {
			$found = 1;
			$version_number = trim(str_replace("');", '', str_replace("define('COPPERMINE_VERSION', '", '', $buffer)));
		}
	}
	@fclose($handle);
	if ($version_number != '' && version_compare($version_number, '1.5', '>') == TRUE) {
		define('COPPERMINE_VERSION', $version_number);
	} else {
		$page_title = 'Could not determine version number';
		html_header();
		echo 'Could not extract the Coppermine version number from the file inlucde/init.inc.php. Please download a fresh copy of the Coppermine package.';
		html_footer();
		die;
	}
}
// include Inspekt for sanitization
$incp = get_include_path().PATH_SEPARATOR.dirname(__FILE__).PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'include';
set_include_path($incp);
require_once 'include/inspekt.php';
$superCage = Inspekt::makeSuperCage();

//load language
$config = array(); // (array) temp config
$config_file['temporary'] = 'include/config.tmp.php';
$config_file['permanent'] = 'include/config.inc.php';
$error = ''; // (string) holds errors
$temp_data; // holds various data
$page_title = ''; // (string) holds the title of the current installation step

// Check if install has already been done, else load temporary config.
loadTempConfig();

//load language
$language = getLanguage();	// (array) holds the language
$icon = array();
$icon['submit'] = '<img src="images/icons/right.png" border="0" alt="" width="16" height="16" class="icon" />';
$icon['lang'] = '<img src="images/icons/babelfish.png" border="0" alt="" width="16" height="16" class="icon" />';
$icon['test'] = '<img src="images/icons/reload.png" border="0" alt="" width="16" height="16" class="icon" />';
$icon['retry'] = '<img src="images/icons/reload.png" border="0" alt="" width="16" height="16" class="icon" />';
$icon['add'] = '<img src="images/icons/add.png" border="0" alt="" width="16" height="16" class="icon" />';


// get installation step
if ($superCage->get->keyExists('step') && isset($config['steps_done']) && is_array($config['steps_done'])
		&&	in_array($superCage->get->getInt('step'), $config['steps_done']))
{
	$step = $superCage->get->getInt('step');
} else {
	if (isset($config['step'])) {
		$step = $config['step'];
	} else {
		$step = STEP_INIT_AND_LANG;
	}
}

// check if we have an update instead of a next step request
if ($superCage->post->keyExists('update_lang')) {
	$step = STEP_INIT_AND_LANG;
}
if ($superCage->post->keyExists('update_im_path')) {
	$step = STEP_SELECT_IMG_PROC;
}
if ($superCage->post->keyExists('update_check_connection')) {
	$step = STEP_DB_INFO;
}
if ($superCage->post->keyExists('update_create_db')) {
	$step = STEP_DB_SELECT;
}

// if installation is done, only show last page
if (isset($config['install_finished'])) {
	$step = STEP_FINALISE;
}


setTmpConfig('steps_done', $step, true);
// check if the installer has already been run succefully
if ($error != '') {
	html_header();
	html_installer_locked();
	html_footer();
	exit;
}

// check if we have new user input and put it in the temp config
if ($superCage->post->keyExists('thumb_method')) {
	setTmpConfig('thumb_method', $superCage->post->getAlnum('thumb_method'));
}
if ($superCage->post->keyExists('im_path') &&
	$superCage->post->getPath('im_path') !=
			(dirname($superCage->server->getPath('SCRIPT_FILENAME') . DIRECTORY_SEPARATOR)))
{
	$im_path = $superCage->post->getPath('im_path');
	$im_path = str_replace('\\', '/', $im_path);
	if (!preg_match('|[/\\\\]\Z|', $im_path)) {
		$im_path .= '/';
	}
	setTmpConfig('im_path', $im_path);
}

switch($step) {
	case STEP_INIT_AND_LANG:	 // Initialisation & natural language selection
		//write a coockie to check in the next step
		setcookie('cpg_install_cookie_check', 'passed', time() + 3600);

		$page_title = $language['title_welcome'];
		html_header();
		html_welcome();
		html_footer();
		break;

	case STEP_VERSIONCHECK:		// Are all mandatory files there
		// Here we also do an extensive version check of php + check of javascript/cookies/register_globals
		// the cookie for this check is inserted in the previous step!
		// javascript is tested by altering a hidden form element in the previous step.

		//PHP VERSION CHECK
		$php_version = phpversion();
		if (version_compare($required_php_version, $php_version, '>=')) {
			//check if php_version is actualy a version number
			if ($php_version == '') {
				//version could not be detected, show corresponding error
				$error .= sprintf($language['version_undetected'], 'PHP', $required_php_version) . '<br />';
			} else {
				//user is using incompatible php version
				$error .= sprintf($language['version_incompatible'], $php_version, 'PHP', $required_php_version) . '<br />';
			}
		}
		//COOKIE CHECK
		if ($superCage->cookie->getAlpha('cpg_install_cookie_check') != 'passed') {
			//no cookie found, you're in trouble now :)
			$error .= $language['no_cookie'] . '<br />';
		}
		//JAVASCRIPT CHECK
		if ($superCage->post->keyExists('javascript_check') && $superCage->post->getAlpha('javascript_check') != 'passed' && !$config['javascript_test_passed']) {
			//javascripts seems to be disabled, send them the message...
			$error .= $language['no_javascript'] . '<br />';
		} else {
			$config['javascript_test_passed'] = true;
		}
		//REGISTER_GLOBALS CHECK
		if (ini_get('register_globals')) {
			//register_globals is turned on, please turn it of.
			$error .= $language['register_globals_detected'];
			$error .= '[<a href="https://coppermine-gallery.net/docs/curr/en/install.htm#install_server_config_register_globals">' . $language['more'] . '</a>]';
			$error .= '<br />';
		}

		//XML PARSER CHECK
		if (function_exists('simplexml_load_string') || function_exists('xml_parser_create')) {
			$has_XML = true;
		} else {
			$has_XML = false;
			$error = $language['no_xml_parser'] . '<br />';
		}

		$page_title = $language['title_file_check'];
		html_header();
		if ($error != '') {
			html_error(false /*false to not include a button*/);
		}

		if ($has_XML) {
			//use versioncheck to check file versions
			$lang_versioncheck_php = $language['versioncheck'];
			$lang_common = $language['lang_common'];
			require_once 'include/versioncheck.inc.php';
	
			// TODO: need to deal with connection failing and skip this step (and maybe allow a retry)
	
			// Connect to the repository and populate the array with data from the XML file
			$file_data_array = cpgVersioncheckConnectRepository($displayOption_array);
	
			$file_data_array = cpg_versioncheckPopulateArray($file_data_array);
			//$file_data_array = cpg_versioncheckPopulateArray($file_data_array, $displayOption_array, $textFileExtensions_array, $imageFileExtensions_array, $CONFIG, $maxLength_array, $lang_versioncheck_php);
			$file_data_count = count($file_data_array);
			// Print the results
			$outputResult = cpg_versioncheckCreateHTMLOutput($file_data_array, $textFileExtensions_array, $lang_versioncheck_php, $majorVersion, $displayOption_array);
			$versioncheck_output = sprintf($lang_versioncheck_php['files_folder_processed'], $outputResult['display'], $outputResult['total'], $outputResult['error']);
	
			// TODO: end
	
			html_content($versioncheck_output);
		}

		html_footer();
		setTmpConfig('step', STEP_FOLDER_PERMISSIONS);
		break;

	case STEP_FOLDER_PERMISSIONS:		// Check if the folder permissions are set up properly
		$page_title = $language['title_dir_check'];
		if (!checkPermissions()) {
			// not all permissions were set correctly, or folder doesn't exist
			html_header();
			html_error();
			html_content($language['perm_not_ok']);	 // show all checked folders?
			html_footer();
		} else {
			// permissions are set alright, continue
			html_header();
			html_content($language['perm_ok']);	 // show all checked folders?
			html_footer();
			setTmpConfig('step', STEP_SELECT_IMG_PROC);
		}
		break;

	case STEP_SELECT_IMG_PROC:		// Check available image processors & let user choose
		$page_title = $language['title_imp'];
		$supported_processors = array('gd2' => "GD2", 'imx' => 'Imagick Extension');
		$image_processors = checkImageProcessor();
		html_header();
		if ($error != '') {
			html_error();
		}
		if( !($error != '' && !isset($image_processors['gd2'])) ) {
			setTmpConfig('step', STEP_TEST_IMG_PROC);
		}
			$content = $language['im_packages'] . '<br />';
		$imp_list = '<select name="thumb_method" class="listbox" size="1">';
		if (isset($image_processors['gd2'])) {
			// gd2 is avilable, add it to the list
			$imp_list .= '<option value="gd2">GD2</option>';
			$content .= '<strong>GDlib</strong> Version 2. <br />';
			$selected = 'gd2';
		}
		// check configuration options of im_path
		if (isset($image_processors['im'])) {
			// im is available, add it to the list
			$path = str_replace(array('.exe', '"'), '',$image_processors['im']['path']);
			$path = substr($path, 0, (strlen($path) - 7));
			$imp_list .= '<option value="im">ImageMagick</option>';
			$content .= '<strong>ImageMagick</strong> Version ' . substr($image_processors['im']['version'], 20, 7) . '(at: ' . $path .')<br />';
			if($error == ''){
				$selected = 'im';
			}
			$im_not_found = '';
		} else {
			$path = '';
			$im_not_found = '<br /><fieldset style="width:90%" title="ImageMagick">' . $language['im_not_found'] .'</fieldset>';
		}
		if (isset($image_processors['imx'])) {
			// Imagick extension is avilable, add it to the list and make it default
			$imp_list .= '<option value="imx">Imagick Extension</option>';
			$content .= '<strong>Imagick Extension</strong> '.$image_processors['imx'].'<br />';
			$selected = 'imx';
		}
		// check configuration options
		if (isset($config['thumb_method'])) $selected = $config['thumb_method'];
		$imp_list .= '</select>';
		$imp_list = str_replace($selected . '"', $selected . '" selected="selected"', $imp_list);

		// if no image library is found, tell the user so, and select gd2
		if (!isset($selected)) {
			$content .= '<br /><fieldset style="width:90%" title="GD">' . $language['no_gd'] . '</fieldset><br />' . $im_not_found;
		} else {
			$content .= '<br />' . $language['installer_selected'] . ' \'' . $supported_processors[$selected] . '\'<br />' . $imp_list . $im_not_found;
		}

		// add IM path box
		if (isset($config['im_path'])
				&& $superCage->post->getPath('im_path') !=
					(dirname($superCage->server->getPath('SCRIPT_FILENAME') . DIRECTORY_SEPARATOR)))
		{
			$path = $config['im_path'];
		}
		$content .= '<br />' . $language['im_path']
			. '<br /><input type="text" class="textinput" name="im_path" value="'
			. $path . '" /><button type="submit" class="button" name="update_im_path" value="'
			. $language['check_path'] . '">'
			. $icon['test'] . $language['check_path'] . '</button>';

		html_content($content);
		html_footer();
		break;

	case STEP_TEST_IMG_PROC:	 // Check if the image library information has been set up properly - display some basic test images created with the image library selected
		$page_title = $language['title_imp_test'];
		html_header();
		$content = '<center>' . testImageProcessor() . '</center>';
		if ($error != '') {
			html_error();
		} else {
			setTmpConfig('step', STEP_DB_INFO);
		}
		html_content($content);
		html_footer();
		break;

	case STEP_DB_INFO:		// Ask user for database type, host, username and password, try to establish a connection using that info
		$db_type = $superCage->post->getRaw('db_type');
		if (!isset($db_type)) {
			$db_type = $config['db_type'];
		} else {
			setTmpConfig('db_type', $db_type);
		}
		list($dext, $dsub) = explode(':', $db_type.':');
		if ($db_type) require_once 'include/database/'.$dext.'/install.php';
		$page_title = $language['title_dbase_user'];
		// check if we are trying to test the connection
		if ($superCage->post->keyExists('update_check_connection')
				|| (isset($config['db_host']) && $superCage->post->keyExists('db_host')))
		{
			// here we do not use the setTmpConfig funtion, as this function always writes the new file
			// and it will be written in the third step...
			$config['db_host'] = $superCage->post->getRaw('db_host');
			$config['db_user'] = $superCage->post->getRaw('db_user');
			setTmpConfig('db_password', $superCage->post->getRaw('db_password'));

			// test the connection
			$con_check = 'check'.ucfirst($dext).'Connection';
			$con_check($dsub);
		}
		html_header();
		if ($error != '') {
			html_error(false /*false to not include a button*/);
		} else {
			if (isset($config['db_password'])) {
				setTmpConfig('step', STEP_DB_SELECT);
			}
		}
		html_dbase_start($db_type);
		html_footer();
		break;

	case STEP_DB_SELECT:	 // Ask the user if he wants to use an existing db or if he wants the installer to create a new database. Try to perform the selected choice. Ask for the table prefix
		$db_type = $config['db_type'];
		list($dext, $dsub) = array_pad(explode(':', $db_type), 2, '');
		require_once 'include/database/'.$dext.'/install.php';
		$page_title = sprintf($language['title_dbase_db_sel'], strtoupper($db_type));
		// save the db data from previous step
		if ($superCage->post->keyExists('db_host')	&& !isset($config['db_populated'])) {
			// here we do not use the setTmpConfig function, as this function always writes the new file
			// and it will be written in the third step...
			$config['db_host'] = $superCage->post->getRaw('db_host');
			$config['db_user'] = $superCage->post->getRaw('db_user');
			setTmpConfig('db_password', $superCage->post->getRaw('db_password'));
			if ($error != '') {
				$error .= '<br />' . sprintf($language['please_go_back'], '<a href="install.php?step=' . ($step - 1) . '">', '</a>');
			}
		} elseif ($superCage->post->keyExists('update_create_db')
				&& trim($superCage->post->getRaw('new_db_name')) != '')
		{
			// try to create a new database.
			$createDb = 'create'.ucfirst($dext).'Db';
			$createDb(trim($superCage->post->getRaw('new_db_name'))); // no /\:*?"<>|.
			// save table prefix
			setTmpConfig('db_prefix', $superCage->post->getRaw('db_prefix')); // no /\:*?"<>|.
		}
		$con_check = 'check'.ucfirst($dext).'Connection';
		$con_check($dsub);
		html_header();
		if ($error != '') {
			html_error();
		} else {
			$html_select_db = 'html_'.$dext.'_select_db';
			$html_select_db($dsub);
			setTmpConfig('step', STEP_DB_INIT);
		}
		html_footer();
		break;

	case STEP_DB_INIT:		// save db_prefix/_name and finally create the tables
		$db_type = $config['db_type'];
		list($dext, $dsub) = explode(':', $db_type.':');
		require_once 'include/database/'.$dext.'/install.php';
		$page_title = $language['title_dbase_pop'];
		// save the db data from previous step
		if ($superCage->post->keyExists('db_name') && !isset($config['db_populated'])) {
			setTmpConfig('db_name', $superCage->post->getRaw('db_name'));
			setTmpConfig('db_prefix', $superCage->post->getRaw('db_prefix'));
		}
		// populate db if not done yet
		$set_populated = false;
		if (!isset($config['db_populated']) && isset($config['db_name'])) {
			$msg = $language['db_populating'];
			if (populateDatabase()) {
				$set_populated = true;
			}
		} elseif (!isset($config['db_populated']) && !isset($config['db_name'])) {
			$msg = sprintf($language['not_here_yet'], '<strong><a href="install.php?step=7">', '</a></strong>');
		}

		if (isset($config['db_populated'])) {
			html_header();
			if ($error != '') {
				html_error();
			}
			$temp_data = '<tr><td><br /><br />' . $language['db_alr_populated']
				. '<br /><br /></td></tr>';
			html_content($language['db_populating']);
			html_footer();
			setTmpConfig('step', STEP_SET_ADMIN);
		} else {
			if ($set_populated) {
				// this is a lock to see if the db has been created yet
				setTmpConfig('db_populated', 'done');
				setTmpConfig('step', STEP_SET_ADMIN);
			}
			html_header();
			if ($error != '') {
				html_error();
			}
			html_content($msg);
			html_footer();
			break;
		}
		break;

	case STEP_SET_ADMIN:	 // Ask for coppermine admin username, password and email address
		$db_type = $config['db_type'];
		list($dext, $dsub) = explode(':', $db_type.':');
		require_once 'include/database/'.$dext.'/install.php';
		$page_title = $language['title_admin'];
		if ($superCage->post->keyExists('admin_username')) {
			// check validity of admin details
			$admin_username = $superCage->post->getMatched('admin_username', '/\A\w*\Z/');
			if ($admin_username[0] == '' || !$admin_username) {
				// admin username not correct
				$error .= $language['user_err'] . '<br />';
			} else {
				setTmpConfig('admin_username', $admin_username[0]);
			}

			// we need a db connection to use getEscaped()
			$con_check = 'check'.ucfirst($dext).'Connection';
			$con_check($dsub);

			$admin_password = $superCage->post->getEscaped('admin_password');
			$admin_password_verif = $superCage->post->getEscaped('admin_password_verif');
			if ($admin_password != $admin_password_verif || $admin_password == '') {
				// admin password not correct
				$error .= $language['pass_err'] . '<br />';
			} else {
				setTmpConfig('admin_password', $superCage->post->getEscaped('admin_password'));
			}
			$email = $superCage->post->getMatched('admin_email', '/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i');
			$ver_email = $superCage->post->getMatched('admin_email_verif', '/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i');
			if ($email[0] != $ver_email[0] || $email[0] == '') {
				// admin email not correct
				$error .= $language['email_no_match'] . '<br />';
			} else {
				setTmpConfig('admin_email', $email[0]);
			}
		}

		if (isset($config['admin_username']) && isset($config['admin_password']) && isset($config['admin_email']) && !isset($config['install_finished'])) {
			// create admin
			if (createAdmin()) {
				// add finished flag to config
				setTmpConfig('install_finished', 'done');
				$step = 10;
				$page_title = $language['title_finished'];
			}
		}

		html_header();
		if ($error != '') {
			html_error();
		} else {
			if (isset($config['install_finished'])) {
				setTmpConfig('step', STEP_FINALISE);
				finaliseInstall();
				html_finish();
			} else {
				html_admin();
			}
		}
		html_footer();
		break;

	case STEP_FINALISE:		// Finally check if everything is set up properly and tell the user so
		finaliseInstall();

		$page_title = $language['title_finished'];
		html_header();
		if ($error != '') {
			html_error();
		}
		html_finish();
		html_footer();

		break;
}


function finaliseInstall ()
{
	// write real config file
	writeConfig();

	// delete temp config + created test images!!
	$files_to_remove = array(
		'albums/combined_generated.jpg',
		'albums/giftest_generated.gif',
		'albums/giftest_generated.jpg',
		'albums/jpgtest_generated.jpg',
		'albums/pngtest_generated.jpg',
		'albums/pngtest_generated.png',
		'albums/scaled_generated.jpg',
		'albums/texttest_generated.jpg',
		'include/config.tmp.php',
		);
	foreach ($files_to_remove as $file) {
		if (is_file($file)) {
			unlink($file);
		}
	}
}


########################
####Install Templates###
########################

/* html_header()
 *
 * prints the header
 */
function html_header()
{
	global $language;

	header('Cache-Control: no-cache');
	echo <<<EOT
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<title>Coppermine - {$language['installation']}</title>
<link rel="stylesheet" href="css/installer.css" type="text/css" />
<link rel="shortcut icon" href="favicon.ico" />
</head>
<body>
 <div align="center">
  <div>
  <table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
	<tr>
	  <td valign="top" style="background-color:#EFEFEF"><img src="images/coppermine-logo.png" width="260" height="60" border="0" alt="" /><br />
	  </td>
	</tr>
  </table>

EOT;

	html_stepper();
}
// end function html_header


/* html_footer()
 *
 * prints the footer
 */
function html_footer()
{
	echo <<<EOT
  </div>
 </div>
</body>
</html>
<noscript><plaintext>

EOT;
}
// end function html_footer


/* html_stepper()
 *
 * prints current installation step with links to the next ones
 */
function html_stepper()
{
	global $config, $page_title, $step, $language;

	$stepper = '';
	$tpl_step_done = '<td class="stepper_d" onMouseOver="this.className=\'stepper_do\'" onMouseOut="this.className=\'stepper_d\'" onclick="document.location=\'install.php?step=%s\'"><a href="install.php?step=%s" title="Step: %s">%s</a></td>';
	$tpl_step_current = '<td class="stepper_c"><span title="Step: %s">%s</span></td>';
	$tpl_step_notyet = '<td class="stepper_n"><span title="Step: %s">%s</span></td>';
	for($i = 1; $i < 11; $i++) {
		if ($i == $step) {
			$stepper .= sprintf($tpl_step_current, $i, $i);
		} elseif (isset($config['steps_done']) && is_array($config['steps_done']) && in_array($i, $config['steps_done'])) {
			$stepper .= sprintf($tpl_step_done, $i, $i, $i, $i);
		} else {
			$stepper .= sprintf($tpl_step_notyet, $i, $i);
		}
	}
print <<< EOT
	<table class="stepper_table">
		<tr>
			<td>{$stepper}</td>
		</tr>
	</table>
	<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		<tr>
			<td class="tableh1" colspan="2"><h2>{$page_title}</h2></td>
		</tr>
	</table>
EOT;
}

/* html_installer_locked()
 *
 * prints the error when the installer is locked
 */
function html_installer_locked()
{
	global $language, $error, $icon;

print <<< EOT
	<form action="index.php" style="margin:0px;padding:0px" name="cpgform" id="cpgform">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableh1" colspan="2"><h2>{$language['installer_locked']}</h2>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableh2" colspan="2"><h3 class="error">{$language['error']}</h3>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" colspan="2">{$error}
		  </td>
		 </tr>
		 <tr>
		  <td colspan="2" align="center" class="tableb">
			<button type="submit" class="button" name="submit" value="{$language['go_to_main']}">{$language['go_to_main']}{$icon['submit']}</button>
		  </td>
		 </tr>
		</table>
	</form>
EOT;
}

/* html_welcome()
 *
 * prints the welcome message at the start of installation + language selection
 */
function html_welcome()
{
	global $language, $error, $icon;

	if (!setTmpConfig('step', STEP_VERSIONCHECK)) {
		$next_step = STEP_INIT_AND_LANG;
	} else {
		$next_step = STEP_VERSIONCHECK;
	}
	print <<< EOT
	  &nbsp;<br />
	  <form action="install.php?step={$next_step}" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableh1" colspan="2">
			<h2>{$language['license']}</h2>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" colspan="2">
			{$language['license_info']}
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" colspan="2">
			<iframe src="https://coppermine-gallery.net/docs/curr/en/copyrights.htm?hide_nav=1" width="100%" height="300" name="license">
			{$language['cpg_info_frames']}</a>.
			</iframe>
		  </td>
		 </tr>
	   </table>
	   &nbsp;<br />
	   <table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
EOT;
	if ($error != '') {
		print <<< EOT
		 <tr>
		  <td class="tableh2" colspan="2" align="left"><span class="error">{$language['error']}</span>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" colspan="2">{$language['error_need_corr']}<br /><strong>{$error}</strong>
		  </td>
		 </tr>
EOT;
	}
	$getLangSelect = getLangSelect();
	print <<< EOT
		 <tr>
		  <td class="tableh1" colspan="2"><strong>{$language['select_lang']}</strong>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" align="center" colspan="2">
			  {$getLangSelect}
			  <button type="submit" class="button" name="update_lang" value="{$language['change_lang']}">{$icon['lang']}{$language['change_lang']}</button>
		  </td>
		 </tr>
		<tr>
		  <td colspan="2" align="center" class="tableh2"><br />
			<button type="submit" class="button" name="submit" value="{$language['lets_go']}">{$language['lets_go']}{$icon['submit']}</button>
		  </td>
		 </tr>
	</table>
	<input type="hidden" name="javascript_check" value="failed" />
  </form>
  <!-- This code will check if javascript is enabled -->
	  <script type="text/javascript">
	  <!--
		document.forms[0][3].value = "passed";
	  -->
	  </script>
EOT;
}

/* html_content()
 *
 * prints standard page with variable content
 */
function html_content($content)
{
	global $language, $step, $temp_data, $icon;

	$step_next = $step + 1;
	echo <<<EOT
	  <form action="install.php?step={$step_next}" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableb" colspan="2">{$content}<br /><br /></td>
		 </tr>

EOT;
	if ($temp_data != '') {
		echo $temp_data;
	}
	echo <<<EOT
		 <tr>
		  <td colspan="2" align="center" class="tableh2"><br />
			<button type="submit" class="button" name="submit" value="{$language['continue']}">{$language['continue']}{$icon['submit']}</button>
		  </td>
		 </tr>
		</table>
	  </form>

EOT;
}
// end function html_content


/* html_error()
 *
 * prints error message
 *
 * @param boolean $button
 */
function html_error($button = true)
{
	global $language, $step, $error, $icon;

	print <<< EOT
	  <form action="install.php?step={$step}" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableh2" colspan="2" align="left"><span class="error">{$language['error']}</span>
		  </td>
		 </tr>
		 <tr>
		  <td class="tableb" colspan="2">{$language['error_need_corr']}<br /><strong>{$error}</strong>
		  </td>
		 </tr>
EOT;
		  if ($button) {
			print <<< EOT
			<tr>
			  <td colspan="2" align="center" class="tableh2">
				  <button type="submit" class="button" name="try_again" value="{$language['try_again']}">{$icon['retry']}{$language['try_again']}</button>
			  </td>
			</tr>
EOT;
		  }
		  print <<< EOT
		</table>
	 </form>
EOT;
}

/* html_dbase_start()
 *
 * prints page with basic database config
 */

function html_dbase_start($type=null)
{
	global $language, $step, $dbase_connected, $config, $icon;

	$step_next = $step + 1;
	$slct = $type ?: 'mysqli';

	require_once 'include/dbselect.inc.php';
	$dbselect = new DbaseSelect();

	echo <<<EOT
	<form action="install.php?step={$step_next}" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
			<tr>
				<td class="tableb" colspan="2">
					{$language['sect_dbase_info']}<br />
				</td>
			</tr>
			<tr>
				<td colspan="2">&nbsp;</td>
			</tr>
			<tr>
				<td align="right">Database Type</td>
				<td><select name="db_type">{$dbselect->options($slct)}</select></td>
			</tr>
EOT;
	if ($dbase_connected) {
		echo <<<EOT
			<tr>
				<td></td>
				<td align="left"><div class="cpg_message_success">{$language['dbase_succ']}</div></td>
			</tr>

EOT;
	}
	$db_host	 = isset($config['db_host']) && $dbase_connected ? $config['db_host'] : 'localhost';
	$db_user	 = isset($config['db_user']) && $dbase_connected ? $config['db_user'] : '';
	$db_password = isset($config['db_password']) && $dbase_connected ? $config['db_password'] : '';
	echo <<<EOT
		 <tr>
		  <td align="right">{$language['dbase_host']}</td>
		  <td><input type="text" class="textinput" name="db_host" value="$db_host" /></td>
		 </tr>
		 <tr>
		  <td align="right">{$language['dbase_username']}</td>
		  <td><input type="text" class="textinput" name="db_user" value="$db_user" /></td>
		 </tr>
		 <tr>
		  <td align="right">{$language['dbase_password']}</td>
		  <td><input type="password" name="db_password" value="$db_password" /></td>
		 </tr>
		 <tr>
		 <td colspan="2" align="center">
			<button type="submit" class="button" name="update_check_connection" value="{$language['dbase_test_connection']}">{$icon['test']}{$language['dbase_test_connection']}</button>
		  </td>
		 </tr>

EOT;
	if ($dbase_connected) {
		echo <<<EOT
		<tr>
		  <td colspan="2" align="center" class="tableh2">
			<button type="submit" class="button" name="submit" value="{$language['continue']}">{$language['continue']}{$icon['submit']}</button>
		  </td>
		 </tr>

EOT;
	} else {
		echo <<<EOT
		<tr>
		  <td colspan="2" align="center" class="tableh2">&nbsp;<br /></td>
		</tr>

EOT;
	}
	echo <<<EOT

		</table>
	  </form>

EOT;
}
// end function html_dbase_start


/* html_admin()
 *
 * prints page for admin details
 */
function html_admin()
{
	global $language, $step, $icon;

	$admin_username = isset($config['admin_username']) ? $config['admin_username'] : '';
	$admin_password = isset($config['admin_password']) ? $config['admin_password'] : '';
	// TODO: check verify field in $config to see if checked against password
	$admin_password_verify = isset($config['admin_password']) ? $config['admin_password'] : '';
	$admin_email = isset($config['admin_email']) ? $config['admin_email'] : '';
	// TODO: ditto above
	$admin_email_verify = isset($config['admin_email']) ? $config['admin_email'] : '';
	echo <<<EOT
	<form action="install.php?step={$step}" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableb" colspan="2">
		  {$language['sect_create_adm']}<br />
		  </td>
		 </tr>
		 <tr>
		  <td colspan="2">&nbsp;</td>
		 </tr>
		 <tr>
		  <td align="right">{$language['username']}</td>
		  <td><input type="text" class="textinput" name="admin_username" value="$admin_username"  /></td>
		 </tr>
		 <tr>
		  <td align="right">{$language['password']}</td>
		  <td><input type="password" name="admin_password" value="$admin_password" /></td>
		 </tr>
		  <tr>
		  <td align="right">{$language['password_verif']}</td>
		  <td><input type="password" name="admin_password_verif" value="$admin_password_verify" /></td>
		 </tr>
		 <tr>
		  <td align="right">{$language['email']}</td>
		  <td><input type="text" class="textinput" name="admin_email" value="$admin_email" /></td>
		 </tr>
		  <tr>
		  <td align="right">{$language['email_verif']}</td>
		  <td><input type="text" class="textinput" name="admin_email_verif" value="$admin_email_verify" /></td>
		 </tr>
		 <tr>
		 <td colspan="2">&nbsp;</td>
		 </tr>
		 <tr>
		  <td colspan="2" align="center" class="tableh2">
			<button type="submit" class="button" name="submit" value="{$language['continue']}">{$language['continue']}{$icon['submit']}</button>
		  </td>
		 </tr>
		</table>
	</form>

EOT;
}
// end function html_admin


/* html_finish()
 *
 * prints last page of installer
 */
function html_finish()
{
	global $language;

	echo <<<EOT
	<form action="index.php" name="cpgform" id="cpgform" method="post" style="margin:0px;padding:0px">
		<table width="100%" border="0" cellpadding="0" cellspacing="1" class="maintable">
		 <tr>
		  <td class="tableb" colspan="2">
		  {$language['ready_to_roll']}<br />
		  </td>
		 </tr>
		 <tr>
		 <td colspan="2">&nbsp;</td>
		 </tr>
		 <tr>
		  <td colspan="2" align="center" class="tableh2">
			<input type="submit" value="{$language['finish']}" /><br />
		  </td>
		 </tr>
		</table>
	</form>

EOT;
}
// end function html_finish


############################
#####CPGInstall functions###
############################

/* loadTempConfig()
*
* Check if install has already been done, else load temporary config.
* if the unserialize doesn't work, it will be tried again for 10 times before showing an error
*
* @param int $rp
*/
function loadTempConfig($rp=0)
{
	global $config, $config_file;
	if (file_exists($config_file['permanent'])) {
		$GLOBALS['language'] = getLanguage();
		$GLOBALS['error'] = '<h3>'.$GLOBALS['language']['already_succ'].'</h3>'.$GLOBALS['language']['already_succ_explain'];
		return false;
	} else {
		// read the temporary file
		if (file_exists($config_file['temporary'])) {
			include $config_file['temporary'];
			$GLOBALS['config'] = $install_config;
		} else {
			$GLOBALS['config'] = array();
		}
	}
}

/* setTmpConfig()
 *
 * Adds a value to the temp config
 *
 * @param string $key
 * @param string $value
 * @param bool $isarray
 *
 * @return bool
 */
function setTmpConfig($key, $value, $isarray = false)
{
	global $language;
	if (!$isarray) {
		$GLOBALS['config'][$key] = $value;
	} else {
		$GLOBALS['config'][$key][] = $value;
		$GLOBALS['config'][$key] = array_unique($GLOBALS['config'][$key]);
	}
	if (!createTempConfig()) {
		// can't write temp config, set error
		$GLOBALS['error'] .= '<br />' . $language['tmp_conf_error'];
		return false;
	}
	return true;
}

/*
* createTempConfig()
*
* Creates a temporary config file or appends new config vars.
*
* @return bool $success
*/
function createTempConfig()
{
	global $language, $config, $config_file, $LINEBREAK;
	if ($handle = @fopen($config_file['temporary'], 'w')) {
		//$config = serialize($config);
		//create php array in config
		$fconfig = '<?php' . $LINEBREAK . arrayToString($config, '$install_config') . $LINEBREAK;
		fwrite($handle, $fconfig);
		fclose($handle);
		return true;
	} else {
		// could not write tmp config, add error
		$GLOBALS['error'] = sprintf($language['cant_write_tmp_conf'], $config_file['temporary']) . ' ' . $language['review_permissions'];
		return false;
	}
}

/*
* sqEsc()
*
* escape single quotes in string
*
* @param string $str
*
* @return string
*/
function sqEsc($str)
{
	return str_replace("'", "\'", $str);
}

/*
* arrayToString()
*
* Creates a text version of an array
*
* @param array $array
* @param string $array_name
* @param string $indent
*
* @return string $array_string
*/
function arrayToString($array, $array_name, $indent = '')
{
	global $LINEBREAK;
	if (is_array($array)) {
		if ($indent == '') {
			$array_string = $indent . $array_name . " = array(" . $LINEBREAK;
		} else {
			$array_string = $indent . "'" .	 $array_name . "' => array(" . $LINEBREAK;
		}

		foreach($array as $key => $value) {
			if (is_array($value)) {
				$array_string .= arrayToString($value, $key, $indent . '	 ');
			} else {
				$value = sqEsc($value);
				$array_string .= $indent . "		'$key' => '$value'," . $LINEBREAK;
			}
		}
		if ($indent == '') {
			$array_string .= ');' . $LINEBREAK;
		} else {
			$array_string .= $indent . '),' . $LINEBREAK;
		}
	} else {
		return $array;
	}

	return $array_string;
}

/*
* getLanguage()
*
* Tries to find the default lang of the user
*
* @return array $language
*/
function getLanguage()
{
	global $config, $language;

	$superCage = Inspekt::makeSuperCage();

	// try to find the users language if we don't have one defined yet
	if (!isset($config['lang'])) {
		include_once 'include/select_lang.inc.php';
		setTmpConfig('lang', $USER['lang']);
		loadTempConfig();
	}

	// change default language
	if ($lang = $superCage->post->getMatched('lang_list', '/^[a-z0-9_-]+$/i')) {
		setTmpConfig('lang', $lang[0]);
		loadTempConfig();
	}
	if ($language == '') {
		include 'lang/english.php';
		$lang_en = $lang_install;
		$lang_en_versioncheck = $lang_versioncheck_php;
		if (isset($config['lang']) && file_exists('lang/' . $config['lang'] . '.php')) {
			// include this lang
			include 'lang/' . $config['lang'] . '.php';
		}
		// provide fallback
		$language = array_merge($lang_en, $lang_install);
		$language['versioncheck'] = isset($lang_versioncheck_php) ? $lang_versioncheck_php : $lang_en_versioncheck;
		$language['lang_common'] = $lang_common;
	}
	return $language;
}

/*
* getLangSelect()
*
* Returns a select box to choose the default labguage
*
* @return string $lang_select
*/
function getLangSelect()
{
	global $config, $LINEBREAK;

	$dir = opendir('lang/');
	$available_languages = array();
	while ($file = readdir($dir)) {
		$extension = ltrim(substr($file,strrpos($file,'.')),'.');
		$filenameWithoutExtension = str_replace('.' . 'php', '', $file);
		if (is_file('lang/' . $file) && $extension == 'php') {
			$available_languages[] = ucfirst($filenameWithoutExtension);
		}
	}
	closedir($dir);
	natcasesort($available_languages);

	$lang_select = '<select name="lang_list" class="listbox" size="1">' . $LINEBREAK;
	foreach($available_languages as $key => $language) {
		$lang_select .= "						<option " . ((strtolower($config['lang']) == strtolower($language)) ? 'selected="selected"' : '') . " value=\"" . strtolower($language). "\">{$language}</option>" . $LINEBREAK;
	}
	$lang_select .= '				</select>';

	return $lang_select;
}

/*
* checkPermissions()
*
* Checks if all folders have the right permissions and exist
*
* @return bool $peCheck
*/
function checkPermissions()
{
	global $config, $language;

	$peCheck = true;
	// If another dir has to be added, you can define as many possible permissions as you want,
	// but if it only has to be a directory, then use the $only_folders array (will only be checked on existence)
	// Always add the maximum required permission as the first item as the installer will try to chmod the files to that value.
	$files_to_check = array(
		'./albums'	=> array('777', '755'),
		'./albums/userpics' => array('777', '755'),
		'./albums/edit'		=> array('777', '755'),
		'./include' => array('777', '755'),

	);

	// clear the file status cache to make sure we are reading the most recent info of the file.
	clearstatcache();

	// start creating table with results
	$temp_data = "<tr><td align=\"center\"><table><tr><td><strong>{$language['directory']}</strong></td><td width=\"10%\"><strong>{$language['status']}</strong></td></tr>";
	foreach($files_to_check as $folder => $perm) {
		// check folder existence
		if (!is_dir($folder)) {
			$peCheck = false;
			$GLOBALS['error'] .= sprintf($language['subdir_called'], $folder) . '<br />';
			$temp_data .= "<tr><td>$folder</td><td><div class=\"cpg_message_error\">{$language['not_exist']}</div></td></tr>";
		} else {
			// try to create a file in the folder
			$test_file = $folder . '/testwritability';
			$file_handle = @fopen($test_file, 'w');
			$mode = substr(sprintf('%o', fileperms($folder)), -3);
			if (!$file_handle) {
				//file could not be created, try to modify the mode
				if (@chmod($folder, (int)("0" . $perm[0]))) {
					// we have changed the mode, jippie :)
					clearstatcache();
					$mode = substr(sprintf('%o', fileperms($folder)), -3);
					// again try to write a file to the folder
					$file_handle2 = @fopen($test_file, 'w');
					if (!$file_handle2) {
						// not working, admin will have to check this by hand, add error
						$peCheck = false;
						$possible_modes_left = implode(' '.$language['or'].' ',array_diff($perm,array($mode)));
						$GLOBALS['error'] .= sprintf($language['perm_error'], $folder, $mode) . ' ' . $possible_modes_left . '.<br />';
						$temp_data .= "<tr><td>$folder</td><td><div class=\"cpg_message_error\">{$language['not_writable']}</div></td></tr>";
					} else {
						//close handle and remove file
						fclose($file_handle2);
						unlink($test_file);
						$temp_data .= "<tr><td>$folder</td><td><div class=\"cpg_message_success\">{$language['writable']}</div></td></tr>";
					}
				} else {
					// could not change mode, add error.
					$peCheck = false;
					$possible_modes_left = implode(' '.$language['or'].' ',array_diff($perm,array($mode)));
					$GLOBALS['error'] .= sprintf($language['perm_error'], $folder, $mode) . ' ' . $possible_modes_left . '.<br />';

					$temp_data .= "<tr><td>$folder</td><td><div class=\"cpg_message_error\">{$language['not_writable']}</div></tr>";
				}
			} else {
				//close file handle and remove file
				fclose($file_handle);
				unlink($test_file);
				$temp_data .= "<tr><td>$folder</td><td><div class=\"cpg_message_success\">{$language['writable']}</div></td></tr>";
			}
		}
	}

	$temp_data .= '</table></td></tr>';
	$GLOBALS['temp_data'] = $temp_data;
	return $peCheck;
}

/*
* checkImageProcessor()
*
* Checks which image processors are available and tries to find IM.
*
* @return array $imagesProcessors
*/
function checkImageProcessor()
{
//	if ($im = getIM()) {
//		$imagesProcessors['im'] = $im;
//	}

	// check basic functionality
	if (checkBasicGD()) {
		$imagesProcessors['gd2'] = 'installed';
	}

	// check for Imagick
	if (extension_loaded('imagick')) {
		$vers = Imagick::getVersion();
		$imagesProcessors['imx'] = $vers['versionString'];
	}

	return $imagesProcessors;
}

/*
* testImageProcessor()
*
* Extensive test on the image processor of choise
*
* @return string $results
*/
function testImageProcessor()
{
	global $config;

	//check which library to use
	switch($config['thumb_method']) {
		case 'gd2':
			$image_processor = new GDtest();
			break;
		case 'im':
			$image_processor = new IMtest($config['im_path']);
			break;
		case 'imx':
			$image_processor = new IMXtest();
			break;
		default:
			$image_processor = new GDtest();
			break;
	}
	$results = createImageTestResult($image_processor->testReadWrite());
	$results .= createImageTestResult($image_processor->testCombineImage());
	$results .= createImageTestResult($image_processor->testTextOnImage());
	$results .= createImageTestResult($image_processor->testScale());

	return $results;
}

/*
* checkBasicGD()
*
* Some basic testing if GD is working correctly.
*
* @param int $gd_version
*
* @return bool
*/
function checkBasicGD()
{
	if (!function_exists('imagecreatetruecolor')) {
		return false;
	}
	$im = imagecreatetruecolor(1, 1);
	$tst_image = "albums/gd2.jpg";
	imagejpeg($im, $tst_image);
	$size = cpgGetimagesize($tst_image);
	@unlink($tst_image);
	if ($size[2] == 2) {
		return true;
	} else {
		return false;
	}
}

/*
* getIM()
*
* Some basic testing if IM is installed & working correctly.
*
* @return array $im
*/
function getIM()
{
	global $config, $language;

	$im_paths = array(
		'/imagemagick/convert',
		'/imagemagick/bin/convert',
		'/local/bin/convert',
		'/local/bin/imagemagick/convert',
		'/local/bin/imagemagick/bin/convert',
		'/usr/local/convert',
		'/usr/local/bin/convert',
		'/usr/local/bin/imagemagick/convert',
		'/usr/local/bin/imagemagick/bin/convert',
		'/usr/bin/convert',
		'C:/Program Files/ImageMagick/convert.exe',
		'C:/ImageMagick/convert.exe',
		'/usr/bin/imagemagick/convert',
		'/usr/bin/imagemagick/bin/convert',
		'/usr/sbin/convert',
		'/bin/convert',
		'/bin/imagemagick/convert',
		'/bin/imagemagick/bin/convert',
		'convert'
		);
	// add trailing slash if necessary
	if (!empty($config['im_path']) && !preg_match('|[/\\\\]\Z|', $config['im_path'])) {
		$config['im_path'] .= '/';
	}
	// add user defined path to paths array
	if (!empty($config['im_path'])) {
		// add unix version
		$im_paths[] = $config['im_path'] . 'convert';
		// add windows version
		$im_paths[] = '"' . $config['im_path'] . 'convert.exe"';
		// both versions are added so we can't make mistakes on finding which OS is used.
	}

	// check if IM is on default path
	foreach ($im_paths as $key => $path) {
		if (stristr($path, ':/')) {
			$path = '"' . $path . '"';
		}
		$command = "$path --version";
		// execute an im command to test if it is working
		@exec($command, $exec_output, $exec_retval);
		$version = @$exec_output[0] . @$exec_output[1];

		if ($version != '') {
			// IM is found and working.
			// check for spaces in the path (we don't want those...)
			if (preg_match('/ /', $path)) {
				$path = str_replace(array('.exe', '"'), '',$path);
				$path = substr($path, 0, (strlen($path) - 7));
				$GLOBALS['error'] = sprintf($language['im_path_space'], $path);
				return false;
			}
			// do a real image conversion check
			$tst_image = "albums/userpics/im.gif";
			exec ("$path images/coppermine-logo.png $tst_image", $output, $result);
			$size = cpgGetimagesize($tst_image);
			@unlink($tst_image);
			$im_installed = ($size[2] == 1);
			// convert tool found, but did not work as expected
			if (!$im_installed) {
				$GLOBALS['error'] = sprintf($language['im_no_convert_ex'], $path);
				return false;
			}
			// convert tool returned errors, add them to our error list
			if ($result && count($output)) {
				$GLOBALS['error'] = $language['conv_said'] . '<br /></pre>';
				foreach($output as $line) {
					$GLOBALS['error'] .= htmlspecialchars($line);
				}
				$GLOBALS['error'] .= "</pre>";
				return false;
			}

			// all went fine, return version info
			$im = array(
				'version' => $version,
				'path' => $path
			);
			return $im;
			break;
		}
	}
	return false;

}


/*
* populateDatabase()
*
* Executes sql file commands in db
*
* @return bool
*/

function populateDatabase()
{
	global $config, $language;

	// define some vars so we can easily find them at the top and change if needed.
	$db_schema = "sql/schema.sql";
	$db_basic = "sql/basic.sql";

	// check if all config values are present.
	if (!isset($config['thumb_method'])) {
		$GLOBALS['error'] = $language['no_thumb_method'];
		return false;
	}
	// Get a connection with the db.
	list($dext, $dsub) = explode(':', $config['db_type'].':');
	$con_check = 'check'.ucfirst($dext).'Connection';
	if (!$con_check($dsub)) {
		return false;
	}
	// Check if we can read the db_schema file
	if (($sch_open = fopen($db_schema, 'r')) === FALSE) {
		$GLOBALS['error'] = sprintf($language['sql_file_not_found'], $db_schema);
		return false;
	} else {
		$sql_query = fread($sch_open, filesize($db_schema));
		// Check if we can read the db_basic file
		if (($bas_open = fopen($db_basic, 'r')) === FALSE) {
			$GLOBALS['error'] = sprintf($language['sql_file_not_found'], $db_basic);
			return false;
		} else {
			$sql_query .= fread($bas_open, filesize($db_basic));
		}
	}
	// Create our fantastic cage object
	$superCage = Inspekt::makeSuperCage();
	require_once 'include/sql_parse.php';
	// Get gallery directory
	$possibilities = array('REDIRECT_URL', 'PHP_SELF', 'SCRIPT_URL', 'SCRIPT_NAME','SCRIPT_FILENAME');
	foreach ($possibilities as $test) {
		if ($matches = $superCage->server->getMatched($test, '/([^\/]+\.php)$/')) {
			$CPG_PHP_SELF = $superCage->server->getEscaped($test);
			break;
		}
	}

	$gallery_dir = strtr(dirname($CPG_PHP_SELF), '\\', '/');
	if ($gallery_dir == '.') {
		$gallery_dir = '';
	}

	$protocol = $superCage->server->keyExists('HTTPS') ? 'https' : 'http';
	$gallery_url_prefix = $protocol . '://' . $superCage->server->getEscaped('HTTP_HOST')
		. $gallery_dir . (substr($gallery_dir, -1) == '/' ? '' : '/');

	// Set configuration values for image package
	$sql_query .= "REPLACE INTO CPG_config VALUES ('thumb_method', '{$config['thumb_method']}');\n";
	if (isset($config['im_path']) && $config['im_path']) {
		$sql_query .= "REPLACE INTO CPG_config VALUES ('impath', '{$config['im_path']}');\n";
	}
	$sql_query .= "REPLACE INTO CPG_config VALUES ('ecards_more_pic_target', '$gallery_url_prefix');\n";

	// Enable silly_safe_mode if test has shown it is not configured properly
	if (checkSillySafeMode()) {
		$sql_query .= "REPLACE INTO CPG_config VALUES ('silly_safe_mode', '1');\n";
	}
	// Test write permissions for main dir
	if (!is_writable('.')) {
		$sql_query .= "REPLACE INTO CPG_config VALUES ('default_dir_mode', '0777');\n";
		$sql_query .= "REPLACE INTO CPG_config VALUES ('default_file_mode', '0666');\n";
	}
	// Update table prefix
	$sql_query = preg_replace('/CPG_/', $config['db_prefix'], $sql_query);

	$sql_query = remove_remarks($sql_query);
	$sql_query = split_sql_file($sql_query, ';');

	if (isset($GLOBALS['temp_data'])) {
		$GLOBALS['temp_data'] .= '<tr><td>';
	} else {
		$GLOBALS['temp_data'] = '<tr><td>';
	}
	foreach($sql_query as $q) {
		$is_table = false;
		//check if we are creating a table so we can add it to the output
		if (preg_match('/(CREATE TABLE IF NOT EXISTS `?|CREATE TABLE `?)([\w]*)`?/i', $q, $table_match)) {
			$table = $table_match[2];
			$is_table = true;
		}
		if (! cpg_db_query($q)) {
			$GLOBALS['error'] = $language['dbase_error'] . cpg_db_getError() . ' ' . $language['on_q'] . " '$q'";
			if ($is_table) {
				$GLOBALS['temp_data'] .= "<br />" . sprintf($language['create_table'], $table)
					. '&nbsp;&nbsp;&nbsp;&nbsp;' . $language['status'] . ':... ' . $language['nok'];
			}
			return false;
		} else {
			if ($is_table) {
				$GLOBALS['temp_data'] .= "<br />" . sprintf($language['create_table'], $table)
					. '&nbsp;&nbsp;&nbsp;&nbsp;' . $language['status'] . ':... ' . $language['ok'];
			}
		}
	}
	$GLOBALS['temp_data'] .= '<br /><br /></td></tr>';
	return true;
}

/*
* createAdmin()
*
* Creates the Coppermine admin.
*
* @return bool
*/
function createAdmin()
{
	global $CONFIG, $config, $language;

	if (!isset($config['admin_username']) || $config['admin_username'] == '') { $GLOBALS['error'] = $language['no_admin_username'];		return false;}
	if (!isset($config['admin_password']) || $config['admin_password'] == '') { $GLOBALS['error'] = $language['no_admin_password'];		return false;}
	if (!isset($config['admin_email']) || $config['admin_email'] == '')	 { $GLOBALS['error'] = $language['no_admin_email'];		return false;}

	require 'include/passwordhash.inc.php';
	$password_params = explode(':', cpg_password_create_hash($config['admin_password']));

	// Insert the admin account
	$sql_query = "INSERT INTO {$config['db_prefix']}users "
		. "(user_group, user_active, user_name, user_password, user_password_salt, "
		. " user_password_hash_algorithm, user_password_iterations, user_lastvisit, "
		. " user_regdate, user_group_list, user_email, user_profile1, user_profile2, "
		. " user_profile3, user_profile4, user_profile5, user_profile6, user_actkey) "
		. "VALUES "
		. "(1, 'YES', '{$config['admin_username']}', '{$password_params[HASH_PBKDF2_INDEX]}', "
		. " '{$password_params[HASH_SALT_INDEX]}', '{$password_params[HASH_ALGORITHM_INDEX]}', '{$password_params[HASH_ITERATION_INDEX]}', "
		. " NOW(), NOW(), '', '{$config['admin_email']}', '', '', '', '', '', '', '');\n";

	// Set gallery admin mail
	$sql_query .= "REPLACE INTO CPG_config VALUES ('gallery_admin_email', '{$config['admin_email']}');\n";

	// Update table prefix
	$sql_query = preg_replace('/CPG_/', $config['db_prefix'], $sql_query);

	require_once 'include/sql_parse.php';
	$sql_query = remove_remarks($sql_query);
	$sql_query = split_sql_file($sql_query, ';');
	// Get a connection with the db.
//	  if (!checkSqlConnection()) {
//		  return false;
//	  }
	foreach($sql_query as $q) {
		if (!cpg_db_query($q)) {
			$GLOBALS['error'] = $language['dbase_error'] . cpg_db_getError() . ' ' . $language['on_q'] . " '$q'";
			return false;
		}
	}
	return true;
}


/*
* checkSillySafeMode()
*
* Test if safe mode is misconfigured
*
* @return bool
*/
function checkSillySafeMode()
{
	$test_file = "albums/userpics/dummy/dummy.txt";
	@mkdir(dirname($test_file), 0755);
	$fd = @fopen($test_file, 'w');
	if (!$fd) {
		@rmdir(dirname($test_file));
		return true;
	}
	fclose($fd);
	@unlink($test_file);
	@rmdir(dirname($test_file));
	return false;
}

/*
* finalCheck()
*
* Check if everything is configured correctly
*
* @return array $results
*/
function writeConfig()
{
	global $config, $language;

	foreach (['db_type','db_host','db_user','db_password','db_name','db_prefix'] as $ix) {
		$config[$ix] = sqEsc($config[$ix]);
	}

	$config = <<<EOT
<?php
// Coppermine configuration file
// Database configuration
\$CONFIG['dbtype'] =	  '{$config['db_type']}';			// Your database type
\$CONFIG['dbserver'] =	  '{$config['db_host']}';			// Your database server
\$CONFIG['dbuser'] =	  '{$config['db_user']}';			// Your database username
\$CONFIG['dbpass'] =	  '{$config['db_password']}';			// Your database password
\$CONFIG['dbname'] =	  '{$config['db_name']}';			// Your database name

// DATABASE TABLE NAMES PREFIX
\$CONFIG['TABLE_PREFIX'] =		   '{$config['db_prefix']}';
EOT;
	//write config file to disk
	if ($fd = @fopen('include/config.inc.php', 'wb')) {
		fwrite($fd, $config);
		fclose($fd);
	} else {
		$GLOBALS['error'] = '<hr /><br />' . $language['unable_write_config'] . '<br />';
	}
}

/*
 * function createImageTestResult()
 *
 * Creates a table to show the results of a test
 *
 * @param array $results
 *
 * @return string $tables
 */
function createImageTestResult($results)
{
	global $config, $language;

	$tables = '';

	foreach($results as $test_title => $test_result) {
		if (isset($test_result['error'])) {
			//there was an error, show this to the user
			$result_error_tpl = <<<EOT
	<table>
		<tr>
			<th colspan="3" align="left">{$language[$test_title]}</th>
		</tr>
		<tr>
			<td>{$language[$test_result['error']]}</td>
			<td>{$language['generated_image']}</td>
			<td>{$language['reference_image']}</td>
		</tr>
	</table>
	<br />
EOT;
			$tables .= $result_error_tpl;
			$GLOBALS['error'] = $language['imp_test_error'];
		} else {
			//all went as it had to, put info on template
			$generated_size = cpgGetimagesize($test_result['created']);
			$generated_size = $generated_size[0] . 'x' . $generated_size[1];
			$reference_size = cpgGetimagesize($test_result['original']);
			$reference_size = $reference_size[0] . 'x' . $reference_size[1];
			$result_ok_tpl = <<<EOT
	<table>
		<tr>
			<th colspan="2" align="left">{$language[$test_title]}</th>
		</tr>
		<tr>
			<td width="200px"><img src="{$test_result['created']}" /></td>
			<td><img src="{$test_result['original']}" /></td>
		</tr>
		<tr>
			<td>{$language['generated_image']}</td>
			<td>{$language['reference_image']}</td>
		</tr>
		<tr>
			<td>$generated_size {$language['pixels']}</td>
			<td>$reference_size {$language['pixels']}</td>
		</tr>
	</table>
	<br />
EOT;
			$tables .= $result_ok_tpl;
		}
	}

	return $tables;
}

/*
 * function cpgGetimagesize()
 *
 * Try to get the size of an image, this is custom built as some webhosts disable this function or do weird things with it
 *
 * @param string $image
 * @param boolean $force_cpg_function
 *
 * @return array $size
 */
function cpgGetimagesize($image, $force_cpg_function = false)
{
	if (!function_exists('getimagesize') || $force_cpg_function) {
		//custom function borrowed from http://www.wischik.com/lu/programmer/get-image-size.html
		$f = @fopen($image, 'rb');
		if ($f === false) {
			return false;
		}
		fseek($f, 0, SEEK_END);
		$len = ftell($f);
		if ($len < 24) {
			fclose($f);
			return false;
		}
		fseek($f, 0);
		$buf = fread($f, 24);
		if ($buf === false) {
			fclose($f);
			return false;
		}
		if (ord($buf[0]) == 255 && ord($buf[1]) == 216 && ord($buf[2]) == 255 && ord($buf[3]) == 224 && $buf[6] == 'J' && $buf[7] == 'F' && $buf[8] == 'I' && $buf[9] == 'F') {
			$pos=2;
			while (ord($buf[2]) == 255) {
				if (ord($buf[3]) == 192 || ord($buf[3]) == 193 || ord($buf[3]) == 194 || ord($buf[3]) == 195 || ord($buf[3]) == 201 || ord($buf[3]) == 202 || ord($buf[3]) == 203) {
					break; // we've found the image frame
				}
				$pos += 2 + (ord($buf[4]) << 8) + ord($buf[5]);
				if ($pos+12>$len) {
					break; // too far
				}
				fseek($f,$pos);
				$buf = $buf[0] . $buf[1] . fread($f,12);
			}
		}
		fclose($f);

		// GIF:
		if ($buf[0] == 'G' && $buf[1] == 'I' && $buf[2] == 'F') {
			$x = ord($buf[6]) + (ord($buf[7])<<8);
			$y = ord($buf[8]) + (ord($buf[9])<<8);
			$type = 1;
		}

		// JPEG:
		if (ord($buf[0]) == 255 && ord($buf[1]) == 216 && ord($buf[2]) == 255) {
			$y = (ord($buf[7])<<8) + ord($buf[8]);
			$x = (ord($buf[9])<<8) + ord($buf[10]);
			$type = 2;
		}

		// PNG:
		if (ord($buf[0]) == 0x89 && $buf[1] == 'P' && $buf[2] == 'N' && $buf[3] == 'G' && ord($buf[4]) == 0x0D && ord($buf[5]) == 0x0A && ord($buf[6]) == 0x1A && ord($buf[7]) == 0x0A && $buf[12] == 'I' && $buf[13] == 'H' && $buf[14] == 'D' && $buf[15] == 'R') {
			$x = (ord($buf[16])<<24) + (ord($buf[17])<<16) + (ord($buf[18])<<8) + (ord($buf[19])<<0);
			$y = (ord($buf[20])<<24) + (ord($buf[21])<<16) + (ord($buf[22])<<8) + (ord($buf[23])<<0);
			$type = 3;
		}

		if (!isset($x, $y, $type)) {
			return false;
		}
		return array($x, $y, $type, 'height="' . $x . '" width="' . $y . '"');
	} else {
		$size = @getimagesize($image);
		if (!$size) {
			//false was returned
			return cpgGetimagesize($image, true/*force the use of custom function*/);
		}elseif (!isset($size[0]) || !isset($size[1])) {
			//webhost possibly changed getimagesize functionality
			return cpgGetimagesize($image, true/*force the use of custom function*/);
		}else {
			//function worked as expected, return the results
			return $size;
		}
	}

}

########################
###### GDtest Class ####
########################
class GDtest
{
	var $image_path = 'albums/'; //path to store temp images

	/*
	 * Initializes the class.
	 *
	 * @param int $version
	 * @param string $image_path
	 */
	function __construct($image_path = '')
	{
		if ($image_path != '') {
			$this->image_path = $image_path;
		}
	}

	/*
	 * function testRead()
	 *
	 * Do basic tests on reading and writing file formats
	 *
	 * @return array $results
	 */
	function testReadWrite()
	{
		//create gif test image
		$test_gif = imagecreatefromgif ('images/install/giftest.gif');
		if (!$test_gif) {
			//put error in array
			$results['read_gif'] = array(
					'error'		=> 'read_error',
				);
		} else {
			if (imagegif ($test_gif, $this->image_path . 'giftest_generated.gif')) {
				//put results in array
				$results['read_gif'] = array(
					'original'	=> 'images/install/giftest.gif',
					'created'	=> $this->image_path . 'giftest_generated.gif',
				);
			}else {
				//put error in array
				$results['read_gif'] = array(
					'error'		=> 'write_error',
				);
			}
		}
		@imagedestroy($test_gif);

		//create png test image
		$test_png = imagecreatefrompng('images/install/pngtest.png');
		if (!$test_png) {
			//put error in array
				$results['read_png'] = array(
					'error'		=> 'read_error',
				);
		} else {
			if (imagepng($test_png, $this->image_path . 'pngtest_generated.png')) {
				//put results in array
				$results['read_png'] = array(
					'original'	=> 'images/install/pngtest.png',
					'created'	=> $this->image_path . 'pngtest_generated.png'
				);
			} else {
				//put error in array
				$results['read_png'] = array(
					'error'		=> 'write_error',
				);

			}
		}
		@imagedestroy($test_png);

		//create jpg test image
		$test_jpg = imagecreatefromjpeg('images/install/jpgtest.jpg');
		if (!$test_jpg) {
			//put error in array
				$results['read_jpg'] = array(
					'error'		=> 'read_error',
				);
		} else {
			if (imagejpeg($test_jpg, $this->image_path . 'jpgtest_generated.jpg')) {
				//put results in array
				$results['read_jpg'] = array(
					'original'	=> 'images/install/jpgtest.jpg',
					'created'	=> $this->image_path . 'jpgtest_generated.jpg',
				);
			}else {
				//put error in array
				$results['read_jpg'] = array(
					'error'		=> 'write_error',
				);

			}
		}
		@imagedestroy($test_jpg);

		return $results;
	}

	/*
	 * function testCombineImage()
	 *
	 * test combining of images
	 *
	 * @return array $results
	 */
	function testCombineImage()
	{
		$source_a = imagecreatefromjpeg('images/install/jpgtest.jpg');
		$source_b = imagecreatefromgif ('images/install/combine_b.gif');
		imagecopymerge($source_a, $source_b, 66, 1, 0, 0, imagesx($source_b), imagesy($source_b), 100);

		if (imagejpeg($source_a, $this->image_path . 'combined_generated.jpg')) {
			//put results in array
			$results['combine'] = array(
				'original'	=> 'images/install/combined.jpg',
				'created'	=> $this->image_path . 'combined_generated.jpg',
			);
		}else {
			//put error in array
			$results['combine'] = array(
				'error'		=> 'write_error',
			);
		}
		@imagedestroy($source_a);
		@imagedestroy($source_b);

		return $results;
	}

	/*
	 * function testTextOnImage()
	 *
	 * test adding text to images
	 *
	 * @return array $results
	 */
	function testTextOnImage()
	{
		$text = '2008 © Susanna Thornton';
		$font = 'images/fonts/LiberationSans-Regular.ttf';
		$source = imagecreatefromjpeg('images/install/jpgtest.jpg');
		$front_color = imagecolorallocate($source, 255, 255, 255);

		imagettftext($source, 9/*size*/, 0/*angle*/, 55/*left*/, 110/*top*/, $front_color/*color*/, $font, $text);
		if (imagejpeg($source, $this->image_path . 'texttest_generated.jpg')) {
			//put results in array
			$results['text'] = array(
				'original'	=> 'images/install/texttest.jpg',
				'created'	=> $this->image_path . 'texttest_generated.jpg',
			);
		}else {
			//put error in array
			$results['text'] = array(
				'error'		=> 'write_error',
			);
		}
		@imagedestroy($source);

		return $results;
	}

	/*
	 * function testScale()
	 *
	 * test scaling of images
	 *
	 * @return array $results
	 */
	 function testScale()
	{
		$image = imagecreatefromjpeg('images/install/jpgtest.jpg');
		$generated = @imagecreatetruecolor(100, 57);
		$final = @imagecopyresampled($generated, $image, 0, 0, 0, 0, 100, 57, 200, 113);
		if (!$final) {
			$final = @imagecopyresized($generated, $image, 0, 0, 0, 0, 100, 57, 200, 113);
		}
		imagejpeg($generated, $this->image_path . 'scaled_generated.jpg');

		if ($final) {
			//put results in array
			$results['scale'] = array(
				'original'	=> 'images/install/scaled.jpg',
				'created'	=> $this->image_path . 'scaled_generated.jpg',
			);
		} else {
			//put error in array
			$results['scale'] = array(
				'error'		=> 'scale_error',
			);
		}

		return $results;
	 }

}

########################
###### IMtest Class ####
########################
class IMtest
{
	var $image_path = 'albums/'; //path to store temp images
	var $IMpath = ''; //path to imageMagick
	var $CPGpath = ''; //path to root cpg folder

	/*
	 * Initializes the class.
	 *
	 * @param string $IMpath
	 * @param string $image_path
	 */
	function __construct($IMpath, $image_path = '')
	{
		// add trailing slash if necessary
		if (!empty($IMpath) && !preg_match('|[/\\\\]\Z|', $IMpath)) {
			$IMpath .= '/';
		}
		$this->IMpath = $IMpath . 'convert';
		if ($image_path != '') {
			$this->image_path = $image_path;
		}
		$this->CPGpath = realpath('./');
		$this->CPGpath = str_replace('\\', '/', $this->CPGpath);
	}

	/*
	 * function createImagePath()
	 *
	 * Creates the path to the images, $dest is to tell
	 * if we are using the destination path
	 *
	 * @param string $image_path
	 * @param boolean $dest
	 *
	 * @return string $path
	 */
	function createImagePath($image_path, $dest = false)
	{
		if ($dest) {
			$path = $this->image_path . $image_path;
		} else {
			$path = $image_path;
		}
		return $path;
	}

	/*
	 * function testRead()
	 *
	 * Do basic tests on reading and writing file formats
	 *
	 * @return array $results
	 */
	function testReadWrite()
	{
		$output = array();

		//create gif test image
		$gif_command = '' . $this->IMpath . ' ' . $this->createImagePath('images/install/giftest.gif')
			. ' ' . $this->createImagePath('giftest_generated.jpg', true);
		exec($gif_command, $output, $retval);
		if ($retval) {
			//an error occured, add to array
			$results['read_gif'] = array(
					'error'		=> 'read_error',
				);
		} else {
			//all went fine
			$results['read_gif'] = array(
					'original'	=> 'images/install/giftest.gif',
					'created'	=> $this->image_path . 'giftest_generated.jpg',
				);
		}

		//create png test image
		$png_command = $this->IMpath . ' ' . $this->createImagePath('images/install/pngtest.png')
			. ' ' . $this->createImagePath('pngtest_generated.jpg', true);
		exec($png_command, $output, $retval);

		if ($retval) {
			//an error occured, add to array
			$results['read_png'] = array(
					'error'		=> 'read_error',
				);
		} else {
			//all went fine
			$results['read_png'] = array(
					'original'	=> 'images/install/pngtest.png',
					'created'	=> $this->image_path . 'pngtest_generated.jpg',
				);
		}

		//create jpg test image
		$jpg_command = $this->IMpath . ' ' . $this->createImagePath('images/install/jpgtest.jpg')
			. ' ' . $this->createImagePath('jpgtest_generated.jpg', true);
		exec($jpg_command, $output, $retval);

		if ($retval) {
			//an error occured, add to array
			$results['read_jpg'] = array(
					'error'		=> 'read_error',
				);
		} else {
			//all went fine
			$results['read_jpg'] = array(
					'original'	=> 'images/install/jpgtest.jpg',
					'created'	=> $this->image_path . 'jpgtest_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testCombineImage()
	 *
	 * test combining of images
	 *
	 * @return array $results
	 */
	function testCombineImage()
	{
		$source_a = 'images/install/jpgtest.jpg';
		$source_b = 'images/install/combine_b.gif';

		$combine_command = $this->IMpath . ' ' . $this->createImagePath($source_a)
			. ' ' . $this->createImagePath($source_b) . ' -geometry +66+1 -composite '
			. $this->createImagePath('combined_generated.jpg', true);

		exec($combine_command, $output, $retval);
		if ($retval) {
			//an error occured, add to array
			$results['combine'] = array(
					'error'		=> 'combine_error',
				);
		} else {
			//all went fine
			$results['combine'] = array(
					'original'	=> 'images/install/combined.jpg',
					'created'	=> $this->image_path . 'combined_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testTextOnImage()
	 *
	 * test adding text to images
	 *
	 * @return array $results
	 */
	function testTextOnImage()
	{
		$text = '2008 � Susanna Thornton';
		$font = 'images/fonts/LiberationSans-Regular.ttf';
		$source = 'images/install/jpgtest.jpg';

		$text_command = '' . $this->IMpath . ' ' . $this->createImagePath($source)
			. ' -fill white -font ' . $font . ' -pointsize 12 -draw "text  50,110 \''
			. $text . '\'" ' . $this->createImagePath('texttest_generated.jpg', true);

		exec($text_command, $output, $retval);
		if ($retval) {
			//an error occured, add to array
			$results['text'] = array(
					'error'		=> 'text_error',
				);
		} else {
			//all went fine
			$results['text'] = array(
					'original'	=> 'images/install/texttest.jpg',
					'created'	=> $this->image_path . 'texttest_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testScale()
	 *
	 * test scaling of images
	 *
	 * @return array $results
	 */
	function testScale()
	{
		$scale_command = $this->IMpath . ' -geometry 100x57 '
			. $this->createImagePath('images/install/jpgtest.jpg') . ' '
			. $this->createImagePath('scaled_generated.jpg', true);
		exec($scale_command, $output, $retval);

		if ($retval) {
			//put error in array
			$results['scale'] = array(
				'error'		=> 'scale_error',
			);
		} else {
			//put results in array
			$results['scale'] = array(
				'original'	=> 'images/install/scaled.jpg',
				'created'	=> $this->image_path . 'scaled_generated.jpg',
			);
		}

		return $results;
	}

}

########################
##### IMXtest Class ####
########################
class IMXtest
{
	var $image_path = 'albums/'; //path to store temp images

	/*
	 * Initializes the class.
	 *
	 * @param string $image_path
	 */
	function __construct ($image_path = '')
	{
		if ($image_path != '') {
			$this->image_path = $image_path;
		}
	}

	/*
	 * function createImagePath()
	 *
	 * Creates the path to the images, $dest is to tell
	 * if we are using the destination path
	 *
	 * @param string $image_path
	 * @param boolean $dest
	 *
	 * @return string $path
	 */
	function createImagePath($image_path, $dest = false)
	{
		if ($dest) {
			$path = $this->image_path . $image_path;
		} else {
			$path = $image_path;
		}
		return $path;
	}

	/*
	 * function testRead()
	 *
	 * Do basic tests on reading and writing file formats
	 *
	 * @return array $results
	 */
	function testReadWrite()
	{
		$imgObj = new Imagick();

		//create gif test image
		$retval = '';
		try {
			$imgObj->readImage($this->createImagePath('images/install/giftest.gif'));
			$imgObj->writeImage($this->createImagePath('giftest_generated.jpg', true));
			$imgObj->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//an error occured, add to array
			$results['read_gif'] = array(
					'error'		=> 'read_error: '.$retval,
				);
		} else {
			//all went fine
			$results['read_gif'] = array(
					'original'	=> 'images/install/giftest.gif',
					'created'	=> $this->image_path . 'giftest_generated.jpg',
				);
		}

		//create png test image
		$retval = '';
		try {
			$imgObj->readImage($this->createImagePath('images/install/pngtest.png'));
			$imgObj->writeImage($this->createImagePath('pngtest_generated.jpg', true));
			$imgObj->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//an error occured, add to array
			$results['read_png'] = array(
					'error'		=> 'read_error: '.$retval,
				);
		} else {
			//all went fine
			$results['read_png'] = array(
					'original'	=> 'images/install/pngtest.png',
					'created'	=> $this->image_path . 'pngtest_generated.jpg',
				);
		}

		//create jpg test image
		$retval = '';
		try {
			$imgObj->readImage($this->createImagePath('images/install/jpgtest.jpg'));
			$imgObj->writeImage($this->createImagePath('jpgtest_generated.jpg', true));
			$imgObj->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//an error occured, add to array
			$results['read_jpg'] = array(
					'error'		=> 'read_error: '.$retval,
				);
		} else {
			//all went fine
			$results['read_jpg'] = array(
					'original'	=> 'images/install/jpgtest.jpg',
					'created'	=> $this->image_path . 'jpgtest_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testCombineImage()
	 *
	 * test combining of images
	 *
	 * @return array $results
	 */
	function testCombineImage()
	{
		$source_a = 'images/install/jpgtest.jpg';
		$source_b = 'images/install/combine_b.gif';
		$retval = '';

		try {
			$imgObjA = new Imagick($this->createImagePath($source_a));
			$imgObjB = new Imagick($this->createImagePath($source_b));
			$imgObjA->compositeImage($imgObjB, imagick::COMPOSITE_DEFAULT, 66, 1);
			$imgObjA->writeImage($this->createImagePath('combined_generated.jpg', true));
			$imgObjA->clear();
			$imgObjB->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//an error occured, add to array
			$results['combine'] = array(
					'error'		=> 'combine_error: '.$retval,
				);
		} else {
			//all went fine
			$results['combine'] = array(
					'original'	=> 'images/install/combined.jpg',
					'created'	=> $this->image_path . 'combined_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testTextOnImage()
	 *
	 * test adding text to images
	 *
	 * @return array $results
	 */
	function testTextOnImage()
	{
		$text = '2008 � Susanna Thornton';
		$font = 'images/fonts/LiberationSans-Regular.ttf';
		$source = 'images/install/jpgtest.jpg';
		$retval = '';

		try {
			$imgObj = new Imagick($this->createImagePath($source));
			$draw = new ImagickDraw();
			$draw->setFont($font);
			$draw->setFontSize(12);
			$draw->setFillColor("#FFF");
			$draw->setStrokeAntialias(true);
			$draw->setTextAntialias(true);
			$draw->annotation(50, 110, $text);
			$imgObj->drawImage($draw);
			$imgObj->writeImage($this->createImagePath('texttest_generated.jpg', true));
			$draw->destroy();
			$imgObj->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//an error occured, add to array
			$results['text'] = array(
					'error'		=> 'text_error: '.$retval,
				);
		} else {
			//all went fine
			$results['text'] = array(
					'original'	=> 'images/install/texttest.jpg',
					'created'	=> $this->image_path . 'texttest_generated.jpg',
				);
		}

		return $results;
	}

	/*
	 * function testScale()
	 *
	 * test scaling of images
	 *
	 * @return array $results
	 */
	function testScale()
	{
		$retval = '';

		try {
			$imgObj = new Imagick($this->createImagePath('images/install/jpgtest.jpg'));
			$imgObj->scaleImage(100, 57);
			$imgObj->writeImage($this->createImagePath('scaled_generated.jpg', true));
			$imgObj->clear();
		} catch (Exception $e) {
			$retval = $e->getMessage();
		}

		if ($retval) {
			//put error in array
			$results['scale'] = array(
				'error'		=> 'scale_error: '.$retval,
			);
		} else {
			//put results in array
			$results['scale'] = array(
				'original'	=> 'images/install/scaled.jpg',
				'created'	=> $this->image_path . 'scaled_generated.jpg',
			);
		}

		return $results;
	}

}

//EOF
