<?php

/*
 * PHP Captcha Image generator
 *
 * This script will look for a session variable 'CAPTCHA_STRING' and generate an
 * image with that string displayed.
 *
 * Requirements PHP with GD installed.
 *
 * Author: Paul Gregg
 * Date: 8th August 2005
 * Copyright, 2005, Paul Gregg
 *
 */

$DEBUG = FALSE;

// We use sessions to store the catpcha information between page requests
if (!isset($_SESSION)) session_start();

// We need to use GD - if not installed, we can't work, so exit.
if (!function_exists('imagecreate')) {
  print "Error: GD not installed.\n";
  exit;
}


// Function to return a random captcha string
Function GenerateCaptchaString($length=6) {
  // Generate a random string for the captcha
  $tmp_availchars = str_shuffle('abcdefghjkmnpqrstuvwxyz23456789'); // shuffle them up
  // pull out $length characters
  $tmp_captcha = substr($tmp_availchars, rand(0, strlen($tmp_availchars)-$length), $length);
  // now randomise the case of the characters 
  // we don't actually care what case it is entered, but it is more entropy for OCR
  $tmp_captcha = preg_replace('/[a-z]/ie', '(rand(0,1) ? \'$0\' ^ str_pad(\'\', strlen(\'$0\'), \' \') : \'$0\')', $tmp_captcha);
  return $tmp_captcha;
}

Function GenerateCaptchaImage($captcha='', $captcha_size=4, $captcha_colours='blue,red,yellow,green') {
  global $PG_ImageColorDef;

  // Pull in PG's GD wrapper functions to make generating this easier.
  require('pg_gd_wrappers.inc.php');


  // read in desired captcha info
  $captcha = isset($_SESSION['CAPTCHA_STRING']) ? $_SESSION['CAPTCHA_STRING'] : '';
  $captcol = isset($_SESSION['CAPTCHA_COLOUR']) ? $_SESSION['CAPTCHA_COLOUR'] : 'blue,red,yellow,green';

  $Legendkeys = explode(',', $captcol);


  if (!isset($captcha_size)) $captcha_size = 6;

  if ($captcha == '') { // Not good, lets try and make one randomly
    // and save it in the session
    $_SESSION['CAPTCHA_STRING'] = GenerateCaptchaString($captcha_size);
    $captcha = $_SESSION['CAPTCHA_STRING'];
  }


  #if ($DEBUG && $captcha == '')
  #  $captcha = 'TestString';


  // Send out the header info and create the initial blank canvas
  #if (!$DEBUG)

  // Set max params
  $Xmax = 200;
  $Ymax = 100;
  $Xborder = 20;
  $Yborder = 20;
  
  $font = 5;
  $fontwidth = ImageFontWidth($font);
  $fontheight = ImageFontHeight($font);
  $legendwidth = $fontwidth * 30;

  #$Ymax = 95;
  $Ymax = $fontheight * count($Legendkeys) +35;
  $Xmax = $legendwidth + 30;
  
  // Generate the canvas
  PG_ImageCreate($image, $Xmax, $Ymax, $Yborder, $Yborder, $Xborder, $Xborder);

  // create an initial grey rectangle for us to draw on
  PG_ImageFilledRectangle($image, 0, 0, $Xmax+$Xborder*2, $Ymax+$Yborder*2, 'white');
  PG_ImageFilledRectangle($image, 0, 0, $Xmax, $Ymax, 'lightgrey', $Yborder, $Yborder, $Xborder, $Xborder);


  // Display graphic title
  #$captcha_live = $Legendkeys[0]; // the first colour.
  $captcha_live_index = rand(0, count($Legendkeys)-1); // random colour index
  $captcha_live = $Legendkeys[$captcha_live_index]; // random colour.
  PG_ImageString($image, 2, 'center', 'top', 'Enter the '.$captcha_live.' text below in the box', 'black');


  // alternative legends gen
  $Legends = array();
  shuffle($Legendkeys); // randomise the colour order
  foreach ($Legendkeys as $legendkey) {
    $tmp_legendvalue = ($legendkey == $captcha_live ? $captcha : str_shuffle($captcha));
    $tmpcaptcha = implode(' ', str_split($tmp_legendvalue, 1));
    $Legends["$legendkey"] = str_pad($tmpcaptcha, 30, ' ', STR_PAD_BOTH);
  }
#$Legends["black"] = $captcha_live . " " . $captcha . "height=$fontheight";


  PG_DrawLegend($image, 10, $Ymax-10, $font, $Legends, 'midgrey', 'lightgrey', 1, $Yborder, $Yborder, $Xborder, $Xborder);


  // output the GIF to the browser and free up memory
  ImagePNG($image);
  ImageDestroy($image);  // free up the memory

}



// finally - if this script is called directly, then it is to generate an image
if ($_SERVER['SCRIPT_NAME'] == $_SERVER['REQUEST_URI']) {
  if (isset($_GET['test'])) $_SESSION['CAPTCHA_STRING'] = '';
  ob_start();
  GenerateCaptchaImage();
  $image = ob_get_clean();
  Header("Content-type: image/png");
  Header('Content-Length: ' . strlen($image));
  print $image;
} else {
  #phpinfo();
}

?>