=c
	NetPatch Captcha class module. 
	Writen by Roman Chebotarev <roma@ultranet.ru> at January 2010
	WWW: http://www.netpatch.ru/npcaptcha.html

 	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License.
	
=cut 

use strict;
use warnings;

package NPCaptcha;

our $VERSION = 0.1;

sub new
{
	my $invocant = shift;
	my $class = ref($invocant) || $invocant;

	my $self = 
	{
		tmpdir => '/tmp',			# Directory which allowed for writing 
		imagesdir => './images',	# Directory with CAPTCHA images
		timeout => 600,				# Timeout for awaiting CAPTCHA code
		extensions => ['gif'],		# CAPTCHA images extension(s)
		remoteAddr => undef,		# Remote IP addres
		cookieName => 'captcha_rcpt',
		cookieValue => undef,
		captchaValue => undef,
		@_
	};

	-d $self->{tmpdir} || die "Invalid temporary directory: $!";
	$self->{timeout} > 0 || die "Invalid timeout value: $self->{timeout}";
	defined $self->{remoteAddr} || die "Remote IP address is not set!";

	clearOld($self);

	return bless($self, $class);
}

sub clearOld
{
	my $self = shift;
	opendir(TMPDIR, $self->{tmpdir}) || die "Can't open temporary directory: $!";
	my @checkFiles = readdir(TMPDIR);
	closedir(TMPDIR);

	my $checkFile;
	# Remove old check files
	foreach $checkFile (@checkFiles)
	{
		unlink "$self->{tmpdir}/$checkFile" 
			if ( time() - (stat("$self->{tmpdir}/$checkFile"))[9] > $self->{timeout});
	}
}

sub getImage
{
	my $self = shift;

	-d $self->{imagesdir} || die "Invalid images directory ($self->{imagesdir}): $!";
	opendir(IMGSDIR, $self->{imagesdir}) || die "Can't open images dir for generating CAPTCHA: $!";
	@{$self->{images}} = readdir (IMGSDIR);
	closedir (IMGSDIR);

	my @suitableImages;
	foreach my $ext (@{$self->{extensions}})
	{
		push @suitableImages, grep /\.$ext$/, @{$self->{images}};
	}
	
	die 'Suitable files (extensions - ' . join(', ', @{$self->{extensions}}) . 
		') not found in images directory ' . $self->{imagesdir}
			unless @suitableImages ;

	my $imgName = $suitableImages[int rand @suitableImages];

	open(IMG, $self->{imagesdir} . '/' . $imgName) || die "Can't open image file: $!";
	my $image;
	$image .= $_ while <IMG>;
	close(IMG);

	$imgName =~ s/\.[\w\d]+$//;	# Remove file extension
	open(TMPFILE,  ">$self->{tmpdir}/$self->{remoteAddr}-$imgName.captcha") || die "Can't create temporary file: $!";
	close(TMPFILE);

	return $image;
}

# Generate cookie with ip for any proxy servers used for image caching
sub getCookie
{
	my $self = shift;
	return "$self->{cookieName}=$self->{remoteAddr}; expires=" . gmtime((time + 86400)) . '; path=/';
}

sub check
{
	my $self = shift;
	my $checkFile = "$self->{remoteAddr}-$self->{captchaValue}.captcha";

	if ( -e "$self->{tmpdir}/$checkFile" )
	{
		unlink "$self->{tmpdir}/$checkFile";
		return 1;
	}

	return 0 unless $self->{cookieValue};

	$checkFile = "$self->{cookieValue}-$self->{captchaValue}.captcha";
	if ( -e "$self->{tmpdir}/$checkFile" )
	{
		unlink "$self->{tmpdir}/$checkFile";
		return 1;
	}

	return 0;

}

1;
