# comment_captcha2.rb $Revision: 1 $
# Copyright (C) 2007 Michitaka Ohno <elpeo@mars.dti.ne.jp>
# You can redistribute it and/or modify it under GPL2.
#
# @options['captcha.secret'] = '秘密の言葉'

require 'digest/md5'

@captcha_lettersize = 4

def comment_captcha_label
	'右の画像に書かれている文字列を入力してください'
end

alias :comment_body_label_orig :comment_body_label

def comment_body_label
	r = ""
	if @mode == 'day' then
		scan = FONT_WIDTH * @captcha_lettersize + FONT_MARGIN * 2
		height = FONT_HEIGHT + FONT_MARGIN * 2
		bitmap = "0" * scan * height
		letter = []
		sx = Math::PI * 2 * rand
		sy = rand < 0.5 ? Math::PI : 0
		@captcha_lettersize.times do |n|
			letter << rand( 26 )
			c = [FONT_DATA[letter.last]].pack( "H*" ).unpack( "B*" ).first
			FONT_HEIGHT.times do |y|
				FONT_WIDTH.times do |x|
					next unless c[y*FONT_WIDTH+x] == ?1 
					xx = FONT_MARGIN + n * FONT_WIDTH + x + (FONT_MARGIN * Math.sin( sy + y * Math::PI / FONT_HEIGHT )).round
					yy = FONT_MARGIN + y + (FONT_MARGIN * Math.sin( sx + x * Math::PI / FONT_WIDTH )).round
					next unless xx >= 0 && xx < scan && yy >= 0 && yy < height
					bitmap[yy*scan+xx] = ?1
				end
			end
		end
		code = letter.map{|i| (?A+i).chr}.join
		image = '<table cellpadding="0" cellspacing="0" style="border: 1px solid black">'
		image << bitmap.gsub( /[01]{#{scan}}/ ) do |s|
			'<tr>' + s.gsub( /[01]/ ) do |c|
				%Q[<td style="width: 1px; height: 1px; background-color: #{PIXEL_COLOR[c.to_i]}"></td>]
			end + '</tr>'
		end
		image << '</table>'
		secret = @conf['captcha.secret'] || ''
		expire = (Time.now.to_i+86400).to_s
		digest = Digest::MD5.hexdigest( code+secret+expire )
		r << %Q[<div class="captcha-image" style="float: right">#{image}</div>]
		r << comment_captcha_label
		r << %Q[:<input class="field" name="captcha_code" value="">]
		r << %Q[<input type="hidden" name="captcha_digest" value="#{digest}">]
		r << %Q[<input type="hidden" name="captcha_expire" value="#{expire}">]
		r << %Q[<br>]
	else
		secret = @conf['captcha.secret'] || ''
		expire = (Time.now.to_i+86400).to_s
		digest = Digest::MD5.hexdigest( secret+expire )
		r << %Q[<input type="hidden" name="captcha_code" value="">]
		r << %Q[<input type="hidden" name="captcha_digest" value="#{digest}">]
		r << %Q[<input type="hidden" name="captcha_expire" value="#{expire}">]
	end
	r << comment_body_label_orig
end

FONT_DATA = [
'0000010001000380038004c004c004c008600fe008601030103078fc00000000',
'00003fc00c600c300c300c300c600fc00c600c300c300c300c603fc000000000',
'000003c806380c180c08180818001800180018080c080c10063003e000000000',
'00003fc00c300c180c180c0c0c0c0c0c0c0c0c0c0c180c180c303fc000000000',
'00003ff00c300c100c100c400cc00fc00cc00c400c100c100c303ff000000000',
'00003ff00c300c100c100c400cc00fc00cc00c400c000c000c003f8000000000',
'000007d00c701830181030103000300030fc3030183018300c7007b000000000',
'00007efc183018301830183018301ff0183018301830183018307efc00000000',
'000007e00180018001800180018001800180018001800180018007e000000000',
'000003f000c000c000c000c000c000c000c000c008c01cc018c00f8000000000',
'00007ef818201840188019001b001d80198018c01860186018307e7c00000000',
'00003f000c000c000c000c000c000c000c000c000c100c100c303ff000000000',
'0000f01e3818383838382c382c582c5826582698269823982318fb7e00000000',
'0000787c18101c101610161013101310119010d010d0107010307c3000000000',
'000003c00c3018181818300c300c300c300c300c181818180c3003c000000000',
'00003fc00c600c300c300c300c600fc00c000c000c000c000c003f8000000000',
'000003c00c3018181818300c300c300c300c338c1c5818580c7003c0003c0018',
'00003fc00c600c300c300c300c600fc00d800cc00c600c600c303f3c00000000',
'000007a008e0186018200c000f8003e000601030101018301c2017c000000000',
'00003ffc318c218421840180018001800180018001800180018007e000000000',
'00007e7c18101810181018101810181018101810181018100c2007c000000000',
'00007e7c181018100c200c200c20064006400640038003800100010000000000',
'0000f3ce61846184618432c832c832c814501c701c7008200820082000000000',
'00003e780c2006400640038003000180038002c004c0046008603ef800000000',
'00003f7c0c100c1006200620034003400180018001800180018007e000000000',
'00001ff0186010c010c0018001800300060006000c100c1018303ff000000000',
]
FONT_WIDTH = 16
FONT_HEIGHT = 16
FONT_MARGIN = 3

PIXEL_COLOR = ['silver', 'black']
