<?php
$autoStart = false;
include_once('../../wiki.php');
//include_once('../wiki2.php'); //for error log

// requires gd
//	-	 imagecreate()

class captcha{
	var $image;
	var $charWidth;
	var $x;
	var $y;
	var $width;
	var $height;

 
	function captcha(){
		global $wbUniq,$includeDir;
		
		$this->charWidth = 19;
		$this->height = 32;
		$this->x = 10;
		$this->y = 7;
		
	    list($usec, $sec) = explode(' ', microtime());
	    $seed = (float) $sec + ((float) $usec * 100000);
		srand($seed);
		
		//prep the text
		$text = md5($wbUniq.$_GET['r']);
		$text = strtolower($text);
		//we just use the integers so there aren't problems with foreign alphabets
		$text = str_replace(array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'),array(''),$text);
		$text = substr($text,1,6);
		
		//sizes
		$this->width = (6*$this->charWidth)+10;
		
		
		// start the image
		$this->image = imagecreate($this->width, $this->height);
		imagecolorallocate($this->image, 255, 255, 255); //first call sets background color
		
		
		$this->addNoise();
		$this->addChars($text);
		
		
		if( function_exists('imagefilter') ){
			//imagefilter($this->image,IMG_FILTER_GAUSSIAN_BLUR); //this works well
			imagefilter($this->image,IMG_FILTER_SMOOTH,10);  //this works well
		}
		
		//output
		header('Content-Type: image/jpeg');
		imagejpeg($this->image);
		imagedestroy($this->image);
	}
		
	function addNoise(){
		
		
		$blue = $green = $red = 150;
		$which = rand(1,3);
		if( $which === 3 ){
			$red = rand(200,240);
		}elseif( $which === 2 ){
			$green = rand(200,240);
		}else{
			$blue = rand(200,240);
		}
		$noise_color = imagecolorallocate($this->image, $red,$green,$blue);
		
		// noise - dots
		for( $i=0; $i<($this->width*$this->height)/3; $i++ ) {
			imagefilledellipse($this->image, rand(0,$this->width), rand(0,$this->height), 1, 1, $noise_color);
		}
		
		// noise - lines
		imagesetthickness($this->image,1);
		for( $i=0; $i<($this->width*$this->height)/150; $i++ ) {
			imageline($this->image, rand(0,$this->width), rand(0,$this->height), rand(0,$this->width), rand(0,$this->height), $noise_color);
		}		
	}
	
	function addChars($text){
		while(strlen($text) > 0){
			$char = $text{0};
			$text = substr($text,1);
			$this->drawChar($char);
			$this->x += $this->charWidth;
		}
	}
	
	function drawChar($char){
		
		$red = rand(40,60);
		$green = rand(40,60);
		$blue = rand(40,60);
		
		$which = rand(1,3);
		if( $which === 3 ){
			$red = rand(100,190);
		}elseif( $which === 2 ){
			$green = rand(100,190);
		}else{
			$blue = rand(100,190);
		}
		$color = imagecolorallocate($this->image, $red, $green, $blue );
		imagesetthickness($this->image,rand(2,4));
		
		$coords = $this->getCoords($char);
		foreach($coords as $coord){
			$fact = rand(.8,1);
			$fact = 1;
			imageline($this->image, ($this->x+($fact*$coord[0])),($this->y+($fact*$coord[1])) , ($this->x+($fact*$coord[2])), ($this->y+($fact*$coord[3])), $color);
		}
	}
	
	
	//a little bulkier this way than using a font file
	// but this way we don't have to worry about which fonts are available on distributed systems
	function getCoords($char){
		
		//coordinates are array(x1, y1, x2, y2)
		switch($char){
			//numbers
				case '1':
					return array( array(9,0,9,17) );
					
				case '2':
					return array( array(0,0,9,0),array(9,0,9,9),array(0,9,0,17),array(0,9,9,9),array(0,17,9,17));
					
				case '3':
					return array( array(0,0,9,0),array(9,0,9,17),array(0,9,9,9),array(0,17,9,17));
					
				case '4':
					return array( array(0,0,0,9),array(9,0,9,17),array(0,9,9,9));
			
				case '5':
					return array( array(0,0,9,0),array(0,0,0,9),array(9,9,9,17),array(0,9,9,9),array(0,17,9,17));
					
				case '6':
					return array( array(0,0,9,0),array(0,0,0,17),array(9,9,9,17),array(0,9,9,9),array(0,17,9,17));
					
				case '7':
					return array(array(0,0,9,0), array(9,0,9,17) );
					
				case '8':
					return array( array(0,0,9,0),array(0,0,0,17),array(9,0,9,17),array(0,17,9,17),array(0,9,9,9));
					
				case '9':
					return array( array(0,0,9,0),array(0,0,0,9),array(9,0,9,17),array(0,17,9,17),array(0,9,9,9));
			
				case '0':
					return array( array(0,0,9,0),array(0,0,0,17),array(9,0,9,17),array(0,17,9,17));
		}
	}
}
 
new captcha();
 
