package Captcha;
# Captcha objektorientiert
# Synopsis:
#   use Captcha;
#   my $capt = new Captcha;
#
#   $capt->gencode();
#   my $img = $capt->image();
#   binmode STDOUT;
#   print $img;

use strict;
use warnings;
use GD;

# Farben
use constant NOISE_COLOR => (110, 130, 190);
use constant TEXT_COLOR  => (30, 70, 220);
use constant BG_COLOR    => (200, 200, 200);

sub new
  {
  # Neues Captcha-Objekt anlegen
  my $class = shift;
  my $self = bless {}, $class;
  $self->{'num'} = 6;
  $self->{'code'} = 'Dummy';
  return $self;
  }

sub gencode #($anzahl)
        {
        # Zufalls-Code generieren
  my $self = shift;
        my $num = $self->{'num'};
        $num = shift if @_;
        # Zeichenvorrat - ohne einander aehnliche Zeichen und Vokale
        my $chars = '23456789bcdfghjkmnpqrstvwxyz';
        my $code = '';
        for (1 .. $num)
          { $code .= substr($chars, rand(length($chars)-1), 1); }
        $self->{'code'} = $code;
        return $self;
        }

sub code
        {
        # Zufalls-Code zurückgeben
  my $self = shift;
        return $self->{'code'};
        }

sub image
  {
  # Captcha-Bild erzeugen und als String zuruecklifern
  my $self = shift;

        # Text als Bild erzeugen
        my $len = length($self->{'code'})*8;
        my $tmp = new GD::Image($len, 16);
        my $bg = $tmp->colorAllocate(BG_COLOR);
        my $tc = $tmp->colorAllocate(TEXT_COLOR);
  $tmp->transparent($bg);
  $tmp->string(gdLargeFont,0,0,$self->{'code'},$tc);

  # Hintergrundbild erzeugen
  my $width = length($self->{'code'})*16 + 32;
  my $height = 40;
  my $image = new GD::Image($width, $height);
        my $background = $image->colorAllocate(BG_COLOR);
  my $noise = $image->colorAllocate(NOISE_COLOR);
  # Zufalls-Punktmuster im Hintergrund
        for(my $i = 0; $i < ($width*$height)/3; $i++)
          {
    $image->setPixel( rand($width), rand($height), $noise);
                }
  # Zufalls-Linien im Hintergrund
  for(my $i = 0; $i < ($width*$height)/150; $i++)
    {
    $image->line(rand($width), rand($height),
                 rand($width), rand($height), $noise);
                }

  # Text vergroessert einkopieren
  my $x = ($width - length($self->{'code'})*16)/2;
  my $y = ($height - 32)/2;
  $image->copyResized($tmp,$x,$y,0,0,$len*2,32,$len,16);

  # Ausgabe
  return $image->gif;
  }

'ende';
