<?php
class checkspam {
	var $session_start = true;
	var $style = array();
	var $path = "./";
	var $path_url	= "./";

	var $imagetext;
	var $tmp_img;
	var $tmp_char;
	var $graphic;
	var $sess_name;
	var $sess_value;
	var $sess_counter = 0;
	var $gd_info = array();
	var $font = array();
	var $font_map = array();
	
	var $log = "LOG STARTS HERE:\n-----\n";
	
	function checkspam($path="./", $pathurl="./"){

		$this->path = $path;
		$this->path_url	= $pathurl;
		$this->free();

		$this->style['text-align']			= "center";
		$this->style['font-size']			= "14";
		$this->style['font-family']			= "courier, verdana, arial";
		$this->style['color']				= "#FF0000";
		$this->style['background-color']	= "#F5F5F5";
		$this->style['border-width']		= "2px";
		$this->style['border-style']		= "solid";
		$this->style['border-color']		= "#FFCC00";
		$this->style['width']				= "80px";
		$this->style['line-height']			= "20px";

		$x = 0;
		for ($i = 97; $i <= 122; $i++){
			$this->font_map[chr($i)] = $x;
			$x += 40;
		}
		for ($i = 0; $i <= 9; $i++){
			$this->font_map[$i] = $x;
			//Next character
			$x += 40;
		}
	}
	
	function free(){
		foreach(glob($this->path."images/*.png") as $tmp)
			unlink($tmp);
	}
	
	function register_session(){
		$this->sess_name = "checkSpam".session_id().$this->sess_counter;
		$this->sess_value = $this->create_secretcode();
		
		$_SESSION[$this->sess_name] = $this->sess_value;
		$this->write_log("Session: $this->sess_name registered successfully with the value of: $this->sess_value !");
		
		$this->sess_counter++;
	}
	
	function create_secretcode(){
		return substr(md5(rand()),0,5);
	}
	
	function create_image(){
		$this->imagetext = imagecreatetruecolor(200,60);
		imagefilledrectangle($this->imagetext,0,0,200,60,imagecolorallocate($this->imagetext,rand(120,255),rand(120,255),rand(120,255)));
		
		// Adding some backgrounds distortion objects
		for ($i = 1; $i < 10; $i++) {
			imagefilledrectangle($this->imagetext,rand(0,100),rand(0,30),rand(100,200),rand(30,60),imagecolorallocate($this->imagetext,rand(120,255),rand(120,255),rand(120,255)));
			imagefilledellipse($this->imagetext,rand(0,200),rand(0,60),rand(25,50),rand(25,50),imagecolorallocate($this->imagetext,rand(120,255),rand(120,255),rand(120,255)));
		}
		
		//Load the fonts
		$font_dir = opendir($this->path."font");
		while ( ($font = readdir($font_dir)) !== false ) {
			// Some file controls
			if ( is_file($this->path."font/".$font) and (strtolower(substr($font, strlen($font) - 3, 3)) == "png") ) {
				$this->font[] = imagecreatefrompng($this->path."font/".$font);
				$this->write_log("Loaded PNG Image font: ".$font);
			}
		}
		closedir($font_dir);
		
		// Add the secret code
		$x = 0;	// Distance from each character
		for($i = 0; $i < strlen($this->sess_value); $i++) {
			// Create the temporary character image
			$this->tmp_char = imagecreatetruecolor(40,40);
			
			// Take the character and do some distortion effects
			imagecopy($this->tmp_char,$this->font[rand(0,count($this->font) - 1)],0,0,$this->font_map[$this->sess_value{$i}],0,40,40);
			imagetruecolortopalette($this->tmp_char,false,32); // Convert a true color image character to a palette image with 32 colors
			imagecolortransparent($this->tmp_char,1); // Set transparent for the background color white
			imagecolorset($this->tmp_char,0,rand(0,200),rand(0,200),rand(0,200)); // Random color for the temporary character
			
			// Copy the resized temporary character into the final image
			imagecopyresized($this->imagetext, $this->tmp_char, $x, rand(0,30), 0, 0, rand(20,60), rand(20,60), 40, 40);
			
			// Go to the next character
			$x += 40;
			
			// Destroy temporary character image
			imagedestroy($this->tmp_char);
		}
		
		// Adding noise
		$noise_color = imagecolorallocate($this->imagetext,255,255,255);
		for ($i = 0; $i <= 250; $i++) {
			imagesetpixel($this->imagetext,rand(0,200),rand(0,60),$noise_color);
		}
		
		// Save the temporary image into the path of the class
		$this->tmp_img = $this->path."images/".$this->sess_name.time();
		imagepng($this->imagetext,$this->tmp_img.".png");
	}
	
	function create_imagetext(){
		// Check if the graphic mode is enabled or the GD Library Extension is available
		if($this->graphic && $this->check_gdlibrary()){
			// Call the function to create the temporary image verfication
			$this->create_image();
			$this->imagetext = "<img src=\"".str_replace($this->path, $this->path_url, $this->tmp_img).".png\" border=\"0\" alt=\"secret code\" title=\"secret code\" />";
			$this->write_log("Starts create IMAGE verification !");
		}else{
			// Text mode
			$this->imagetext = "<div style=\"";
			foreach($this->style as $key => $value){
				$this->imagetext .= "$key:$value; ";
			}
			$this->imagetext .= "\">$this->sess_value</div>";
			$this->write_log("Starts create TEXT verification !");
		}
	}
	
	function check_gdlibrary(){
		if(function_exists('gd_info')){
			$this->gd_info = gd_info();
			if($this->gd_info['PNG Support']){
				$this->write_log("GD Library Extension are available, version: ".$this->gd_info['GD Version']." with PNG Support !");
				return true;
			}else{
				$this->write_log("GD Library Extension are available, version: ".$this->gd_info['GD Version']." without PNG Support !");
				return false;
			}
		}else{
			$this->write_log("GD Library Extension are not available !");
			return false;
		}
	}
	
	function write_log($message){
		if(strlen($message) > 0)
			$this->log .= date("[m d Y - H:i]")." $message\n";
	}
	
	function init_session(){
		if(!session_id() && $this->session_start){
			session_start();
			$this->write_log("Sessions started !");
		}else{
			$this->write_log("Sessions is already started !");
		}
	}
	
	function exec_checkspam($type = 1){
		// Set the type of verification
		$this->graphic = ($type == 1) ? true : false;
		$this->register_session();
		// Starts building new code image/text verification
		$this->create_imagetext();
	}
	
	function print_imagetext(){
		echo $this->imagetext;
	}
	
	function print_input($params = "name=\"secretcode\""){
		// Check if exist an image / text code verification to input
		if($this->sess_counter != 0){
			echo "<input type=\"hidden\" name=\"checkspam\" value=\"$this->sess_name\" />";
			echo "<input type=\"text\" $params maxlength=\"".strlen($this->sess_value)."\" / onKeyDown=\"changeCSS(this, 'text');\" class=\"inputbox\">";
			$this->write_log("Input form printed out for: $this->sess_name !");
		}else{
			$this->write_log("Image or text does not exist for the verification of the code for: $this->sess_name !");
		}
	}
	
	function verify($code){
	
		if(isset($_POST["checkspam"])){
			$this->sess_value = $_SESSION[$_POST["checkspam"]];
			//echo $this->sess_value;
		}else{
			if(isset($_GET["checkspam"])){
				$this->sess_value = $_SESSION[$_GET["checkspam"]];
			}else{
				return false;
			}
		}
		return ($code == $this->sess_value) ? true : false;
	}
	
	function print_log(){
		echo "<pre style=\"color:#CCCCCC;background-color:#000000;padding:3px;\">$this->log</pre>";
	}
}
?>
