/*
	captcha.js

	Autor: sb

	Erstellt: 04.04.2024 

	Zweck: Stellt eine Captcha-Aufgabe, die richtig beantwortet werden muss, um ein Eingabeformular absenden zu können.

	Voraussetzung: Das Eingabeformular wird durch das Perl-Script "contact.pl" verarbeitet.

	- Dieses schickt die erwartete Captcha-Lösung als MD5-Checksumme im versteckten Eingabefeld "captcha-question"
	  und wertet die im versteckten Eingabefeld "captcha-answer" enthaltene Captcha-Antwort des Benutzers aus.

	- Bei einer fehlerhaften Antwort wartet das Perl-Script 5 Sekunden, bevor es sich mit einer Fehlermeldung zurückmeldet.
	  Dies soll Brute-Force-Angriffsversuchen vorbeugen.

	Anwendung:

	- In den <head>-Bereich der HTML-Datei (Template) folgende Dateien einfügen:

	captcha.css
	captcha.js

	- In das Eingabeformular der HTML-Datei (Template) folgendes einfügen:

		  <template-captcha>
			<div id="captcha">
				<p class="center">@CAPTCHA_TEXT@</p>
				<table id="captcha-game"></table>
				<input type="hidden" name="captcha-question" value="@CAPTCHA_QUESTION@">
				<input type="hidden" id="captcha-answer" name="captcha-answer">
			</div>
		  </template-captcha>

	- In den auskommentierten <template-constants>-Bereich der HTML-Datei (Template) folgendes einfügen:

	CaptchaEnabled|1 # 0 = Captcha deaktiviert, 1 = Captcha aktiviert
	CaptchaSecret|ke6Te9bJzVMU # Geheimer Zusatz-String für die Captcha-Antwort

	  Hinweis: Der Wert für CaptchaSecret sollte für jedes Formular neu erzeugt werden, z.B. mit random.org
	  (https://www.random.org/passwords/?num=5&len=12&format=html&rnd=new).

	- In den auskommentierten <template-message-strings>-Bereich der HTML-Datei (Template) folgendes einfügen:

	captcha-text|de=<b>Spamschutz:</b> Bitte setze durch Klicken/Tippen auf das Schachbrett ein Smiley auf die Felder @CAPTCHA_FIELD1@ und @CAPTCHA_FIELD2@:$en=<b>Spam protection:</b> Please place a smiley on the @CAPTCHA_FIELD1@ and @CAPTCHA_FIELD2@ fields by clicking/tapping on the chessboard.
	captcha-letter-words|de=Anton Berta Cäsar Dora Emil Friedrich Gustav Heinrich$en=Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel
	captcha-number-words|de=Eins Zwei Drei Vier Fünf Sechs Sieben Acht$en=One Two Three Four Five Six Seven Eight
	error-wrong-captcha-answer|de=Falsche Antwort auf die Spamschutz-Frage.$en=Wrong answer to the spam protection question.

	  Hinweis: Die Texte können nach Bedarf angepasst werden. In diesem Beispiel werden zweisprachige Texte verwendet.
*/

"use strict";

function InitCaptcha()
{
	var elemCaptchaGame = document.getElementById('captcha-game');
	if (elemCaptchaGame)
	{
		for (var v = 0; v < 10; v++)
		{
			var elemRow = document.createElement('tr');
			elemCaptchaGame.appendChild(elemRow);
			for (var h = 0; h < 10; h++)
			{
				var elemCell = document.createElement('td');
				elemRow.appendChild(elemCell);

				var labelH = ' ABCDEFGH '.substring(h, h + 1);
				var labelV = ' 87654321 '.substring(v, v + 1);
				var label = '';
				var cssClass = 'captcha-game-border';

				if ((v == 0 || v == 9) && (h >= 1 && h <= 8)) label = labelH;
				else if ((v >= 1 && v <= 8) && (h == 0 || h == 9)) label = labelV;
				else if ((h >= 1 && h <= 8) && (v >= 1 && v <= 8))
				{
					cssClass = (h + v) & 1 ? 'captcha-game-black' : 'captcha-game-white';
					elemCell.id = labelH + labelV;
					elemCell.onclick = function()
					{
						var elemCaptchaAnswer = document.getElementById('captcha-answer');
						if (elemCaptchaAnswer)
						{
							var arrCaptchaAnswer = [];
							if (elemCaptchaAnswer.value) arrCaptchaAnswer = elemCaptchaAnswer.value.split(' ');

							var i = arrCaptchaAnswer.indexOf(this.id);
							if (i != -1) arrCaptchaAnswer.splice(i, 1);

							if (this.innerText == '')
							{
								this.innerText = '🙂';
								arrCaptchaAnswer.push(this.id);
								arrCaptchaAnswer.sort();
							}
							else
							{
								this.innerText = '';
							}

							elemCaptchaAnswer.value = arrCaptchaAnswer.join(' ');
						}
					};
				}
				elemCell.classList.add(cssClass);
				elemCell.innerHTML = label;
			}
		}
	}
}

document.addEventListener('DOMContentLoaded', InitCaptcha, false);
