--- /Users/kevin/doc/dl/captcha/captcha.module	Wed Jan 26 10:00:44 2005
+++ captcha.module	Sat Apr 16 17:41:35 2005
@@ -40,39 +40,122 @@ function captcha_menu($may_cache) {
 
 function captcha_settings() {
 
-  //check for GD
-  if (!function_exists(imagecreate)) 
-    form_set_error('No GD', t('Image library not available. Captcha needs the GD library extension to be installed. Please install GD.'));
-
-  else {
+  $output .= form_checkbox(t('Check during user registration'), 'captcha_user_register', 'true', _captcha_istrue("captcha_user_register", "true"), 'If enabled, users will be asked to meet a challenge during user registration.');
   
-    $fonts_path = variable_get("captcha_fonts_path", "");
-    
-    //check for TTF support
-    if (!function_exists(imagettftext) || !function_exists(imagettfbox)) 
-      form_set_error('No TTF support', t('Your image library does not seem to have TrueType font support. Captcha will work, but will use the default inbuilt font.'));
-      
-    else {
+  $output .= form_checkbox(t('Check during anonymous comments'), 'captcha_comment_anonymous', 'true', _captcha_istrue("captcha_comment_anonymous"), 'If enabled, anonymous users will be asked to meet a challenge while posting .');
+  
+  $output .= form_checkbox(t('Check during registered user comments'), 'captcha_comment_registered', 'true', _captcha_istrue("captcha_comment_registered"), 'If enabled, registered users will be asked to meet a challenge while posting .');
+  
+  // Select captcha method.
+  $modules = module_implements('captcha');
+  $select = array();
+  foreach ($modules as $m) {
+    $description = module_invoke($m, 'captcha', 'description');
+    if ($description) {
+      $desc[$m] = $description;
+    }
+  }
+  if (count($desc) > 1) {
+    $output .= form_radios(t('Captcha method'), 'captcha_method', variable_get('captcha_method', 'captcha'), $desc, NULL, TRUE);
+  }
+  else {
+    $output .= form_hidden('captcha_method', 'captcha');
+  }
 
-      //check for valid font path
-      if ($fonts_path!="" && !is_dir($fonts_path))
-        form_set_error('Invalid font path', t('The current font path is invalid. The default font will be used.'));
+  // Settings for each captcha method.
+  foreach ($modules as $m) {
+    $group = module_invoke($m, 'captcha', 'settings');
+    if ($group) {
+      $output .= form_group($desc[$m], $group);
     }
-  
   }
-    
-  $output .= form_checkbox(t('Check during user registration'), 'captcha_user_register', 'true', _captcha_istrue("captcha_user_register", "true"), 'If enabled, users will be asked to recognize an image during user registration.');
-  
-  $output .= form_checkbox(t('Check during anonymous comments'), 'captcha_comment_anonymous', 'true', _captcha_istrue("captcha_comment_anonymous"), 'If enabled, anonymous users will be asked to recognize an image while posting .');
-  
-  $output .= form_checkbox(t('Check during registered user comments'), 'captcha_comment_registered', 'true', _captcha_istrue("captcha_comment_registered"), 'If enabled, registered users will be asked to recognize an image while posting .');
-  
-  $output .= form_textfield(t('TrueType Fonts Path'), 'captcha_fonts_path', $fonts_path, 30, 255, 'Location of the directory where the Truetype (.ttf) fonts are stored. If you do not provide any fonts, the module will use the default font for text.');  
+
+  return $output;
+}
+
+/**
+* Captcha API: Form items for a captcha test.
+*
+* @return
+*   Form items to be presented to the user as a captcha test.
+*/
+function captcha_form()
+{
+  $module = variable_get('captcha_method', 'captcha');
+  $output = module_invoke($module, 'captcha', 'form');
+  if (!$output) {
+    // If the configured captcha implementation is somehow unavailable,
+    // fall back on the default implemented by this module.
+    variable_set('captcha_method', 'captcha');
+    $output = captcha_captcha('form');
+  }
   return $output;
 }
 
 /**
-* Implementation of hook_menu(), for adding form elements & validation.
+* Captcha API: Tests the entered captcha response.
+*
+* @param $edit
+*   Input form data including the captcha_form() items.
+*/
+function captcha_test($edit) {
+  $module = variable_get('captcha_method', 'captcha');
+  return module_invoke($module, 'captcha', 'test', $edit);
+}
+
+
+/**
+* Implementation of hook_captcha().
+*/
+function captcha_captcha($op, $edit = NULL) {
+  switch ($op) {
+
+    case 'description':
+      // Brief description of this method; used in the catpcha settings form.
+      // In third-party captcha modules, this could test whether the particular
+      // captcha method is supported in the current configuration.
+      // The captcha module itself implements the default method,
+      // which is always available (though not always supported).
+      return t('Image recognition');
+
+    case 'settings':
+      // Settings for this captcha method.
+
+      //check for GD
+      if (!function_exists(imagecreate)) {
+        form_set_error('No GD', t('Image library not available. Captcha needs the GD library extension to be installed. Please install GD.'));
+      }
+      else {
+        $fonts_path = variable_get("captcha_fonts_path", "");
+        //check for TTF support
+        if (!function_exists(imagettftext) || !function_exists(imagettfbox)) {
+          form_set_error('No TTF support', t('Your image library does not seem to have TrueType font support. Captcha will work, but will use the default inbuilt font.'));
+        }
+        else {
+          //check for valid font path
+          if ($fonts_path!="" && !is_dir($fonts_path))
+            form_set_error('Invalid font path', t('The current font path is invalid. The default font will be used.'));
+        }
+      }
+      return form_textfield(t('TrueType Fonts Path'), 'captcha_fonts_path', $fonts_path, 30, 255, 'Location of the directory where the Truetype (.ttf) fonts are stored. If you do not provide any fonts, the module will use the default font for text.');  
+
+    case 'form':
+      // Return form items for this captcha method.
+      $output .= form_item("", '<img src="'.url('captcha/image/'.time()).'" alt="Captcha Image: you will need to recognize the text in it."/>');
+      $output .= form_textfield(t('Word'), 'captchaword', NULL, 15, 15, 'Please type in the letters/numbers that are shown in the image above.', NULL, TRUE);
+      return $output;
+
+    case 'test':
+      // Return TRUE or FALSE according to whether the supplied form values
+      // satisfy the captcha test.
+      return ($edit != NULL) && (strtolower($edit['captchaword']) == strtolower($_SESSION['captcha']));
+
+  }
+}
+
+
+/**
+* Implementation of hook_user(), for adding form elements & validation.
 */
 function captcha_user($type, &$edit, &$newuser, $category = NULL) {
 
@@ -84,16 +167,12 @@ function captcha_user($type, &$edit, &$n
   switch ($type) {
     case t("register"):
     // Add two items to the resigtration form.
-    
-    $output .= form_item("", '<img src="'.url('captcha/image/'.time()).'" alt="Captcha Image: you will need to recognize the text in it."/>');
-    $output .= form_textfield(t('Word'), 'captchaword', NULL, 15, 15, 'Please type in the letters/numbers that are shown in the image above.', NULL, TRUE);
-
-    return array(array('title' => t('Verify Registration'), 'data'=>$output));
+    return array(array('title' => t('Verify Registration'), 'data' => captcha_form()));
 
     break;
     case t("validate"):
     // The user has filled out the form and checked the "accept" box.
-    if (strtolower($edit['captchaword']) == strtolower($_SESSION['captcha'])) {
+    if (captcha_test($edit)) {
       // on success return the values you want to store
       return array("captcha_correct" => 1);
     }
@@ -123,7 +202,7 @@ function captcha_comment($op,$edit) {
       // this implementation basically sets a flag when you've successfully validated a captcha;
       // any successive comment inserted uses and invalidates the set flag.
       if ($_SESSION['captcha_comment_correct']!='ok') {
-        if (strtolower($edit['captchaword']) != '' && strtolower($edit['captchaword']) == strtolower($_SESSION['captcha'])) {
+        if (captcha_test($edit)) {
           $_SESSION['captcha_comment_correct'] = 'ok';
         }
         else {
@@ -139,9 +218,7 @@ function captcha_comment($op,$edit) {
     case 'form':
       $form_html = "";
       if ($_SESSION['captcha_comment_correct']!='ok') {
-        $output .= form_item("", '<img src="'.url('captcha/image/'.time()).'" alt="Captcha Image: you will need to recognize the text in it."/>');
-        $output .= form_textfield(t('Word'), 'captchaword', NULL, 15, 15, 'Please type in the letters/numbers that are shown in the image above.', NULL, TRUE);
-        $form_html = form_group(t('Verify comment authorship'), $output);
+        $form_html = form_group(t('Verify comment authorship'), captcha_form());
       }
       return $form_html;
   }
