#!/usr/bin/perl

use Data::Dumper;

###!C:\PROGRA~1\Prolytic\WEB-FR~1\perl\bin\perl

#
# fragebogen.pl 
# von Matthias Hubert
# Beginn: 06.08.2002
#
# History fragebogen.pl:
# -----------------------------------------------------------------
# v0.1/06.08.02: Sub zum Einlesen des XML Files mit XML::Parser
# v0.2/07.08.02: Ausgabe des HTML-Codes
# v0.3/08.08.02: Einbinden des CGI-Modules, XMLfile wird mit URI übergeben
# v0.4/13.08.02: Anpassen an die neue Struktur des XMLfiles,Behandlung von Umlauten
# v0.5/19.08.02: Default-Wert wenn nichts ausgewählt wurde
# v0.6/19.08.02: Verwenden von Style Sheets,Neues Design
# v0.7/27.08.02: Anpassen an die Struktur des Output, Übergabe der rel. Werte
# v0.8/31.08.02: Variablen in externe config Datei auslagern
# v0.9/14.09.02: Jede Kategorie auf einer eigenen Seite ausgeben
# v1.0/16.09.02: Zusammenlegen von fragebogen.pl,speichern.pl 
# v1.1/22.09.02: Überprüfen der Antworten
# v1.2/29.09.02: Löschen der .tmp Files die älter als 1 Tag sind
# v1.3/30.09.02: Anzeigen der Schritte / neues encoding text für offene Fragen
# 		 neues encoding auswahlxbin für Auswahl x aus n
# v1.4/01.10.02: encoding numerisch - min und max Werte		 
# 		 Darstellung von Bildern zur Beschreibung
# 		 Javascript Eingabeüberprüfung für auswahlxbin
# v1.5/02.10.02: Conjoint-Analyse / Ausgabe in ASCII
# v1.6/04.10.02: XMLfile Angabe in ASCII Output / Back verhindern
# 		 Löschen der session bei Fragebogen-Abbruch
# v1.7/06.10.02: Neues Design (CSS)		 
# v1.8/08.10.02: Fehlerbehebung / Javascript-aktiv Abfrage / Anpassung Netscape
# v1.9/10.10.02: 'die' durch Fehler-Routine ersetzt
# 		 Fehlerbehebung in Javascriptroutine
# v2.0/13.10.02: Conjoint-Set Auswahl durch Zufallsvariable		 
# 		 Fehlerbehebung in Javascriptroutine
# v2.1/16.10.02: Bilder bei Conjoint moeglich
# v2.2/18.10.02: Quellcode dokumentiert
# v2.3/23.10.02: Schlußtext aus XML File
# 		 Jeden Conjoint Task auf einer eigenen Seite darstellen
# v2.4/24.10.02: FragebogenID in Conjoint Daten mit ausgeben
# 		 Fehlerbehebung in Javascriptroutine
# v2.5/25.10.02: Layout veraendert
# v2.6/26.10.02: Eingabeueberpruefung bei Bewertung 
# v2.7/06.11.02: Fehlerbehebung in JavaScriptroutine
# 		 'Schliessen'-Button wenn fertig
# v2.8/13.11.02: Aenderungen bei Conjoint-Export
# 		 Fehler bei Nummernsortierung behoben
# 		 Produktattribute koennen einzeln gestaltet werden
# 		 Aenderungen bei der Conjoint-Darstellung
# v2.9/19.11.02: Fehlerbehebung in JavaScriptroutine
# 		 Automatische Weiterleitung bei Conjoint-Task
# v3.0/20.11.02: Ausgabe der Attributname statt Werte
# 		 bei Export: '_' durch '/' ersetzen
# v3.1/27.11.02: bei Export: eigenes Verz. pro Fragebogen
# 		 Unterscheidung daten und conjoint (alle csv), statt csv und txt
# 		 ID im Dateinamen mitausgeben
# 		 neue Spalte im Conjoint-File
# v3.2/29.11.02: XML Datei für jeden Fragebogen generieren, wenn Set-Anzahl > 50
# 		 FragebogenID bei Export neu einlesen
# v3.3/07.12.02: Verzeichnis der Bilder in config.pl einstellbar
# v3.4/28.02.03: Eine Frage pro Seite
# v3.5/01.03.03: Filter moeglich
# v3.6/20.03.03: Umlaute in Optionswerten
# v3.7/03.04.03: Mehrfach-Absenden verhindert
# v3.8/05.04.03: Debug Schalter in config.pl
# v3.9/05.04.03: Umstellung auf neue Header-Variablen
# v3.10/07.04.03: Fehlerbehebung
# v3.11/16.04.03: Unvertraeglichkeiten mit Netscape entfernt
# v3.12/22.04.03: Zufaellige Reihenfolge der Optionen bei auswahl,auswahlbin (nicht aktiviert!)
# v3.13/22.04.03: Update auswertung.pl (1.4)
# v3.14/25.04.03: Update auswertung.pl (1.6)
# v3.15/04.05.03: Fehlerbehebung bei Debug-Schalter
# v3.16/30.05.03: CreatePDF Modul hinzugefuegt
# v3.17/02.06.03: Darstellung der Optionen in 2 Spalten (rang,auswahlxbin)
# v3.18/11.06.03: Alternative JS-Abfrage bei Rang-Fragen
# v3.19/12.06.03: Fehlerbehebung
# v3.20/27.06.03: Rangreihung durch Anklicken der Felder moeglich
# v3.21/30.06.03: fixe Spaltenbreite der Optionen (als eigene CSS class definiert)
# v3.22/30.06.03: Fragennummerierung (in config einstellbar)
# v3.23/30.06.03: Fehlerbehebung bei Filterfragen
# v3.24/01.07.03: mind. Ausfüllmenge bei Rang-Fragen
# v3.25/01.07.03: Kategorienfortschritt ausblendbar (in config)
# v3.26/07.07.03: Mischen der Attribute ueber Tag schaltbar (vgl. 3.12)
# v3.27/07.07.03: Infoseite ausgeben
# v3.28/07.07.03: Fehlermeldungen in Datei ausgeben
# v3.29/08.07.03: Fehlerbehebung
# v3.30/08.07.03: Abfrage bei Klick auf Abbrechen
# v3.31/10.07.03: Bei Fehler - Wiederholen / Fehlernummern vergeben
# v3.32/10.07.03: Rangreihenfragen verstecken
# v3.33/10.07.03: Automatische Weiterleitung bei 1 Rangfrage
# v3.34/10.07.03: Logfile ausgeben
# v3.35/15.07.03: Mehrsprachenunterstützung
# v3.36/18.07.03: Andere Conjoint Darstellung
# v3.37/25.07.03: Optimierung der Conjoint-Darstellung
# v3.38/25.07.03: Kommastellen bei numerischer Eingabe
# v3.39/25.07.03: Bild auf Infoseite
# v3.40/25.07.03: Auswahl Combo od. Checkbox bei 1 aus n Fragen
# v3.41/29.07.03: Bilder bei allen Fragen/Fehler bei Filter behoben
# v3.42/14.08.03: mehrzeilige Attribute bei Conjoint-Fragen
# v3.43/14.08.03: Angabe eines tmp-Verz im config
# v3.44/16.10.03: Bugfix: Optionstext abgeschnitten
# v3.45/18.10.03: Bugfix von 3.44: Optionstext abgeschnitten / Deaktivieren des Submit bei empty-Seiten
# v3.46/04.11.03: Neue Exportroutine für csv
# v3.47/06.11.03: Bugfix: SubmitButton erscheint in Datenfile
# v3.48/11.11.03: Sessionfile abfragen
# v3.49/14.11.03: Bugfix in neuer Exportroutine / Browser im Logfile
# v3.50/20.11.03: Version aus Kopfzeile im Browser entfernen
# v3.51/24.11.03: min,max und genau bei XausN moeglich
# v3.52/27.11.03: Bugfix in Javascriptroutine für Conjoint und auswahlbin(radio)
# v3.53/02.12.03: Excel 97 Support in auswertung.pl
# v3.54/03.12.03: kompakte Darstellung
# v3.55/05.12.03: Logviewer im Paket
# v3.56/11.12.03: FB weiterempfehlen / Bugfix: mehrmals speichern moeglich
# v3.57/16.02.04: Bugfix: Weiter bei Auswahl (Ansicht Radio) ohne Option moeglich
# v3.58/05.03.04: Bugfix: ";" im eingegebenen Text werden durch ":" ersetzt
# v3.59/08.03.04: Update auswertung.pl auf 1.10
# v3.60/23.03.04: Update auswertung.pl auf 1.11
# v3.61/25.03.04: Update auswertung.pl auf 1.12
# v3.62/30.03.04: Behandlung von nominalen NEIN Werten
# v3.63/01.04.04: Update auswertung,setup,config (Excel)
# v3.64/08.04.04: Update setup auf 1.8
# v3.65/23.04.04: Update auswertung,setup,config (Excel)
# v3.66/26.04.04: neg. Werte erlaubt
# v3.67/26.04.04: Versionseintrag von Startseite entfernen
# v3.68/26.04.04: HTML-Tags in Fragetext interpretieren
# v3.69/30.04.04: 0-Wert bei Bewertung durch "" ersetzen
# v3.70/07.05.04: Update testfb/Neu fillin.pl
# v3.71/13.05.04: "Bitte warten" bei leeren Seiten
# v3.72/13.05.04: Bugfix bei 0-Wert
# v3.73/25.05.04: Bugfix in Javascript Eingabe Pruefung
# v3.74/28.05.04: Neu genxls.pl
# v3.75/01.06.04: Update fillin.pl
# v3.76/02.06.04: Update createpdf.pl (1.12)
# v3.77/02.06.04: Update createpdf.pl (1.13)
# v3.78/02.06.04: Update createpdf.pl (1.14)
# v3.79/03.06.04: Update createpdf.pl (1.15) / neu export.pl
# v3.80/03.06.04: Update export.pl, genxls.pl, fillin.pl
# v3.81/06.06.04: Update auswertung.pl, createpdf.pl
# v3.82/09.06.04: Update auswertung.pl, genxls.pl
# v3.83/15.06.04: Integration TMPdir, Umstellung der Verzeichnisse, Fehlerausgabe bei reload am Ende
# v3.84/12.03.05: Bugfix bei Eingabe von ", Update genxls.pl
# v3.85/09.04.05: Bugfix "mehrmaliges Daten speichern"
# v3.86/26.03.06: Änderungen am Layout der Startseite, Gestaltung mit HTML moeglich
# v3.87/29.03.06: Unique ID für FBs (7-stellig)
# v3.88/02.04.06: Zeilen für Linuxversion sind auskommentiert und mit dem Vermerk "Linux Version" versehen, sub u2a erweitert
# v3.89/30.04.06: Update genxls.pl auf 007
# v3.90/11.05.06: Update genxls.pl auf 008
# v3.91/05.06.06: Update auf Perl 5.8 inkl. Module, Update setup.pl 1.11
# v3.92/07.07.06: Hoehe der Bilder zentral einstellbar
# v3.93/07.07.06: Nummerierung der Optionen aus/einblendbar
# v3.94/07.07.06: Kategorien in Conjoint
# v3.95/14.10.06: neue Optionen im Setup
# v3.96/10.03.07: Bewertungsskala oben und unten wenn mehr als 5 Antworten
# v3.97/15.04.07: Update logviewer.pl
# v3.98/20.07.07: Bugfix: Anzahl der Balken in Conjoint Kategorie inkorrekt
# v3.99/23.07.07: Teilnehmernummer und Prüfsumme wird mit URL übergeben
# v4.00/02.08.07: Ausblenden der Null Option bei Bewertung ( XML Attribut nullopt="0")
# v4.01/26.08.07: Teilnehmernummer wird als FB-ID gespeichert
# v4.02/03.11.07: URL-Weiterleitung am Ende, Übergabe der ID und MD5, kein Start bei falscher md5 (in config.pl einstellbar)
# v4.03/03.11.07: Ausgabe der Bilder bei auswahlbin 1 aus n
# v4.04/18.04.08: bei Filter nicht die ganze Kategorie überspringen
# v4.05/18.04.08: Update testfb.pl und fillin.pl
# v4.06/19.04.08: Response time der conjoint tasks + Update genxls.pl
# v4.07/25.09.08: Null Option bei numerischen Fragen hinzugefügt, Labels für Optionen bei Bewertungsfragen [PL]
# v4.08/09.10.08: Ausgabe der Teilnehmernummer in das Logfile [PL]
# v4.09/28.04.10: AA Firefox-Hänger bearbeitet
#---------------------------------------------------------------------
# Definieren der externen Module
#---------------------------------------------------------------------
#use lib "/is/htdocs/45370/www.prolytic.com/umfrage/cgi-bin/module";		#Linux Version auf Prolytic Server
#use lib "/is/htdocs/wp10476306_VSFXCX86KU/www/umfrage1/cgi-bin/module";
use XML::Parser;
use CGI;
#use CGI qw(:standard -no_xhtml);
use CGI::Carp qw(fatalsToBrowser);
use Fcntl qw(:flock);
use Digest::MD5 qw(md5_hex);
#use strict;
use Text::Iconv;		#Linux Version


#---------------------------------------------------------------------
# Definieren der Variablen 
#---------------------------------------------------------------------

#Variablen aus Config-File laden
use vars qw($XMLpfad $XMLfile $CSSfile $PicDir $TMPdir $interviewer $fragebogenid $minID $maxID $img_height %conkat $trz $debug $fragenum $optnum $kat_anzeige $logfile $langfile $mailactive $start_nomd5 $url_redir $url_redir_opt);
do "config.pl";

my $tmppath = $TMPdir."tmp/";
my $datapath = $TMPdir."data/";
my $logpath = $TMPdir."log/";

#my $cgi = new CGI;		#neues CGI Objekt erzeugen
my $cgi = CGI->new();
$| = 1;				#Datei-Puffer abschalten
my $ver='v4.06';		#Programm Version
my $copyright = "";		#Copyright Info
$0 =~ /[\\\/](\w*\.pl)$/;		#Dateinamen extrahieren ...
my $me=$0;			#... und zuweisen
my $url=$cgi->url();		#Referenz auf die aufrufende URL
my $html;			#speichert die HTML Ausgabe
my $js;				#speichert die JavaScript Ausgabe
my $XMLname = $XMLfile;
$XMLname =~ s/\.xml//;		#Name des Fragebogens
my $XMLdatei = $XMLpfad.$XMLfile;
my $XMLfile = $XMLpfad.$XMLfile;#Filename des Fragebogens mit Pfadangabe
my $setcount = 1;		#speichert die durchlaufenen Conjoint Sets
my $setmax;			#maximale Anzahl an Conjoint-Sets
my $setakt;			#aktuelles Conjoint-Set
my $set;			#Flag ob ein Conjoint-Set begonnen hat
my $myxml;			#Flag ob eigene XML Datei angelegt wurde
my $frageakt;			#aktuelle Frage
my $fragecount;			#Fragenzaehler innerhalb einer Kategorie
my $confragenmax;		#maximale Anzahl an Fragen innerhalb eines Conjoint-Sets
my $confrageakt;		#aktuelle Frage innerhalb eines Conjoint-Sets
my $confragecount;		#Zaehler fuer die Fragen innerhalb eines Conjoint-Sets
my $fragenid;			#Eindeutige ID einer Frage
my $katcount = 1;		#speichert die durchlaufenen Kategorien
my $katakt;			#aktuelle Kategorie
my $katmax;			#maximale Anzahl an Kategorien
my $leer = 0;			#speichert ob bereits der JS Teil 'leer' ausgegeben wurde
my $endtext;			#enthaelt den Text der letzten Seite
my $titel;			#Titel des Fragebogens
my $version;			#Version des Fragebogens
my $beschr;			#Begruessungstext
my $sessionfile;		#File in dem die Sessiondaten gespeichert werden
my $print;			#Flag ob Ausgabe erfolgt oder nicht
my $contag;			#Flag ob wir uns innerhalb eines Conjoint-Blocks befinden
my $kattag;			#Flag ob wir uns innerhalb eines Kategorie-Blocks befinden
my $kopf;			#enthaelt die Kopfzeile des Conjoint Codings
my $kuerzel;			#speichert Fragenkuerzel
my $encoding;			#speichert die Art der Kodierung pro Kategorie
my $min;			#speichert das Minimum bei Bewertung, falls vorhanden
my $max;			#speichert das Maximum bei Bewertung, falls vorhanden
my $wert;			#enthaelt den Wert der einzelnen Antwortoptionen
my $labels;			#enthaelt den die Labels (mit : "Doppelpunkt" getrennt) der Antwortoptionen bei Bewertungsfragen
my $label_nullopt;	#enthaelt den das Labels der Nulloption bei Bewertungsfragen
my @optid;			#Eindeutige ID der Antwortoption
my %optwert;			#speichert die einzelnen Werte in einem Hash
my %optbe;			#speichert die Beschreibung der Produkte zu den Antworten in einem Hash
my %optpic;			#speichert den Pfad der Bilder zu den Antworten in einem Hash
my %optc;			#speichert den Conjoint-Code zu den Antworten in einem Hash
my %opttext;			#speichert den Optionstext
my $starttag;			#speichert den Wert wenn der Parser ein oeffnendes Tag erreicht
my $endtag;			#speichert den Wert wenn der Parser ein schliessendes Tag erreicht
my $fragetext;			#speichert die Frage
my @felder;			#speichert die Parameter einer Session
my @data;			#enthaelt die Datenzeilen fuer den Export
my @header;			#enthaelt die Kopfzeilen fuer den Export
my $conjoint;			#enthaelt die Conjoint-Daten fuer den Export
my $conkopf = 0;		#Flag ob Kopfzeile bei Conjoint-Export ausgegeben wurde
my $seite;			#zaehlt die Seiten mit
my $filter;			#enthaelt das Kuerzel der Quellfrage
my $wenn;			#enthaelt den Wert der Filterpruefung
my $filtertag;
my $optiontag;
my $empty = 1;
my $incgi;
my @kategorie;
my %sessfile;
my $qid;			#FragenID
my $oid;			#OptionsID
my $scramble;			#Mischen der Attribute (wahr/falsch)
my $weiter;			#Schalter zum Ueberspringen der Frage
my $attribtag;			#Attributliste erreicht
my $ansicht;			#Art der Darstellungsform bei auswahl/bin
my $nullopt;			#Null Option bei Bewertung ausblenden
my $tn;					#speichert übergebene ID
my $response;		#Inhalt der Responsetime Datei

my $md5 = Digest::MD5->new;
my $secret = "kofler";		#Schlüsselzusatz für MD5 Prüfsumme

#Texte aus Languagefile laden
my $msg = &get_msg($langfile);



my $converter = Text::Iconv->new("UTF-8", "ISO-8859-1"); #Linux Version - Konvertierung zw. UTF8 und LATIN1

#---------------------------------------------------------------------
# MAIN
#---------------------------------------------------------------------

if ($cgi->param('do') eq 'query')	#Startknopf oder 'Naechste Seite' wurde gedrueckt
{
	#Variablen definieren
	$tn = $cgi->param('tn');
	$katmax = $cgi->param('katmax');
	$setmax = $cgi->param('setmax');
	$confragenmax = $cgi->param('confragenmax');
	$confrageakt = $cgi->param('confrageakt');
	$sessionfile = $cgi->param("session");
	
	# Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
	my $tn_log_text = "TN=$tn";
	# /Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer

	#Neues Sessionfile anlegen wenn neuer Fragebogen ...
	if (!$sessionfile)
	{
		$seite = 0;
		$katakt = 1;
		$frageakt = 1;
		$sessionfile = "session".time.".tmp";

		&write_log("SESSION=$sessionfile;Fragebogen gestartet;$tn_log_text");

		if ($setmax > 50)
		{
			$XMLfile = &generate_xml($XMLfile,$sessionfile,$setmax);
			$myxml = 1;
		}
	}
	elsif (-e $tmppath.$sessionfile)	#sonst vorhandenes Sessionfile oeffnen
	{
		$seite = $cgi->param("seite");
		$frageakt = $cgi->param("frageakt");
		$katakt = $cgi->param("katakt");
		if (defined ($cgi->param("XMLfile")))
		{
			$XMLfile = $cgi->param("XMLfile");
			$myxml = 1;
		}
	
		#Sessionfile nach Kategorien absuchen
		&get_kat;
	}
	else
	{
	        &print_htmlheader("Fragebogen");	        

		&print_err ("$msg->[51]","61",2);
	        &print_htmlfooter;
	}

	#HTML Kopf ausgeben
	&print_htmlheader("Fragebogen");	

	#Fehler ausgeben und beenden falls XMLfile nicht existiert
	&print_err ("$msg->[50]","01",1) unless (-e $XMLfile);

	#wenn noch nicht auf lezter Seite ...
	if ($katmax >= $katakt)
	{
		#Formular Kopf ausgeben
		&print_formheader;

		#JavaScript Kopf zuweisen
		&start_js;

		#XMLfile bearbeiten 
		&get_xml($XMLfile);

		#JavaScript Ende zuweisen
		&end_js;

		#Session Information der bereits ausgefuellten Seite speichern
		&save_cgi;

		#JavaScript Code ausgeben
		print $js;
		undef $js;

		$html.= "<input type=\"hidden\" name=\"do\" value=\"query\">\n";
		$html.= "<input type=\"hidden\" name=\"session\" value=\"$sessionfile\">\n";
		$html.= "<input type=\"hidden\" name=\"tn\" value=\"$tn\">\n";
	  	$html.= "<input type=\"hidden\" name=\"XMLfile\" value=\"$XMLfile\">\n" if ($myxml == 1);

		#HTML Code ausgeben
		print $html;
		undef $html;

		#Formular Ende ausgeben
		&print_formfooter;
	}
	else	#Fragebogen fertig ausgefuellt
	{
		#Informationen aus dem XMLfile holen
		&get_info($XMLfile);

		#Session Information der letzten ausgefuellten Seite speichern
		&save_cgi;

		#Variablen definieren und nochmals einlesen
		our $xlscol=2;

		#Wenn der aktuelle Fragebogen noch nicht die maximale Anzahl erreicht hat ...
		if ($fragebogenid < $maxID)
		{
			#...dann Sessionfile abarbeiten und Daten speichern
			if (&do_param == 0)
			{
				&print_html($endtext,$titel,$version,1);
			}
			else #Daten nur einmal speichern falls ein Reload auftritt
			{
				&print_err("$msg->[51]",'02',1);
			}
		}
		elsif ($fragebogenid == $maxID)		#der letzte Fragebogen wurde erreicht
		{
			#Sessionfile abarbeiten und Daten speichern
			if (&do_param == 0)
			{
				&print_html("$endtext<br><br>$msg->[52]",$titel,$version,2);
			}
			else #Daten nur einmal speichern falls ein Reload auftritt
			{
				&print_err("$msg->[51]",'03',2);
			}
		}
		else	#das Maximum an Frageboegen wurde erreicht
		{
			&print_err("$msg->[53]",'04',2);
		}

		#Session loeschen
		if ($debug ne 1)
		{
			unlink ("$tmppath$sessionfile") or &print_err ("$sessionfile - $msg->[100]",'05',1);
		}
		unlink ($XMLfile) if ($myxml == 1);	

	&write_log("SESSION=$sessionfile;Fragebogen beendet;ID=$fragebogenid;$tn_log_text");
	}

	#HTML Ende ausgeben
	&print_htmlfooter;
}
elsif ($cgi->param('js') == 1)		#JavaScript aktiviert -> Startseite ausgeben
{
	$tn = $cgi->param('tn');
	my $ck = $cgi->param('ck');
	
	#MD5 prüfen
	$md5->add("$tn","$secret");
	my $md5hex = $md5->hexdigest;

	#Session loeschen falls Fragebogen abgebrochen wurde
	my $tmp = $cgi->param('session');
	my $xml = $cgi->param('xml');
	unlink ($tmp) if ($tmp =~ /\.tmp$/);
	unlink ($xml) if ($xml =~ /\.xml$/);

	# Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
	&write_log("SESSION=$tmp;Fragebogen abgebrochen;TN=$tn") if (defined $tmp);
	# /Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer

	#Alle Sessionfiles loeschen die aelter als 1 Tag sind
	&del_tmp if ($debug ne 1);

	#Startseite ausgeben
	&print_htmlheader("WEB-Fragebogen $ver - $msg->[1]");

#	print $md5hex;
	
	#Fehler ausgeben und beenden falls XMLfile nicht existiert
	&print_err ("$msg->[50]",'06',1) unless (-e $XMLfile);

	#Informationen aus dem XMLfile holen
	&get_info($XMLfile);
	$katcount--;
	$setcount--;

	#Startseite weiter ausgeben
    	print "<table class=\"head\" width=\"100%\"><tr><td>\n";
	print "<div class=\"program\" >Fragebogen</div>";
	print "<div class=\"copyright\" > $copyright</div>";
    	print "</td></tr></table>\n";
    	print "<table class=\"body\" width=\"100%\"><tr><td>\n";
	print "$beschr";

	print $cgi->start_form();
	print $cgi->hidden("do","query");
	print $cgi->hidden("katmax",$katcount);
	print $cgi->hidden("setmax",$setcount);
	print $cgi->hidden("confragenmax",$confragenmax);

        print "</td></tr></table>\n";
        print "<table class=\"footer\" width=\"100%\"><tr><td class=\"footer\">\n";

	#Falls die Anzahl der maximal verfuegbaren Fragebogen ueberschritten wurde -> Fehler ausgeben
	if ($fragebogenid > $maxID)
	{
		print "<div class=\"alle\">$msg->[54]</div>";
	}
	elsif ($tn and ($ck ne $md5hex))
	{
		if ($start_nomd5 == 0)
		{
			print $cgi->br;
			print "<div class=\"rot\">$msg->[56]</div>";
			print $cgi->br;
		}
		else
		{
			print "<div>$msg->[55]</div>";
			print $cgi->br;
			print $cgi->button('SubmitButton',"     $msg->[1]     ","document.forms[0].SubmitButton.disabled = true;document.forms[0].submit();");
		}
	}
	else
	{
		print "<input type=\"hidden\" name=\"tn\" value=\"$tn\">";
		print $cgi->button('SubmitButton',"     $msg->[1]     ","document.forms[0].SubmitButton.disabled = true;document.forms[0].submit();");
	}
        print "</td></tr></table>\n";
	print $cgi->endform;
	&print_htmlfooter;
}
else 		#pruefen ob JavaScript aktiviert, wenn ja weiterleiten, sonst Fehlermeldung ausgeben
{
	print $cgi->header;

	my $tn = $cgi->param('tn');
	my $ck = $cgi->param('ck');
	my $jscript = "function check() {\n";
	$jscript .= "window.location.href=\"$url?js=1&tn=$tn&ck=$ck\"\n";
	$jscript .= "}\n";
	$jscript .= "setTimeout(\'check()\', 20);\n";
	print $cgi->start_html(-title=>"WEB-Fragebogen $ver - Test JavaScript", -script=>$jscript);
	print "<noscript>\n";
	print "<p>$msg->[2]\n";
	print "</noscript>\n";

	&print_htmlfooter;
}


exit;

#---------------------------------------------------------------------
# Subs fragebogen.pl
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Erstellt eine temporaere XML-Datei mit nur einem Set der 
# Conjoint-Fragen um die Performance zu erhoehen
#---------------------------------------------------------------------
sub generate_xml
{
	my $XMLfile = shift;
	my $sessionfile = shift;
	my $setmax = shift;
	my $outputfile = $tmppath.$sessionfile;
	$outputfile =~ s/\.tmp$/\.xml/;
	my $count = 0;
	my $ok = 0;
  	my $setakt = int(rand($setmax));
  	$setakt = $setmax if ($setakt == 0);

	open (IN ,"<$XMLfile") or &print_err ("$XMLfile - $msg->[101]",'07',1);
	flock (IN, LOCK_EX);
	open (OUT ,">$outputfile") or &print_err ("$outputfile - $msg->[102]",'08',1);

	while (<IN>)
	{
		if ( $_ =~ /<conjoint/ )
		{
			$ok = -1;
			print OUT $_;
			next;
		}

		if ( $_ =~ /<set>/ )
		{
			$ok = 0 if ( $count == $setakt );
			$count++;
		}

		if ( $_ =~ /<\/set>/ and $ok == 0 )
		{
			$ok = -1;
			print OUT $_;
			next;
		}
		
		if ( $_ =~ /<\/conjoint>/ )
		{
			$ok = 0;
		}

		if ($ok == 0)
		{
			print OUT $_;
		}
	}

	close (OUT) or &print_err ("$outputfile - $msg->[103]",'09',1);
	close (IN) or &print_err ("$XMLfile - $msg->[103]",'10',1);
	
	return $outputfile;
}

#---------------------------------------------------------------------
# Zählt die </frage> tags um herauszufinden, wieviele 
# Fragen insgesamt gestellt werden
# AA, 12.05.2010
#---------------------------------------------------------------------
sub number_of_questions
{
	my $XMLfile = shift;
	my $noq = 0;
	open (IN ,"<$XMLfile") or &print_err ("$XMLfile - $msg->[101]",'07',1);
	flock (IN, LOCK_EX);
	while (<IN>)
	{
		if ( $_ =~ /<\/frage>/ )
		{
			$noq++;
		}

	}
	close (IN) or &print_err ("$XMLfile - $msg->[103]",'10',1);
	return $noq;
}
#---------------------------------------------------------------------
# Definiert die Behandlung des XML-Files und startet den Parser
#---------------------------------------------------------------------
sub get_xml
{
  my $XMLfile = shift;
  my $parser = new XML::Parser ();
  $parser->setHandlers (Start => \&Start_handler,End => \&End_handler,Default => \&Default_handler);
  $parser->parsefile ($XMLfile) or &print_err ("$XMLfile - $msg->[101]",'11',1);  	
}

#---------------------------------------------------------------------
# Aufgerufen bei Erreichen eines Starttags
#---------------------------------------------------------------------
sub Start_handler
{
  my $p=shift;
  $starttag=shift;

  if ($starttag eq "fragebogen")
  {
	  while (my $attr=shift)
	  {
		  my $val=u2a(shift);
		  $version=$val if ($attr eq "version");
		  $titel=$val if ($attr eq "titel");
	  }
	  if ($seite == 0)
	  {
	  	$html.= "<input type=\"hidden\" name=\"version\" value=\"$version\">\n";
	  	$html.= "<input type=\"hidden\" name=\"interviewer\" value=\"$interviewer\">\n";
	  }
	  $html.= "<table class=\"top\" width=\"100%\"><tr><td>\n";
	  $html.= "<div class=\"topheader\">$titel</div>\n";
	  #$html.= "<div class=\"topver\">Version: $version</div>\n";
	  $html.= "</td></tr></table>\n";
  	  $html.= "<table class=\"main\" width=\"100%\"><tr><td>\n";
  }
  elsif ($starttag eq "kategorie" && $katakt == $katcount)
  {
	  $fragecount = 1;
	  $kattag = 1;
	  my $beschr;
	  my $titel;
	  
	  while (my $attr=shift)
	  {
		  my $val=u2a(shift);
		  $titel = $val if ($attr eq 'titel');
		  $beschr = $val if ($attr eq 'beschreibung');
	  }

	  $html.= "<div class=\"kat\">$beschr</div>\n";

  }
  elsif ($starttag eq "conjoint" && $katakt == $katcount)
  {
	  my $beschr;
	  my $titel;

	  while (my $attr=shift)
	  {
		  my $val=u2a(shift);
		  $kopf = $val if ($attr eq "kopf");
		  $titel = $val if ($attr eq 'titel');
		  $beschr = $val if ($attr eq 'beschreibung');
	  }

	  $html.= "<div class=\"kat\">$beschr</div>\n";

	  if ($cgi->param('setakt'))
	  {
		  $setakt = $cgi->param('setakt');
	  }
	  elsif ($myxml == 1)
	  {
	  	$setakt = 1;
		$confrageakt = 1;
	  }
	  else
	  {
	  	$setakt = int(rand($setmax));
	  	$setakt = $setmax if ($setakt == 0);
		$confrageakt = 1;
  	  }

	  $html.= "<input type=\"hidden\" name=\"setakt\" value=\"$setakt\">\n";

	  if ($confragenmax == $confrageakt)
	  {
	  	$html.= "<input type=\"hidden\" name=\"frageakt\" value=\"1\">\n";
	  	$html.= "<input type=\"hidden\" name=\"katakt\" value=\"".++$katakt."\">\n";
	  	$katakt--;
	  }
	  else
	  {
	  	$html.= "<input type=\"hidden\" name=\"katakt\" value=\"$katakt\">\n";
	  }
  }
  elsif ($starttag eq "set" && $setakt == $setcount)
  {
	  $contag = 1;
	  $confragecount = 1;
	  $html.= "<input type=\"hidden\" name=\"kopf\" value=\"$kopf\">\n";

  }
  elsif ($starttag eq "frage" && $fragecount == $frageakt && $kattag)
  {
	  $print = 1;
	  while (my $attr=shift)
	  {
		  my $val=shift;
		  $kuerzel=$val if ($attr eq "kuerzel");
		  $encoding=$val if ($attr eq "kodierung");
		  $min=$val if ($attr eq "min");
		  $max=$val if ($attr eq "max");
		  $qid=$val if ($attr eq "id");
		  $ansicht=$val if ($attr eq "ansicht");
		  $nullopt=$val if ($attr eq "nullopt");
		  $labels=$val if ($attr eq "labels");
		  $label_nullopt=$val if ($attr eq "labelnullopt");
	  }

  }
  elsif ($starttag eq "frage" && $contag && $confragecount == $confrageakt)
  {
	  $print = 1;
	  while (my $attr=shift)
	  {
		  my $val=shift;
		  $kuerzel=$val if ($attr eq "kuerzel");
		  $encoding=$val if ($attr eq "kodierung");
		  $min=$val if ($attr eq "min");
		  $max=$val if ($attr eq "max");
		  $labels=$val if ($attr eq "labels");
	  }
  }
  elsif ($starttag eq "filter" && $print)
  {
	  $filtertag = 1;

	  while (my $attr=shift)
	  {
		  my $val=shift;
		  $filter=$val if ($attr eq "frage");
		  $wenn=$val if ($attr eq "wenn");
	  }

	  my @felder = $cgi->param();
	  $incgi = 1 if grep(/$filter/,@felder);

	  $filtertag = &test_filter($filter,$wenn);

	  if ($filtertag == -1)
	  {
		  undef $print;
		  undef $max;
		  undef $min;
		  $empty = 1;
	  }
  }
  elsif ($starttag eq "attributliste" && $contag)
  {
	  $attribtag = 1;
	  $optid[0] = 0;
  }
  elsif ($starttag eq "antwort" && $print)
  {
	  while (my $attr=shift)
	  {
		  my $val=shift;
		  $scramble=$val if ($attr eq "scramble");
	  }
  }
  elsif ($starttag eq "option" && $print)
  {
	  $optiontag = 1;
	  while (my $attr=shift)
	  {
		  my $val=shift;
		  $wert=$val if ($attr eq "wert");
		  $oid=$val if ($attr eq "id");
	  }
	  $oid = $wert if ($contag);
  }
}

#---------------------------------------------------------------------
# Aufgerufen bei Erreichen eines EndTags
# und zuständig für die Verarbeitung der Fragen
# entsprechend dem Encoding
#---------------------------------------------------------------------
sub End_handler
{
  my $p=shift;
  $endtag=shift;

  if ($print)
  {
	  if ($endtag eq "frage" && defined ($encoding) && $fragenum == 1)
	  {
	  	$fragetext = "Frage ".++$seite.": ".$fragetext;
	  	$seite--;
	  }
	  if ($endtag eq "frage" && $encoding eq "info")
	  {
		  $html.= "<table width=\"70%\" cellpadding=\"3\" border=\"0\" align=\"center\">\n";
		  $html.= "<tr><td align=\"center\">\n";
		  $html.= "<div class=\"infoseite\">".xml2html($fragetext)."</div>\n";
	 	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img></td>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr>\n";
		  $html.= "</table>\n";

		  undef $fragetext;
	  }
	  if ($endtag eq "frage" && $encoding eq "rangfix")
	  {
		  foreach (@optid)
		  {
			  $html.= $cgi->hidden($_,$optwert{$_})."\n";
		  }

		  $weiter = 1;

		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optbe;
		  undef %optwert;
		  undef %optpic;
	  }
	  if ($endtag eq "frage" && $encoding eq "rang")
	  {
		  my $array;
		  my $max = @optid;
		  my @optid2;

		  foreach (@optid)
		  {
			  if ($opttext{$_} eq " - ")
			  {
			  	$html.= $cgi->hidden($_,$max)."\n";
			  }
			  else
			  {
				  push (@optid2,$_);
			  }
		  }

		  @optid = @optid2;
		  $max = @optid;

		  if ($max == 1)
		  {
			  $html.= $cgi->hidden($optid[0],1)."\n";
			  $weiter = 1;
		  }
		  else
		  {
			  if ($scramble eq "wahr")
			  {
				  $array = &shuffle(\@optid);
			  }
			  else
			  {
				  $array = \@optid;
			  }
	
			  #zuerst JavaScript-Code 
			  my $max2 = int($max/2);
			  $max2 += 1 if (($max/2-$max2) > 0);
			  
			  #$js.=&leer_js unless ($leer == 1);
			  $min = $max unless (defined $min);
			  $js.=&fill_min_js($min);
			  $js.=&doppel_js($array->[0],$fragetext);
	
			  #dann den HTML-Code 
			  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  	  $html.= "<tr><td>\n";
		  	  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
			  $html.= "</td>\n";
			  $html.= "<td align=\"center\">\n";
	 	  	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
			  $html.= "</td></tr></table>\n";
			  $html.= "<table class=\"rang\" cellpadding=\"3\">\n";
	
			  $max2 = $max if ((defined %optbe) or (defined %optpic) or ($max < 8));

			  for (my $x=0;$x<$max2;$x++)
			  {
				  #Javascript
				  $js.=&minmax_js(1,$max,$array->[$x]);
				  
				  #HTML
			  	  $html.= "<tr>\n";
				  $html.= "<td class=\"rang\">\n";
				  my $y = $x+1;
				  $html.= "($y) " if ($optnum == 1);
			  	  $html.= "</td>\n";
				  $html.= "<td class=\"rang_opt\">\n";
				  $html.= "$opttext{$array->[$x]}\n";
			  	  $html.= "</td>\n";
			  	  $html.= "<td class=\"rang\">\n";
				  $html.= "<input name=\"$array->[$x]\" type=\"text\" maxlength=\"2\" size=\"2\" onClick=\"write_el(document.forms[0].elements[\'".$array->[$x]."\'].value,$max,'".$array->[$x]."')\">\n";
				  #$html.= "<input type=\"hidden\" name=\"var_$feld\_$optwert{$_}\" value=\"".&u2u("$feld\/$_")."\">\n";
			  	  $html.= "</td>\n";
	
				  $x2 = $x+$max2;
				  if (defined $array->[$x2] and ($max != $max2))
				  {
				  	  #Javascript
					  $js.=&minmax_js(1,$max,$array->[$x2]);
				  
					  #HTML
				  	  $html.= "<td>\n";
					  $html.= "&nbsp;\n";
				  	  $html.= "</td>\n";

					  $html.= "<td class=\"rang\">\n";
				  	  my $y = $x2+1;
					  $html.= "($y) " if ($optnum == 1);
				  	  $html.= "</td>\n";
				  	  $html.= "<td class=\"rang_opt\">\n";
					  $html.= "$opttext{$array->[$x2]}\n";
		 	 	  	  $html.= "</td>\n";
		 	 	  	  $html.= "<td class=\"rang\">\n";
				  	  $html.= "<input name=\"$array->[$x2]\" type=\"text\" maxlength=\"2\" size=\"2\" onClick=\"write_el(document.forms[0].elements[\'".$array->[$x2]."\'].value,$max,'".$array->[$x2]."')\">\n";
			  	  	  $html.= "</td>\n";
			  	  }

				  if (defined $optbe{$array->[$x]})
				  {
					  $html.= "<td class=\"rang\"><span class=\"info\">".&attr($optbe{$array->[$x]})."</span></td>\n";
				  }
				  elsif (defined %optbe)
				  {
					  $html.= "<td class=\"rang\">&nbsp;</td>\n";
				  }
				  if (defined $optpic{$array->[$x]})
				  {
				  $html.= "<td class=\"rang\"><img src=\"$optpic{$array->[$x]}\" alt=\"$optpic{$array->[$x]}\" height=\"$img_height\"></img></td>\n";
				  }
				  elsif (defined %optpic)
				  {
					  $html.= "<td class=\"rang\">&nbsp;</td>\n";
				  }
			  	  $html.= "</tr>\n";
			  }
			  $html.= "</table>\n";
		  }
		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optbe;
		  undef %optwert;
		  undef %optpic;
	  }
	  if ($endtag eq "frage" && $encoding eq "auswahl")
	  {
		  #zuerst JavaScript-Code 

		  #dann den HTML-Code 
		  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  $html.= "<tr><td width=\"80%\">\n";
		  $html.= "</td>\n";
		  $html.= "<td align=\"center\">\n";
	   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr></table>\n";
		  $html.= "<table class=\"auswahl\">\n";
	  	  $html.= "<tr>\n";
  		  $html.= "<td class=auswahlfrage>\n";
		  $html.= "$fragetext\n";
  		  $html.= "</td>\n";
  		  $html.= "<td>\n";

		  my $array;
		  if ($scramble eq "wahr")
		  {
			  $array = &shuffle(\@optid);
		  }
		  else
		  {
			  $array = \@optid;
		  }

		  if ($ansicht eq "radio")
		  {
			  my $maxjs = @optid;
		  	  $js.=&bew_js($maxjs,$qid);
			  foreach (@$array)
			  {
			  	$html.= "<input type=\"radio\" name=\"$qid\" value=\"$optwert{$_}\"> $opttext{$_}<br>\n";
			  }
		  }
		  else
		  {
			  $html.= "<select name=\"$qid\" size=\"1\">\n";

			  foreach (@$array)
			  {
				  $html.= "<option";
				  $html.= " value=\"$optwert{$_}\"";
				  $html.= ">$opttext{$_}</option>\n";
			  }
			  $html.= "</select>\n";
		  }

  		  $html.= "</td>\n";
  		  $html.= "</tr>\n";
		  $html.= "</table>\n";
		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optwert;
		  undef $ansicht;
	  }
	  if ($endtag eq "frage" && $encoding eq "auswahlbin")
	  {
		  #zuerst JavaScript-Code 

		  #dann den HTML-Code 
		  my $opts;
		  $html.= "<input type=\"hidden\" name=\"encoding_$qid\" value=\"auswahlbin\">\n";
		  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  $html.= "<tr><td width=\"80%\">\n";
		  $html.= "</td>\n";
		  $html.= "<td align=\"center\">\n";
	   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr></table>\n";
		  $html.= "<table class=\"auswahl\">\n";
  		  $html.= "<tr>\n";
		  my $maxrows = @optid + 2;
  		  $html.= "<td rowspan=\"$maxrows\" class=\"auswahlfrage\">\n";
		  $html.= "<b>".xml2html($fragetext)."</b>\n";
  		  $html.= "</td>\n";
  		  $html.= "<td>\n";

		  foreach (@optid)
		  {
			$opts.= $_.":";
		  }

		  my $array;
		  if ($scramble eq "wahr")
		  {
			  $array = &shuffle(\@optid);
		  }
		  else
		  {
			  $array = \@optid;
		  }

		  if ($ansicht eq "radio")
		  {
			  my $maxjs = @optid;
		  	  $js.=&bew_js($maxjs,$qid);
			  foreach (@$array)
			  {
				$html.= "<tr>\n";
				$html.= "<td class=\"auswahloption\">\n";
			  	$html.= "<input type=\"radio\" name=\"$qid\" value=\"$_\"> $opttext{$_}\n";
				if (defined $optpic{$_})
				{
					$html.= "<td class=\"auswahloption\">\n";
					$html.= "<img src=\"$optpic{$_}\" alt=\"$optpic{$_}\" height=\"$img_height\"></img>\n";
					$html.= "</td>\n";
				}
				$html.= "</td>\n";
				$html.= "</tr>\n";
			  }
		  }
		  else
		  {
			  $html.= "<select name=\"$qid\" size=\"1\">\n";

			  foreach (@$array)
			  {
				  $html.= "<option";
				  $html.= " value=\"$_\"";
				  $html.= ">$opttext{$_}</option>\n";
			  }
			  $html.= "</select>\n";
	  	  }
	  	  $html.= "</td>\n";
  		  $html.= "</tr>\n";
		  $html.= "</table>\n";
		  chop ($opts);
		  $html.= "<input type=\"hidden\" name=\"optionen_$qid\" value=\"$opts\">\n";

		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optwert;
		  undef $ansicht;
	  }
	  if ($endtag eq "frage" && $encoding eq "auswahlxbin")
	  {
		  my $array;
		  if ($scramble eq "wahr")
		  {
			  $array = &shuffle(\@optid);
		  }
		  else
		  {
			  $array = \@optid;
		  }

		  $min = 1 if not defined($min);
		  $max = 9999 if not defined($max);
		  my $anz = @optid;
		  my $anz2 = int($anz/2);
		  $anz2 += 1 if (($anz/2-$anz2) > 0);

		  #zuerst JavaScript-Code 
		  $js.=&checkbox_js($array,$min,$max);

		  #dann den HTML-Code 
		  my $opts;
		  $html.= "<input type=\"hidden\" name=\"encoding_$qid\" value=\"auswahlxbin\">\n";
		  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  $html.= "<tr><td>\n";
		  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
		  $html.= "</td>\n";
		  $html.= "<td align=\"center\">\n";
	   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr></table>\n";
		  $html.= "<table class=\"xbin\" cellpadding=\"5\">\n";

		  $anz2 = $anz if ((defined %optbe) or (defined %optpic) or ($anz < 8));

		  for (my $x=0;$x<$anz2;$x++)
		  {
		  	  $html.= "<tr>\n";
		  	  $html.= "<td class=\"rang_opt\">\n";
			  $html.= "($optwert{$array->[$x]})" if (defined %optwert and $optnum == 1);
			  $html.= " $opttext{$array->[$x]}\n";
		  	  $html.= "</td>\n";
		  	  $html.= "<td class=\"rang\">\n";
			  $html.= "<input type=\"checkbox\" name=\"$array->[$x]\" value=\"1\">\n";
		  	  $html.= "</td>\n";

			  $x2 = $x+$anz2;
			  if (defined $array->[$x2] and ($anz != $anz2))
			  {
			  	  $html.= "<td>\n";
				  $html.= "&nbsp;\n";
			  	  $html.= "</td>\n";

			  	  $html.= "<td class=\"rang_opt\">\n";
				  $html.= "($optwert{$array->[$x2]}) " if (defined %optwert and $optnum == 1);
				  $html.= "$opttext{$array->[$x2]}\n";
			  	  $html.= "</td>\n";
			  	  $html.= "<td class=\"rang\">\n";
				  $html.= "<input type=\"checkbox\" name=\"$array->[$x2]\" value=\"1\">\n";
			  	  $html.= "</td>\n";
			  }

			  if (defined $optbe{$array->[$x]})
			  {
				  $html.= "<td class=\"rang\"><span class=\"info\">".&attr($optbe{$array->[$x]})."</span></td>\n";
			  }
			  elsif (defined %optbe)
			  {
				  $html.= "<td class=\"rang\">&nbsp;</td>\n";
			  }
			  if (defined $optpic{$array->[$x]})
			  {
			  	  $html.= "<td class=\"rang\"><img src=\"$optpic{$array->[$x]}\" alt=\"$optpic{$array->[$x]}\" height=\"$img_height\"></img></td>\n";
			  }
			  elsif (defined %optpic)
			  {
				  $html.= "<td class=\"rang\">&nbsp;</td>\n";
			  }
		  	  $html.= "</tr>\n";
		  }
		  
		  $html.= "</table>\n";
		  foreach (@$array)
		  {
			  $opts.= $_.":";
		  }
		  chop ($opts);
		  $html.= "<input type=\"hidden\" name=\"optionen_$qid\" value=\"$opts\">\n";

		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optwert;
		  undef %optbe;
		  undef %optpic;
	  }
	  if ($endtag eq "frage" && $encoding eq "bewertung")
	  {
		  my $array;
		  if ($scramble eq "wahr")
		  {
			  $array = &shuffle(\@optid);
		  }
		  else
		  {
			  $array = \@optid;
		  }

		  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  $html.= "<tr><td>\n";
		  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
		  $html.= "</td>\n";
		  $html.= "<td align=\"center\">\n";
	   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr></table>\n";
		  $html.= "<table class=\"bew\" cellpadding=\"3\">\n";
		  $html.= "<tr>\n";
		  $html.= "<td class=\"bewtop\">\n";
		  $html.= "&nbsp;";
  		  $html.= "</td>\n";
		  
		  my @labels_array = split(":",$labels);
		  
		  if ($nullopt ne "0")
		  {
				$html.= "<td class=\"bewtop\">\n";
				if ($label_nullopt ne "") {
					$html.= "$label_nullopt\n";
				} else {
					$html.= "0\n";
				}
				$html.= "</td>";
		  }
		  $html.= "<td class=\"bewtop\" width=\"20px\">\n";
		  $html.= "&nbsp;";
  		  $html.= "</td>\n";
		  
		  for (my $col=$min;$col<=$max;$col++)
		  {
			  if (@labels_array > 0) {
				$html.= "<td class=\"bewtop\">@labels_array[$col - 1]</td>\n";
			  } else {
				$html.= "<td class=\"bewtop\">$col</td>\n";
			  }
		  }

		  my $defbe = 0;
		  my $defpic = 0;
		  my $arr_anzahl = 0;

		  foreach (@$array)
		  {
			  $arr_anzahl++;
			  $defbe = 1 if (defined $optbe{$_});
			  $defpic = 1 if (defined $optpic{$_});
		  }
		  $html.= "<td class=\"bewtop\" width=\"20px\">&nbsp;</td>\n" if ($defbe == 1 or $defpic == 1);
		  $html.= "<td class=\"bewtop\">$msg->[3]</td>\n" if ($defbe == 1);
		  $html.= "<td class=\"bewtop\">$msg->[4]</td>\n" if ($defpic == 1);

  		  $html.= "</tr>\n";

		  foreach (@$array)
		  {
		  	  #zuerst JavaScript-Code 
		  	  my $maxjs = abs($max-$min)+1;
			  if ($nullopt eq "0")
			  {
					$maxjs--;
			  }
		  	  $js.=&bew_js(++$maxjs,$_);

		  	  #dann den HTML-Code 
			  $html.= "<tr>\n";
			  $html.= "<td class=\"bew\">$opttext{$_}</td>\n";
			  if ($nullopt ne "0")
			  {
				$html.= "<td>\n";
				$html.= "<input type=\"radio\" name=\"$_\" value=\"§§§\">\n";
				$html.= "</td>\n";
			  }
			  $html.= "<td>&nbsp;</td>\n";
			  for (my $col=$min;$col<=$max;$col++)
			  {
				  $html.= "<td>\n";
				  $html.= "<input type=\"radio\" name=\"$_\" value=\"$col\">\n";
				  $html.= "</td>\n";
			  }
			  
		  	  $html.= "<td width=\"20px\">&nbsp;</td>\n" if ($defbe == 1 or $defpic == 1);
			  $html.= "<td><span class=\"info\">".&attr($optbe{$_})."</span></td>\n" if (defined $optbe{$_});
			  $html.= "<td><img src=\"$optpic{$_}\" alt=\"$optpic{$_}\" height=\"$img_height\"></img></td>\n" if (defined $optpic{$_});
		  	  $html.= "</tr>\n";
		  }
		  if ($arr_anzahl > 5)
		  {
			  $html.= "<tr>\n";
			  $html.= "<td class=\"bewtop\">\n";
			  $html.= "&nbsp;";
	  		  $html.= "</td>\n";
			  if ($nullopt ne "0")
			  {
				$html.= "<td class=\"bewtop\">\n";
				$html.= "0\n";
				$html.= "</td>";
			  }
			  $html.= "<td class=\"bewtop\">\n";
			  $html.= "&nbsp;";
	  		  $html.= "</td>\n";
			  for (my $col=$min;$col<=$max;$col++)
			  {
				  $html.= "<td class=\"bewtop\">$col</td>\n";
			  }

			  $html.= "<td class=\"bewtop\" width=\"20px\">&nbsp;</td>\n" if ($defbe == 1 or $defpic == 1);
			  $html.= "<td class=\"bewtop\">$msg->[3]</td>\n" if ($defbe == 1);
			  $html.= "<td class=\"bewtop\">$msg->[4]</td>\n" if ($defpic == 1);

	  		  $html.= "</tr>\n";
		  }
		  
		  $html.= "</table>\n";

		  undef @optid;
		  undef $fragetext;
		  undef $min;
		  undef $max;
		  undef %opttext;
		  undef %optbe;
		  undef %optpic;
		  undef %optwert;
	  }
	  if ($endtag eq "frage" && $encoding eq "numerisch")
	  {
		  my $laenge;

		  #zuerst JavaScript-Code 
		  $js.=&leer_js unless ($leer == 1);

		  #dann HTML-Code
		  if (defined $max)
		  {
			  $laenge = length($max);
			  $laenge++ if (defined $min && $min < 0);
		  }
		  else
		  {
			  $laenge = 6;
		  }

		  if (@optid)
		  {
		  	my $array;
			  if ($scramble eq "wahr")
			  {
				  $array = &shuffle(\@optid);
			  }
			  else
			  {
				  $array = \@optid;
			  }

			  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  	  $html.= "<tr><td>\n";
		  	  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
			  $html.= "</td>\n";
			  $html.= "<td align=\"center\">\n";
		   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
			  $html.= "</td></tr></table>\n";
  		  	  $html.= "<table class=\"num\">\n";
			  foreach (@$array)
			  {
		  	  	$html.= "<tr>\n";
		  	  	$html.= "<td class=\"num_opt\">\n";
			  	$html.= "$opttext{$_}\n";
		  	  	$html.= "</td>\n";
				my $element = &a2u($_);

			  	#Javascript
			  	$js.=&minmax_js($min,$max,$_);

			  	#HTML
		  	  	$html.= "<td class=\"num\">\n";
			  	$html.= "<input name=\"$_\" type=\"text\" maxlength=\"$laenge\" size=\"$laenge\">\n";

		  	  	$html.= "</td>\n";
		  	  	$html.= "</tr>\n";
			  }
  		  	  $html.= "</table>\n";
		  }
		  else
		  {
			  #Javascript
		  	  $js.=&minmax_js($min,$max,$qid);

			  #HTML
		  	  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
			  $html.= "<tr><td width=\"80%\">\n";
			  $html.= "</td>\n";
			  $html.= "<td align=\"center\">\n";
		   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
			  $html.= "</td></tr></table>\n";
  		  	  $html.= "<table class=\"num\">\n";
  		  	  $html.= "<tr>\n";
  		  	  $html.= "<td class=\"auswahlfrage\">\n";
		  	  $html.= "<b>".xml2html($fragetext)."</b>\n";
  		  	  $html.= "</td>\n";
  		  	  $html.= "<td>\n";
			  $html.= "<input name=\"$qid\" type=\"text\" maxlength=\"$laenge\" size=\"$laenge\">\n";
			  # Philip Langer (2008-09-25): Null-Option bei numerischen Fragen
			  # encoding mitgeben, da später durch checkbox beim CVS-Schreiben aufgepasst werden muss.
			  $html.= "<input type=\"hidden\" name=\"encoding_$qid\" value=\"numerisch\">\n";
			  # Wenn Nulloption angegeben, wird HTML-Checkbox und JavaScript hinzugefügt.
			  if ($nullopt eq "1")
			  {
				$html.= "<input name=\"$qid\_nulloption\" type=\"checkbox\" onClick=\"noOptClicked()\">&nbsp;$msg->[17]\n";
				$html.= "<script type=\"text/javascript\">\n";
				$html.= "  function noOptClicked() {\n";
				$html.= "  	if(document.forms[0].elements[\"$qid\_nulloption\"].checked == true) {\n";
				$html.= "  		document.forms[0].elements[\"$qid\"].value=\"\";\n";
				$html.= "  		document.forms[0].elements[\"$qid\"].disabled=true;\n";
				$html.= "  	} else {\n";
				$html.= "  		document.forms[0].elements[\"$qid\"].disabled=false;\n";
				$html.= "  	}\n";
				$html.= "  }\n";
				$html.= "</script>\n";
			  }
			  # /Phili p Langer (2008-09-25)
  		  	  $html.= "</td>\n";
  		  	  $html.= "</tr>\n";
  		  	  $html.= "</table>\n";
		  }
		  undef @optid;
		  undef %opttext;
		  undef $fragetext;
	  }
	  if ($endtag eq "frage" && $encoding eq "text")
	  {
		  #zuerst JavaScript-Code 

		  #dann HTML-Code
	  	  $html.= "<table cellpadding=\"3\" border=\"0\" width=\"100%\">\n";
		  $html.= "<tr><td>\n";
		  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
		  $html.= "</td>\n";
		  $html.= "<td align=\"center\">\n";
	   	  $html.= "<img src=\"$optpic{$qid}\" alt=\"$optpic{$qid}\" height=\"$img_height\"></img>\n" if (defined $optpic{$qid});
		  $html.= "</td></tr></table>\n";
		  $html.= "<textarea class=\"text\" name=\"$qid\" cols=\"50\" rows=\"7\">\n";
  		  $html.= "</textarea>\n";
		  undef $fragetext;
	  }	  
	  if ($endtag eq "frage" && $encoding eq "conjoint")
	  {
		  #zuerst JavaScript-Code 
		  my $maxjs = @optid;
		  my $feld = "c".&a2u($kuerzel);
		  $js.=&con_js($maxjs,$feld);

		  #dann den HTML-Code 
		  $html.= "<input type=\"hidden\" name=\"contimestart\" value=\"".time."\">\n";
		  $html.= "<input type=\"hidden\" name=\"encoding_$feld\" value=\"conjoint\">\n";
		  if (defined %optwert)
		  {
			  my @value = sort(NummernSort values(%optwert));
			  $html.= "<input type=\"hidden\" name=\"maxvalue_$feld\" value=\"".$value[$#value]."\">\n";
			  $html.= "<input type=\"hidden\" name=\"minvalue_$feld\" value=\"".$value[0]."\">\n";
		  }
		  $html.= "<div class=\"frage\">".xml2html($fragetext)."</div>\n";
		  $html.= "<table class=\"con\" width=\"90%\" cellspacing=\"0\">\n";
		  $html.= "<tr class=\"con\">\n";

		  my $width = (90 / --$maxjs)."%";
		  my $lastel = pop(@optid);

		  # ausgabe der <th> über den attributen
		  foreach (@optid)
		  {
		  	  $html.= "<th class=\"con\" width=\"$width\">\n";
			  $html.= "($optwert{$_}) " if (defined $optwert{$_} and $optnum == 1);
			  $html.= "$opttext{$_}\n";
		  	  $html.= "</th>\n";
		  }
	  	  $html.= "</tr>\n";
		  
		  my @lines;
		  
		  # zusammenbau der attribute <tr> der conjoint 
		  foreach (@optid)
		  {
			  if (defined $optbe{$_} &! defined $optwert{$_})
			  {
				  my @be = split (/\n/,$optbe{$_});
				  foreach (@be)
				  {
					  push (@lines,"+conatt+<span class=\"coninfo\">$_</span></td>");
				  }
			  }
			  else
			  {
				  my @be = split (/\n/,$optbe{$_});
				  my $x = 0;
				  foreach (@be)
				  {
					  $lines[$x] .= "+conbe+<span class=\"coninfo\">$_</span></td>";
					  $x++;
				  }
			  }
		  }

		  # Kategorie linien
		  my $cj_line_no = 1;
		  my $cj_count_attrib = @lines;
		  my $col_anz = @optid;

		  foreach (@lines)
		  {
	  	  	if (defined $conkat{$cj_line_no}) 
			{
				$html.= "<tr class=\"cjkat\">";
				$html.= "<td class=\"cjkat\">&nbsp;&nbsp;".$conkat{$cj_line_no}."</td>";
				for (my $i = 1;$i < $col_anz;$i++)
				{
			  		$html.= "<td class=\"cjkat\">&nbsp;</td>";
		  		}
				$html.= "</tr>\n";
				$cj_line_no++;
			}
			# ausgabe der conjoint rows
		    $html.= "<tr>\n";
			$_ =~ s/^\+conatt\+/<td class=\"conatt\">/;
			$_ =~ s/\+conbe\+/<td class=\"conbe\">/g;
	  	  	$html.= &attr($_)."\n";
	  	  	$html.= "</tr>\n";

			$cj_line_no++;
		  }
	  	  
		  # ausgabe der <tr> nach den attributen 
		  $html.= "<tr>\n";
		  
		  # ausgabe produktbild
		  foreach (@optid)
		  {
		  	  $html.= "<td class=\"conbe\">\n";
		  	  $html.= "<center>&nbsp;\n";
			  $html.= "<img src=\"$optpic{$_}\" alt=\"$optpic{$_}\" height=\"$img_height\"></img></td>\n" if (defined $optpic{$_});
		  }
	  	  $html.= "</tr>\n";
	  	  $html.= "<tr class=\"con\">\n"; # start ausgabe radio buttons
		  foreach (@optid)
		  {
		  	  $html.= "<td class=\"border\">\n";
		  	  $html.= "<center>\n";
			  $html.= "<input type=\"radio\" name=\"$feld\" value=\"$optwert{$_}\" onClick=\"document.forms[0].SubmitButton.disabled = true;document.forms[0].submit();\">\n" if (defined $optwert{$_});
		  	  $html.= "</td>\n";
		  }
		  
	  	  $html.= "<tr>\n";
	 	  $html.= "<td class=\"conbe_leer\" colspan=\"$maxjs\">\n";
	 	  $html.= "&nbsp;\n";
	 	  $html.= "</td>\n";
	  	  $html.= "</tr>\n";
	  	  $html.= "<tr class=\"con\">\n";
	 	  $html.= "<th colspan=\"$maxjs\">\n";
		  $html.= "($optwert{$lastel}) " if (defined %optwert and $optnum == 1);
		  $html.= "$opttext{$lastel}\n";
	 	  $html.= "</th>\n";
	  	  $html.= "<tr class=\"con\">\n";
	 	  $html.= "<td colspan=\"$maxjs\">\n";
		  $html.= "<input type=\"radio\" name=\"$feld\" value=\"$optwert{$lastel}\" onClick=\"document.forms[0].SubmitButton.disabled = true;document.forms[0].submit()\">\n";
	 	  $html.= "</td>\n";
	  	  $html.= "</tr>\n";
		  $html.= "</table>\n";

		  push (@optid,$lastel);
		  foreach (@optid)
		  {
			  $html.= "<input type=\"hidden\" name=\"$feld\_$optwert{$_}\" value=\"$optc{$_}\">\n" if (defined $optwert{$_});
		  }
		  undef @optid;
		  undef $fragetext;
		  undef %opttext;
		  undef %optwert;
		  undef %optbe;
		  undef %optc;
		  undef %optpic;
	  }
	  undef $filtertag if $endtag eq "frage";
	  undef $print if $endtag eq "frage";
	  undef $empty;
  }
  if ($endtag eq "antwort")
  {
	  my @out;
    	  my $prev = "not equal to $optid[0]";

	  @out = grep($_ ne $prev && ($prev = $_, 1), @optid);
	  @optid = @out;
  }
  if ($endtag eq "option")
  {
	undef $oid;
  }
  if ($endtag eq "frage" && $contag)
  {
	  $confragecount++;
	  undef $print;
  }
  if ($endtag eq "frage" && $kattag)
  {
	  $fragecount++;
#	  $frageakt++ if ($filtertag);
	  undef $filtertag;
  }
  if ($endtag eq "kategorie" or $endtag eq "conjoint")
  {
	  $katcount++;
	  undef $print;
	  undef $kattag;
  }
  if ($endtag eq "attributliste")
  {
	  undef $attribtag;
  }
  if ($endtag eq "set")
  {
	  $setcount++;
	  undef $print;
	  undef $contag;
  }
  if ($endtag eq "fragebogen")
  {
	  $html.= "<input type=\"hidden\" name=\"katmax\" value=\"$katmax\">\n";
	  $html.= "<input type=\"hidden\" name=\"setmax\" value=\"$setmax\">\n";
	  $html.= "<input type=\"hidden\" name=\"confragenmax\" value=\"$confragenmax\">\n";

	  $fragecount--;
  	  if ($fragecount <= $frageakt)
	  {
	  	$html.= "<input type=\"hidden\" name=\"frageakt\" value=\"1\">\n";
	  	$html.= "<input type=\"hidden\" name=\"katakt\" value=\"".++$katakt."\">\n";
	  	$katakt--;
  	  }
  	  else
  	  {
	  	$html.= "<input type=\"hidden\" name=\"frageakt\" value=\"".++$frageakt."\">\n";
	  	$frageakt--;
	  	$html.= "<input type=\"hidden\" name=\"katakt\" value=\"$katakt\">\n";
	  }

	  if ($empty or $weiter)
	  {
		  $html.= "<script type=\"text/javascript\">\n";
		  $html.= "<!--\n";
		  $html.= "function los(){\n";
		  $html.= "document.forms[0].SubmitButton.disabled = true;\n";
		  $html.= "document.forms[0].submit();\n";
		  $html.= "}\n";
		  $html.= "window.setTimeout(\'los()\',100);\n"; #muss mit ' ' definiert werden und t >= 20!!
		  $html.= "//-->\n";
		  $html.= "</script>\n";
		  $html.= "<div class=\"frage\">". $msg->[16]."</div>\n";

		  undef $weiter;
	  }
	}
}

#---------------------------------------------------------------------
# Aufgerufen zwischen Anfangs- und EndTag
# und zuständig für das Einlesen des Textes
#---------------------------------------------------------------------
sub Default_handler
{
	if ($print)
	{
		my $p=shift;
		my $val=u2a(shift);
  
		if ($starttag eq "fragetext" && $endtag ne "fragetext")
		{
			$fragetext.=$val;
			$fragetext =~ s/^ +|[\r\t\f]//g;
			$fragetext =~ s/^\n//g;
			$fragetext =~ s/\n/<br>/g;
			$fragetext =~ s/apos/quot/g;
		}

		if (not defined $filtertag or $filtertag > 0)
		{
			if ($starttag eq "zeile" && $attribtag && $val =~ /\S/)
			{
				$optbe{$optid[0]} .= "$val\n";
				$optbe{$optid[0]} =~ s/\n&gt;\n/&gt;/g;
				$optbe{$optid[0]} =~ s/\n&lt;\n/&lt;/g;
				$optbe{$optid[0]} =~ s/\n&amp;\n/&amp;/g;
				$optbe{$optid[0]} =~ s/\n&apos;\n/&apos;/g;
				$optbe{$optid[0]} =~ s/\n&quot;\n/&quot;/g;
			}
			
			if ($starttag eq "optionstext")
			{
				push (@optid,$oid) if (defined $oid);
				$opttext{$oid} .= $val if ($val =~ /\S/ && $endtag ne "optionstext");
				$optwert{$oid} = $wert if (defined $wert);
				undef $wert;
			}
			if ($starttag eq "optionsc" && $endtag ne "optionsc" && $val =~ /\S/)
			{
				$optc{$optid[$#optid]} .= $val;
			}
		
			if ($starttag eq "zeile" && $endtag ne "optionsb" && $val =~ /\S/ &! $attribtag)
			{
				$optbe{$optid[$#optid]} .= "$val\n";
				$optbe{$optid[$#optid]} =~ s/\n&gt;\n/&gt;/g;
				$optbe{$optid[$#optid]} =~ s/\n&lt;\n/&lt;/g;
				$optbe{$optid[$#optid]} =~ s/\n&amp;\n/&amp;/g;
				$optbe{$optid[$#optid]} =~ s/\n&apos;\n/&apos;/g;
				$optbe{$optid[$#optid]} =~ s/\n&quot;\n/&quot;/g;
			}

			if ($starttag eq "bild" && $endtag ne "bild" && $val =~ /\S/)
			{
				$val =~ s/\\/\//g;
				if (defined @optid)
				{
					$optpic{$optid[$#optid]} = "$PicDir$val";
				}
				elsif (defined $qid)
				{
					$optpic{$qid} = "$PicDir$val";
				}
			}
		}
	}
}

#---------------------------------------------------------------------
# Position der jeweils letzten Kategorie speichern
#---------------------------------------------------------------------
sub get_kat
{
	my $zaehler = 1;
	my $sess;
	my $file = $tmppath.$sessionfile;

	open (FILE,"<$file") or &print_err ("$sessionfile - $msg->[102]",'12',1);
	while (!eof(FILE))
	{
		my $session = new CGI(FILE);
		$kategorie[$session->param('seite')] = $zaehler if (defined $session->param('seite'));
		$zaehler++;
	}
	foreach (@kategorie)
	{
		my $pos=$_;
		if (defined $pos)
		{
			seek (FILE,0,0);
			while (!eof(FILE))
			{
				my $i=1;
				do
				{
					$sess = new CGI(FILE);
					$i++;
				}
				until ($i > $pos);
	
				my @felder = $sess->param();
				foreach (@felder)
				{
					$sessfile{$_} = $sess->param($_);
				}
				last;
			}
		}
	}

	close FILE or &print_err ("$sessionfile - $msg->[103]",'13',1);

}

#---------------------------------------------------------------------
# durchsucht die Session-Datei um den Filter anzuwenden
#---------------------------------------------------------------------
sub test_filter
{
	my $filter = shift;
	my $wenn = shift;
	my $erg = -1;

	if (($cgi->param($filter) eq $wenn) or ((defined $cgi->param($wenn)) and ($cgi->param($wenn) ne "")))
	{
		$erg = 1;
		$incgi = 1;
	}
	elsif (not defined $incgi)
	{
		if (($sessfile{$filter} eq $wenn) or ((exists $sessfile{$wenn}) and ($sessfile{$wenn} ne "")))
		{
			$erg = 1;
		}
	}

	$erg++ if $optiontag;
	undef $optiontag;

	return $erg;
}


#---------------------------------------------------------------------
# speichert die Variablen eines ausgefuellten Formulars
# in einer Datei
#---------------------------------------------------------------------
sub save_cgi
{
	my $contime;
	my $contimestart = $cgi->param('contimestart');
	
	if ($contimestart)
	{
	  $contime = time - $contimestart if $contimestart;
	  $cgi->param('contime',$contime);
	}
	
	$cgi->delete('tn');
	$cgi->delete('contimestart');
	$cgi->delete('katmax');
	$cgi->delete('setmax');
	$cgi->delete('do');
	$cgi->delete('session');
	$cgi->delete('submit');
	$cgi->delete('confragenmax');
	$cgi->delete('setakt');
	$cgi->delete('katakt');
	$cgi->delete('frageakt');
	$cgi->delete('confrageakt');
	$cgi->delete('SubmitButton');
	$cgi->delete('XMLfile') if ($myxml == 1);

	if ($seite == 0)
	{
		open (OUT,">$tmppath$sessionfile") or &print_err ("$sessionfile - $msg->[104]",'14',1);
	}
	else
	{
		open (OUT,">>$tmppath$sessionfile") or &print_err ("$sessionfile - $msg->[104]",'15',1);
	}

	$cgi->save(OUT);
	close OUT;
}

#---------------------------------------------------------------------
# Einlesen der XML-Datei, um allg. Informationen auszulesen
#---------------------------------------------------------------------
sub get_info
{
  my $XMLfile = shift;
  my $parse = new XML::Parser ();
  $parse->setHandlers (Start => \&Info_handler,End => \&Info_End);
  $parse->parsefile ($XMLfile) or &print_err ("$XMLfile - $msg->[101]",'16',1);  	
}

sub Info_handler
{
  my $p=shift;
  my $starttag=shift;

  if ($starttag eq "fragebogen")
  {
	  while (my $attr=shift)
	  {
		  my $val=u2a(shift);
		  $version=$val if ($attr eq "version");
		  $titel=$val if ($attr eq "titel");
		  $beschr=$val if ($attr eq "beschreibung");
		  $endtext=$val if ($attr eq "verabschiedung");
	  }
  }
  elsif ($starttag eq "kategorie" or $starttag eq "conjoint")
  {
	  $katcount++;
  }
  elsif ($starttag eq "set")
  {
	  $set = 1;
	  $confragenmax = 0;
	  $setcount++;
  }
  elsif ($starttag eq "frage" && $set == 1)
  {
	  $confragenmax++;
  }
}

  
sub Info_End
{
  my $p=shift;
  my $endtag=shift;

  if ($endtag eq "conjoint")
  {
	  undef $set;
  }

}

sub write_log
{
	my $text = shift;
	my $file = $logpath.$logfile;

	open (LOG,">>$file");
	flock (LOG, LOCK_EX);
	print LOG localtime(time).";IP=$ENV{'REMOTE_ADDR'};AGENT=$ENV{'HTTP_USER_AGENT'};INTERVIEWER=$interviewer;$text\n";
	close LOG;
}

#---------------------------------------------------------------------
# Subs speichern.pl
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# liest das Session-File ein erstellt die Exportdateien
#---------------------------------------------------------------------
sub do_param
{
	my $session;
	my $zaehler = 1;
	my @kat;

	my $testid = $fragebogenid - 1;
	my $csvfile = $sessionfile;
	$csvfile =~ s/\.tmp$/\.csv/;
	$csvfile =~ s/session/daten/;
	$csvfile = $datapath."ID$testid-".$csvfile;

	my $confile = $sessionfile;
	$confile =~ s/\.tmp$/\.csv/;
	$confile =~ s/session/conjoint/;
	$confile = $datapath."ID$testid-".$confile;

	my $responsefile = $sessionfile;
	$responsefile =~ s/\.tmp$/\.csv/;
	$responsefile =~ s/session/response/;
	$responsefile = $datapath."ID$testid-".$responsefile;

	if (-e $csvfile or -e $confile or -e $responsefile)
	{
		return -1;
	}

	undef $csvfile;
	undef $confile;
	undef $responsefile;

	my $unique_extension=&get_uniqueID;
	$fragebogenid = &write_config;
	$fragebogenid .= $unique_extension;
	
	# falls ID mit URL übergeben wurde
	$fragebogenid = $tn if ($tn ne "");

	push (@header,"ID");
	push (@data,$fragebogenid);

	# Position der jeweils letzten Kategorie speichern
	
	open (FILE,"<$tmppath$sessionfile") or &print_err ("$sessionfile - $msg->[102]",'17',1);
	while (!eof(FILE))
	{
		my $session = new CGI(FILE);
		$kat[$session->param('seite')] = $zaehler if (defined $session->param('seite'));
		$zaehler++;
	}
	close FILE or &print_err ("$sessionfile - $msg->[103]",'18',1);

	# Positionen der Reihe nach abarbeiten
	
	foreach (@kat)
	{
		if (defined $_)
		{
			my $pos = $_;
			open (FILE,"<$tmppath$sessionfile") or &print_err ("$sessionfile - $msg->[102]",'19',1);
			while (!eof(FILE))
			{
				my $i=1;
				do
				{
					$session = new CGI(FILE);
					$i++;
				}
				until ($i > $pos);
				&get_sessparam($session);
				&write_csv($session);
				last;
			}
			close FILE or &print_err ("$sessionfile - $msg->[103]",'20',1);
		}
	}

	#mkdir ($datapath.$XMLname) unless (-e -d $datapath.$XMLname);
	
	my $csvfile = $sessionfile;
	$csvfile =~ s/\.tmp$/\.csv/;
	$csvfile =~ s/session/daten/;
	$csvfile = "ID$fragebogenid-".$csvfile;

	my $confile = $sessionfile;
	$confile =~ s/\.tmp$/\.csv/;
	$confile =~ s/session/conjoint/;
	$confile = "ID$fragebogenid-".$confile;

	my $responsefile = $sessionfile;
	$responsefile =~ s/\.tmp$/\.csv/;
	$responsefile =~ s/session/response/;
	$responsefile = "ID$fragebogenid-".$responsefile;

	if (-e $csvfile or -e $confile or -e $responsefile)
	{
		return -1;
	}
	else
	{
		open (CSV,">$datapath$csvfile") or &print_err ("$csvfile - $msg->[102]",'21',1);
		print CSV "$XMLdatei\n";
		foreach (@header)
		{
			print CSV "$_$trz";
		}
		print CSV "\n";
		foreach (@data)
		{
			print CSV "$_$trz";
		}
		print CSV "\n";
		close CSV or &print_err ("$csvfile - $msg->[103]",'22',1);

		open (CON,">$datapath$confile") or &print_err ("$confile - $msg->[102]",'23',1);
		print CON "$XMLdatei\n";
		$conjoint =~ s/;/$trz/g;
		print CON $conjoint;
		close CON or &print_err ("$confile - $msg->[103]",'24',1);

		open (RES,">$datapath$responsefile") or &print_err ("$responsefile - $msg->[102]",'23',1);
		print RES "$XMLdatei\n";
		$response =~ s/;/$trz/g;
		print RES $response;
		close RES or &print_err ("$responsefile - $msg->[103]",'24',1);
	}
	return 0;
}


sub get_sessparam
{
	my $session = shift;
	@felder = $session->param();
}

#---------------------------------------------------------------------
# wertet die Daten des Session-Files entspr. dem Encoding aus
#---------------------------------------------------------------------
sub write_csv
{
	my $session = shift;

	my $feld = join("#",@felder);
	$feld .= "#";
	$feld =~ /encoding_(.+?)#/;
	my $tag = $1;

		if ($session->param('version'))
		{
			push (@header,'version');
			push (@data,$session->param('version'));
			$session->delete('version');
		}
		if ($session->param('interviewer'))
		{
			push (@header,'interviewer');
			push (@data,$session->param('interviewer'));
			$session->delete('interviewer');
		}
		if ($session->param("encoding_$tag") eq "conjoint")
		{
			if ($conkopf == 0)
			{
				my $kopf = $session->param('kopf');
				$conjoint .= "ID".$trz."Task".$trz."Product".$trz.$kopf.$trz."none".$trz."choice\n";
				$conkopf = 1;
				$response .= "ID".$trz."Task".$trz."ResponseTime\n";
			}
			my $max = $session->param('maxvalue_'.$tag);
			my $min = $session->param('minvalue_'.$tag);
			my $value = $session->param($tag);
			my $task = substr($tag,1);
			for (my $i=$min;$i<=$max;$i++)
			{
				if ($i == $value and $i != $max)
				{
					$conjoint .= $fragebogenid.$trz.$task.$trz.$i.$trz.$session->param("$tag\_$i").$trz."0".$trz."1\n";
				}
				elsif ($i == $value and $i == $max)
				{
					$conjoint .= $fragebogenid.$trz.$task.$trz.$i.$trz.$session->param("$tag\_$i").$trz."1".$trz."1\n";
				}
				elsif ($i == $max)
				{
					$conjoint .= $fragebogenid.$trz.$task.$trz.$i.$trz.$session->param("$tag\_$i").$trz."1".$trz."0\n";
				}
				else
				{
					$conjoint .= $fragebogenid.$trz.$task.$trz.$i.$trz.$session->param("$tag\_$i").$trz."0".$trz."0\n";
				}
			}
			$response .= $fragebogenid.$trz.$task.$trz.$session->param("contime")."\n";
		}
		elsif ($session->param("encoding_$tag") eq "auswahlbin")
		{
			my @optionen = split(/:/,$session->param('optionen_'.$tag));
			my $value = $session->param($tag);

			foreach (@optionen)
			{
				push (@header,$_);
				if ($_ eq $value)
				{
					push (@data,"1");
				}
				else
				{
					push (@data,"0");
				}
			}
		}
		elsif ($session->param("encoding_$tag") eq "auswahlxbin")
		{
			my @optionen = split(/:/,$session->param('optionen_'.$tag));

			foreach (@optionen)
			{
				push (@header,$_);
				if (defined $session->param($_))
				{
					push (@data,"1");
				}
				else
				{
					push (@data,"0");
				}
			}
		}
		# Philip Langer (2008-09-25): Null-Option bei numerischen Fragen
		# Da Nulloption-Checkbox als Requestparameter in der Ausgabe nie erwünscht ist und bei Nulloption das Textfeld leer ist (und damit kein Request-Param reinkommt)
		# Muss das hier manuell geregelt werden und nicht generisch wie im else-Zweig
		elsif ($session->param("encoding_$tag") eq "numerisch")
		{
			push (@header,$tag);
			if (defined $session->param($tag))
			{
				push (@data,$session->param($tag));
			}
			else
			{
				push (@data,"");
			}
		}
		# /Philip Langer (2008-09-25): Null-Option bei numerischen Fragen
		else
		{
		   foreach (@felder)
		   {
		    if ($_ ne "seite" && $_ ne "version" && $_ ne "interviewer")
		    {
			 push (@header,$_);

			 if ($session->param($_) eq "§§§" or $session->param($_) eq "Â§Â§Â§")
			 {
				push (@data,"");
			 }
			 elsif ($session->param($_) ne "")
			 {
				my $val = $session->param($_);
				$val =~ s/$trz/:/g;
				$val =~ s/"/'/g;
				if ($val =~ /[\n\r]+/)
				{
					push (@data,"\"$val\"");
				}
				else
				{
					push (@data,$val);
				}
			 }
			 else
			 {
				push (@data,"0");
			 }
		    }
		   }
		}

	undef @felder;
}

#---------------------------------------------------------------------
# schreibt Informationen in die Konfigurationsdatei config.pl
#---------------------------------------------------------------------
sub write_config
{
	my $fid;
	my $infile = "config.pl";
	my $tempfile = "config.".time.".tmp";

	open (OUT, ">$tempfile");
	flock (OUT, LOCK_EX);
	open (IN, "<$infile");
	flock (IN, LOCK_EX);

	while (<IN>)
	{
		if (/^\$fragebogenid = '(\d+)'/)
		{
			$fid = $1;
			print OUT "\$fragebogenid = \'".++$fid."\';\n";
			$fid--;
		}
		else
		{
			print OUT $_;
		}
	}

	close (IN) or &print_err ("$infile - $msg->[103]",'25',1);
	close (OUT) or &print_err ("$tempfile - $msg->[103]",'26',1);
	unlink ($infile) or &print_err ("$infile - $msg->[100]",'27',1);
	rename ($tempfile, $infile) or &print_err ("$tempfile - $msg->[105]",'28',1);		

	return $fid;
}


#---------------------------------------------------------------------
# HTML Code
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Gibt die Kopfzeile für HTML aus
#---------------------------------------------------------------------
sub print_htmlheader
{
  my $title=shift;

  print $cgi->header('text/html');
  print "<html><head><title>$title</title>\n";
  print "<link rel=\"stylesheet\" type=\"text/css\" href=\"$CSSfile\">\n";
  print "</head><body>\n";
}

#---------------------------------------------------------------------
# Gibt die Kopfzeile des Formulars aus
#---------------------------------------------------------------------
sub print_formheader
{
  print "<form action=\"$me\" method=\"post\" onSubmit=\"if (!this.clicked) {return chkInput();} else {return false;}\">\n";
}

#---------------------------------------------------------------------
# Gibt die Fusszeile des Formulars aus
#---------------------------------------------------------------------
sub print_formfooter
{
  print $cgi->br();	
  print $cgi->br();	
  print "<table width=\"100%\"><tr>\n"; 
  print "<td class=\"button\" width=\"20%\"><input type=\"button\" name=\"ResetButton\" value=\"$msg->[5]\" onClick=\"document.forms[0].ResetButton.disabled = true;chkExit();\"></td>\n";

  my $aktanz;
  
  if ($confrageakt)
  {
	$aktanz = $katakt + $confrageakt - 2;
	$confrageakt++ if ($confrageakt < $confragenmax);
	print "<input type=\"hidden\" name=\"confrageakt\" value=\"$confrageakt\">\n";
  }

  print "<td class=\"button\" width=\"60%\">";
  print "$msg->[6] $katakt $msg->[7] $katmax</td>\n" if ($kat_anzeige == 1);
       #AA Fortschrittsbalken
  #seite gibt mir die seitenzahl
  print "<style type=\"text/css\">\n"; 
  print "div.fsb {border:1px solid #eeeeee; background-color:white; width:200px; height:10px; padding:1px;}\n";
  $noq = &number_of_questions($XMLfile);
  $fortschritt = int($seite*100/$noq);
  if ($seite/$noq le 1/3)
  {
	print "div.fortschritt {background-color:#ff6633;height:10px;width:$fortschritt%;}\n";
  } 
  elsif ($seite/$noq gt 1/3 && $seite/$noq le 2/3)
  {
	print "div.fortschritt {background-color:#ffff66;height:10px;width:$fortschritt%;}\n";
  }
  elsif ($seite/$noq gt 2/3)
  {
	print "div.fortschritt {background-color:#99ff99;height:10px;width:$fortschritt%;}\n";
  } 
  print "</style>\n";
  print "<br><b><font color=gray>Fortschritt: $fortschritt%</font></b><br><div class=\"fsb\"><div class=\"fortschritt\"></div></div><br>\n"; 
  print "</td>\n";

  if ($katakt == $katmax && $fragecount <= $frageakt)
  {
  	print "<td class=\"button\" width=\"20%\"><input type=\"submit\" value=\"        $msg->[8]        \" name=\"SubmitButton\" OnClick=\"if (!this.clicked) {return true;} else {return false;}\"></td>\n";
  }
  else
  {
  	print "<td class=\"button\" width=\"20%\"><input type=\"submit\" value=\"$msg->[9]\" name=\"SubmitButton\" OnClick=\"if (!this.clicked) {return true;} else {return false;}\" onkeypress=\"var keyCode = event.which ? event.which : event.keyCode ? event.keyCode : event.charCode;return keyCode != 13;\"></td>\n";
  }
  print "<input type=\"hidden\" name=\"seite\" value=\"".++$seite."\">\n";
  print "</tr></table>\n"; 
  print "</td></tr></table>\n"; 

  print "</form>\n";
}

#---------------------------------------------------------------------
# Gibt die Fusszeile für HTML aus
#---------------------------------------------------------------------
sub print_htmlfooter
{
	print $cgi->end_html();
}

#---------------------------------------------------------------------
# Gibt HTML-Code der letzten Seite aus
#---------------------------------------------------------------------
sub print_html
{
	my $text = shift;
	my $titel = shift;
	my $version = shift;
	my $option = shift;

	unless ($url_redir_opt == 0)
	{
		print "<script type=\"text/javascript\" language=\"JavaScript\">\n";
		print "<!-- Hide script\n";
		print "function check() {\n";
	
		if ($url_redir_opt == 3)
		{
			$md5->add("$fragebogenid","$secret");
			my $md5hex = $md5->hexdigest;
			print "window.location.href=\"$url_redir?tn=$fragebogenid&ck=$md5hex\"\n";
		}
		elsif ($url_redir_opt == 2)
		{
			print "window.location.href=\"$url_redir?js=1&tn=$fragebogenid&ck=\"\n";
		}
		elsif ($url_redir_opt == 1)
		{
			print "window.location.href=\"$url_redir\"\n";
		}
		
		print "}\n";
		print "setTimeout(\"check()\", 10);\n";
		print "</script>";
	}

	print "<table class=\"head\" width=\"100%\"><tr><td>\n";
	print "<div class=\"topheader\">$titel</div>\n";
	#print "<div class=\"topver\">Version: $version</div>\n";
	print "</td></tr></table>\n";
        print "<table class=\"body\" width=\"100%\"><tr><td>\n";
	print "$text";
  	print "<form>\n";
	print "</td></tr></table>\n";
        print "<table class=\"footer\" width=\"100%\"><tr><td class=\"footer\">\n";

	if ($option == 1)
	{
		print "<input type=\"button\" name=\"start\" value=\"".$msg->[10]."\" onclick=\"document.forms[0].start.disabled = true;location.replace(\'".$url."\');\">";
		print "</td><td align=\"center\">\n";
		print $cgi->button('close',"$msg->[11]","window.close()");
	}
	elsif ($option == 2)
	{
		print $cgi->button('close',"$msg->[11]","window.close()");
	}
	print "</td></tr></table>\n";
  	print "</form>\n";

	if ($mailactive == 1)
	{
		print "<a href=\"sendmail.pl?url=$url&thema=$titel\" target=\"_blank\">$msg->[15]</a>";
	}
}

#---------------------------------------------------------------------
# Gibt eine Fehlermeldung in HTML-Code aus
#---------------------------------------------------------------------
sub print_err
{
	my $text = shift;
	my $nr = shift;
	my $option = shift;
	my $errlog = "fragebogen_err.log";

	open (ERRFILE,">>$logpath$errlog");
	flock (ERRFILE, LOCK_EX);
	print ERRFILE localtime(time)." : SESSION=$sessionfile : ID=$fragebogenid : $nr-$text : $!\n";
	close ERRFILE;

        print "<div class=\"linie1\"></div>\n";
	print "<div class=\"fehler\">$msg->[14] $nr</div>\n";
	print "<div class=\"linie1\"></div>\n";
	print "<center>\n";
	print "<div class=\"fehlertext\">$text</div>\n";
  	print "<br>\n";
  	print "<form>\n";
	print "<table width=\"30%\" border=\"0\"><tr><td align=\"center\">\n";
	if ($option == 1)
	{
		print $cgi->button('close',"$msg->[12]","location.reload()");
		print "</td><td align=\"center\">\n";
		print "<input type=\"button\" name=\"start\" value=\"".$msg->[10]."\" onclick=\"document.forms[0].start.disabled = true;location.replace(\'".$url."\');\">";
		print "</td></tr></table>\n";
		print $cgi->h4("Falls dieser Fehler weiterhin auftritt, m&uuml;ssen Sie den Fragebogen ggf. neu starten");
  		print "</form>\n";
	}
	elsif ($option == 2)
	{
		print $cgi->button('close',"$msg->[11]","window.close()");
		print "</td></tr></table>\n";
  		print "</form>\n";
		exit;
	}
}

  

#---------------------------------------------------------------------
# Other Subs
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Wandelt Umlaute in HTML-Form um
#---------------------------------------------------------------------
sub u2a
{
	my $text=shift;
	$text = $converter->convert($text);		#Linux Version
	$text =~ s/([\xC0-\xDF])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
	$text =~ s/ä/&auml;/g;
	$text =~ s/ö/&ouml;/g;
	$text =~ s/ü/&uuml;/g;
	$text =~ s/Ä/&Auml;/g;
	$text =~ s/Ö/&Ouml;/g;
	$text =~ s/Ü/&Uuml;/g;
	$text =~ s/ß/&szlig;/g;
	$text =~ s/á/&aacute;/g;
	$text =~ s/é/&eacute;/g;
	$text =~ s/í/&iacute;/g;
	$text =~ s/ó/&oacute;/g;
	$text =~ s/ú/&uacute;/g;
	return ($text);
}

sub xml2html
{
	my $text=shift;
	$text =~ s/&lt;/</g;
	$text =~ s/&gt;/>/g;
	return ($text);
}

#---------------------------------------------------------------------
# Wandelt Umlaute in JavaScript-Form um
#---------------------------------------------------------------------
sub a2u
{
	my $text=shift;
	$text =~ s/([\xC0-\xDF])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
	$text =~ s/&auml;/ae/g;
	$text =~ s/&ouml;/oe/g;
	$text =~ s/&uuml;/ue/g;
	$text =~ s/&Auml;/Ae/g;
	$text =~ s/&Ouml;/Oe/g;
	$text =~ s/&Uuml;/Ue/g;
	$text =~ s/&szlig;/ss/g;
	$text =~ s/ä/ae/g;
	$text =~ s/ö/oe/g;
	$text =~ s/ü/ue/g;
	$text =~ s/Ä/Ae/g;
	$text =~ s/Ö/Oe/g;
	$text =~ s/Ü/Ue/g;
	$text =~ s/ß/ss/g;
	$text =~ s/<br>/-/g;
	$text =~ s/\W/_/g;
	return ($text);
}

sub u2u
{
	my $text=shift;
	$text =~ s/([\xC0-\xDF])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
	return ($text);
}

#---------------------------------------------------------------------
# Ersetzt Unterstriche durch Leerzeichen
#---------------------------------------------------------------------
sub pp 
{
	my $text=shift;
	$text =~ s/_/ /g;
	return ($text);
}

#---------------------------------------------------------------------
# Loescht temporaere Dateien aus dem Arbeitsverzechnis
#---------------------------------------------------------------------
sub del_tmp
{
	opendir(DIR,$tmppath);
	my @eintraege = readdir(DIR);
	closedir(DIR);
	foreach (@eintraege)
	{
		unless( -d $_ )
		{
			if ( ($_ =~ /.*session.*\.tmp$/ or $_ =~ /.*session.*\.xml$/) && -M $_ > 1)
			{
				unlink($_);
			}
		}
	}
	opendir(DIR,".");
	my @eintraege = readdir(DIR);
	closedir(DIR);
	foreach (@eintraege)
	{
		unless( -d $_ )
		{
			if ( ($_ =~ /.*session.*\.tmp$/ or $_ =~ /.*session.*\.xml$/) && -M $_ > 1)
			{
				unlink($_);
			}
		}
	}
}

#---------------------------------------------------------------------
# sortiert Nummern in aufsteigender Reihenfolge
#---------------------------------------------------------------------
sub NummernSort
{
	if($a < $b)
		{ return -1; }
	elsif($a == $b)
		{ return 0; }
	else
		{ return 1; }
}

#---------------------------------------------------------------------
# gibt gekennzeichnete Felder in eigener Formatierung aus
#---------------------------------------------------------------------
sub attr
{
	my $text = shift;
	my $a = 1;
	
	$text =~ s/\n/<div class=\"attline\"><\/div>/g;

	while ($text =~ /~/)
	{
		if ($a == 1)
		{
			$text =~ s/~/<span class=\"attr\">/;
			$a++;
		}
		else
		{
			$text =~ s/~/<\/span>/;
			$a--;
		}
	}

	$text .= "</span>" if ($a > 1);
	return $text;
}

#---------------------------------------------------------------------
# sortiert ein Array zufaellig
#---------------------------------------------------------------------
sub shuffle 
{
        my $array = shift;
        my $i;
        for ($i = @$array; --$i; ) 
	{
        	my $j = int rand ($i+1);
        	@$array[$i,$j] = @$array[$j,$i];
        }

	return $array;
}

    
#---------------------------------------------------------------------
# liest die Sprachdatei ein
#---------------------------------------------------------------------
sub get_msg 
{
	my $langfile = shift;

	if ($langfile =~ /^language.*\.txt$/)
	{
		open (IN ,"<$langfile") or &print_err ("$langfile - $msg->[102]",'28',1);
		flock (IN, LOCK_EX);
		my @zeilen = <IN>;
		close IN;

		my @msg;
		my $start;
		foreach (@zeilen)
		{
			my @col = split (/=/,$_);
			if ($col[0] eq $me)
			{
				$start = 1;
			}
			elsif ($col[0] eq 'END')
			{
				last if ($start);
			}
			if ($start)
			{

				my $dummy = $col[1];
				chomp $dummy;
				$dummy =~ s/"//g;
				$msg[$col[0]] = $dummy;
			}
		}

		return \@msg;
	}
	else
	{
		&print_err ("$langfile - $msg->[101]",'29',2);
	}
}


#---------------------------------------------------------------------
# JavaScript Subs
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# gibt die Kopfzeile fuer JavaScript aus
#---------------------------------------------------------------------
sub start_js
{
	$js.="<script type=\"text/javascript\" language=\"JavaScript\">\n";
	$js.="<!-- Hide script\n";
	$js.="//<![CDATA[\n";
	$js.="var clickcount = 1;\n";
	$js.="function write_el(eli,max,ele) {\n";
	$js.="  if (eli == \"\"){\n";
	$js.="    document.forms[0].elements[ele].value = clickcount;\n";
	$js.="    if (clickcount < max){\n";
	$js.="      clickcount++;\n";
	$js.="    }\n";
	$js.="  }\n";
	$js.="}\n";

	if ($myxml == 1)
	{
		# Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
		my $tn_param = "";
		$md5->add("$tn","$secret");
		my $md5hex = $md5->hexdigest;
		if (length($tn) > 0) {
			$tn_param = "&tn=$tn&ck=$md5hex";
		}
		# /Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
		$js.="function chkExit() {\n";
		$js.="  var chkex;\n";
		$js.="  chkex = confirm (\"$msg->[200]\");\n";
		$js.="  if (chkex == true) {\n";
		$js.="    location.replace(\'$url?js=1&session=$sessionfile&xml=$XMLfile$tn_param\');\n";
		$js.="  }\n";
		$js.="  else {\n";
		$js.="  document.forms[0].ResetButton.disabled = false;\n";
		$js.="  }\n";
		$js.="}\n";
	}
	else
	{
		# Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
		my $tn_param = "";
		$md5->add("$tn","$secret");
		my $md5hex = $md5->hexdigest;
		if (length($tn) > 0) {
			$tn_param = "&tn=$tn&ck=$md5hex";
		}
		# /Philip Langer (2008-10-09): Ausgabe der Teilnehmernummer
		$js.="function chkExit() {\n";
		$js.="  var chkex;\n";
		$js.="  chkex = confirm (\"$msg->[200]\");\n";
		$js.="  if (chkex == true) {\n";
		$js.="    location.replace(\'$url?js=1&session=$sessionfile$tn_param\');\n";
		$js.="  }\n";
		$js.="  else {\n";
		$js.="  document.forms[0].ResetButton.disabled = false;\n";
		$js.="  }\n";
		$js.="}\n";
	}
	
	$js.="function chkInput() {\n";
	$js.=" this.clicked = true;\n";
	$js.=" document.forms[0].SubmitButton.disabled = true;\n";
}

#---------------------------------------------------------------------
# gibt die Fusszeile fuer JavaScript aus
#---------------------------------------------------------------------
sub end_js
{	
	$js.=" document.forms[0].SubmitButton.title = \"$msg->[201]\";\n";
	$js.=" return true;\n";
	$js.="}\n";
	$js.="//]]> End script hiding -->\n";
	$js.="</script>\n";

}
	
#---------------------------------------------------------------------
# JavaScript-Code fuer Wert mehrfach verwendet
#---------------------------------------------------------------------
sub doppel_js
{
	my $kuerzel = shift;
	my $frage = &a2u(shift);
	$frage =~ s/_+/ /g;
	my $js;
	
	$js.="var chkDup = 1;\n";
	$js.="for(i=0; i<document.forms[0].elements.length; ++i) {\n";
	$js.=" var elityp=\'document.forms[0].elements[i].type\';\n";
	$js.=" if(eval(elityp) == \"text\")  {\n";

	$js.="  var elival=\'document.forms[0].elements[i].value\';\n";
	$js.="  var val = eval(elival);\n";
	$js.="  for(j=0; j<document.forms[0].elements.length; ++j) {\n";
	$js.="   var eljtyp=\'document.forms[0].elements[j].type\';\n";
	$js.="   var eljval=\'document.forms[0].elements[j].value\';\n";
	$js.="   if(eval(eljtyp) == \"text\" && eval(eljval) != \"\")  {\n";
	$js.="    if(i != j)  {\n";	$js.="      var eljval=\'document.forms[0].elements[j].value\';\n";
	$js.="      if(eval(eljval) == val)\n";
	$js.="        chkDup = -1;\n";
	$js.="    }\n";
	$js.="   }\n";
	$js.="  }\n";
	$js.="  if(chkDup == -1) {\n";
	#$js.="    alert(\"$msg->[202]\\n\'$frage\'\\n $msg->[203]\");\n";
	$js.="    alert(\"$msg->[203]\");\n";
	$js.="    var box=\'document.forms[0].elements[\"$kuerzel\"]\';\n";
	$js.="    eval(box).focus();\n";
	$js.="    this.clicked = false;\n";
	$js.="    document.forms[0].SubmitButton.disabled = false;\n";
	$js.="    return false;\n";
	$js.="  }\n";

	$js.=" }\n";
	$js.="}\n";

	return $js;
}

#---------------------------------------------------------------------
# JavaScript-Code fuer Alle Felder ausgefuellt
#---------------------------------------------------------------------
sub leer_js
{
	my $js;

	$js.="if(!eval(document.forms[0].elements[\"$qid\_nulloption\"]) || document.forms[0].elements[\"$qid\_nulloption\"].checked != true)  {\n";
	
	$js.="for(i=0; i<document.forms[0].elements.length; ++i) {\n";
	$js.=" if(document.forms[0].elements[i].type == \"text\")  {\n";

	$js.="  if(document.forms[0].elements[i].value == \"\")  {\n";
	$js.="   alert(\"$msg->[204]\");\n";
	$js.="       document.forms[0].elements[i].focus();\n";
	$js.="       this.clicked = false;\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="  }\n";
	$js.=" }\n";
	$js.="}\n";
	
	$js.="}\n";

	$leer=1;
	return $js;
}

sub fill_min_js
{
	my $min = shift;
	my $js;
	
	$js.="if(!eval(document.forms[0].elements[\"$qid\_nulloption\"]) || document.forms[0].elements[\"$qid\_nulloption\"].checked != true)  {\n";
	
	$js.="var count = 0;\n";
	$js.="for(i=0; i<document.forms[0].elements.length; ++i) {\n";
	$js.=" if(document.forms[0].elements[i].type == \"text\")  {\n";

	$js.="  if(document.forms[0].elements[i].value != \"\")  {\n";
	$js.="       count++;\n";
	$js.="  }\n";
	$js.=" }\n";
	$js.="}\n";
	$js.="if(count < ".$min.")  {\n";
	$js.="   alert(\"$msg->[205] ".$min." $msg->[206]\");\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="}\n";
	
	$js.="}\n";

	return $js;
}

#---------------------------------------------------------------------
# JavaScript-Code fuer Wert innerhalb des gueltigen Bereichs
#---------------------------------------------------------------------
sub minmax_js
{
	my $minjs = shift;
	my $maxjs = shift;
	my $kuerzel = shift;
	my $js;

	$minjs=0 unless (defined $minjs);
	$maxjs=999999 unless (defined $maxjs);
	
	$js.="if(!eval(document.forms[0].elements[\"$qid\_nulloption\"]) || document.forms[0].elements[\"$kuerzel\_nulloption\"].checked != true)  {\n";
	
	$js.="  if(document.forms[0].elements[\"$kuerzel\"].value != \"\") {\n";

	$js.="  var chkZ=1;\n";
	$js.="  var chkkom=0;\n";
	$js.="  var leng=document.forms[0].elements[\"$kuerzel\"].value.length;\n";
	$js.="  for(j=0;j<leng;++j) {\n";
	$js.="  if(document.forms[0].elements[\"$kuerzel\"].value.charAt(j) < \"0\" || document.forms[0].elements[\"$kuerzel\"].value.charAt(j) > \"9\")\n";
	$js.="   chkZ = -1;\n";
	$js.="  if(j == 0 && document.forms[0].elements[\"$kuerzel\"].value.charAt(j) == \".\")\n";
	$js.="   chkZ = -1;\n";
	$js.="  if(j != 0 && document.forms[0].elements[\"$kuerzel\"].value.charAt(j) == \".\") {\n";
	$js.="   chkkom++;\n";
	$js.="   chkZ = 1;\n";
	$js.="  }\n";
	$js.="  if(j == (leng-1) && document.forms[0].elements[\"$kuerzel\"].value.charAt(j) == \".\")\n";
	$js.="   chkZ = -1;\n";
	$js.="  if(j == 0 && document.forms[0].elements[\"$kuerzel\"].value.charAt(j) == \"-\")\n";
	$js.="   chkZ = 1;\n";
	$js.="  if(j == (leng-1) && document.forms[0].elements[\"$kuerzel\"].value.charAt(j) == \"-\")\n";
	$js.="   chkZ = -1;\n";
	$js.="  }\n";
	$js.="  if(chkZ == -1 || chkkom > 1) {\n";
	$js.="   alert(\"$msg->[207]\");\n";
	$js.="       document.forms[0].elements[\"$kuerzel\"].focus();\n";
	$js.="       this.clicked = false;\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="  }\n";

	$js.="  if(document.forms[0].elements[\"$kuerzel\"].value < $minjs || document.forms[0].elements[\"$kuerzel\"].value > $maxjs)  {\n";
	$js.="   alert(\"$msg->[208]\");\n";
	$js.="       document.forms[0].elements[\"$kuerzel\"].focus();\n";
	$js.="       this.clicked = false;\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="  }\n";
	$js.="  }\n";

	$js.="  }\n";

	return $js;
}

#---------------------------------------------------------------------
# JavaScript-Code fuer richtige Anzahl an Checkboxen
#---------------------------------------------------------------------
sub checkbox_js
{
	my $js;
	my $optref = shift;
	my @optid = @{$optref};
	my $first = @optid[0];
	my $minjs = shift;
	my $maxjs = shift;

	$js.="var x;\n";
	$js.="var check=0;\n";

	foreach (@optid)
	{
		$js.="  var box=\'document.forms[0].elements[\"$_\"].checked\';\n";
		$js.="  if(eval(box) == true)\n";
		$js.="   check++;\n";
	}

	$js.="  if(check > $maxjs) {\n";
	$js.="   alert(\'$msg->[209] $maxjs $msg->[210]\');\n";
	$js.="       box=\'document.forms[0].elements[\"$first\"]\';\n";
	$js.="       eval(box).focus();\n";
	$js.="       this.clicked = false;\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="  }\n";
	$js.="  if(check < $minjs) {\n";
	$js.="   alert(\'$msg->[205] $minjs $msg->[210]\');\n";
	$js.="       box=\'document.forms[0].elements[\"$first\"]\';\n";
	$js.="       eval(box).focus();\n";
	$js.="       this.clicked = false;\n";
	$js.="       document.forms[0].SubmitButton.disabled = false;\n";
	$js.="       return false;\n";
	$js.="  }\n";

	return $js;
}

#---------------------------------------------------------------------
# JavaScript-Code fuer Conjoint-Fragen
#---------------------------------------------------------------------
sub con_js
{
	my $maxjs = shift;
	$maxjs--;
	my $kuerzel = shift;
	my $js;
	
	$js.="var chkradio=0;\n";
	$js.="for(i=0; i<$maxjs; i++) {\n";

	$js.="  var elval=\'document.forms[0].$kuerzel\[\'+i+\'].checked\';\n";
	$js.="  if(eval(elval))\n";
	$js.="    chkradio=1;\n";
	$js.="}\n";

	$js.="if(chkradio == 0)  {\n";
	$js.="   alert(\"$msg->[211]\");\n";
	$js.="   this.clicked = false;\n";
	$js.="   document.forms[0].SubmitButton.disabled = false;\n";
	$js.="   return false;\n";
	$js.="}\n";

	return $js;
}

#---------------------------------------------------------------------
# JavaScript-Code fuer Bewertungs-Fragen
#---------------------------------------------------------------------
sub bew_js
{
	my $maxjs = shift;
	my $opt = shift;
	my $js;
	
	$js.="var chkradio=0;\n";
	$js.="for(i=0; i<$maxjs; i++) {\n";

	$js.="  var elval=\'document.forms[0].$opt\[\'+i+\'].checked\';\n";
	$js.="  if(eval(elval))\n";
	$js.="    chkradio=1;\n";
	$js.="}\n";

	$js.="if(chkradio == 0)  {\n";
	$js.="   alert(\"$msg->[211]\");\n";
	$js.="   var box=\'document.forms[0].$opt\[0]\';\n";
	$js.="   eval(box).focus();\n";
	$js.="   this.clicked = false;\n";
	$js.="   document.forms[0].SubmitButton.disabled = false;\n";
	$js.="   return false;\n";
	$js.="}\n";

	return $js;
}

sub get_uniqueID
{
	my $zahl1=time; #Sekunden seit 1.1.1970
	my $uniqueID;
	my $tmp;

	#     ---Zufallszahl zwischen 0 und 99---
	my $zufallszahl=int(rand(99) + 1); 
	my $laenge_zufallszahl=length($zufallszahl);

	# erzeuge auf jeden Fall einen 2 stelligen String.
	if ($laenge_zufallszahl==1)
	{
		$zufallszahl="0".$zufallszahl;
	}
	# der untere Fall  sollte eigentlich nie auftreten
	if (($laenge_zufallszahl==0)or($laenge_zufallszahl>2))
	{
		$zufallszahl="00";
	}
	
	$tmp=reverse(substr(reverse($zahl1),0,5)); # die letzen 5 Ziffern der Sekunden seit 1.1.1970
	$uniqueID=$tmp.$zufallszahl;
	
	return  $uniqueID;

}
