Modul:Vorlage:Curlingspiel

aus Wikipedia, der freien Enzyklopädie
local function trim(text)
	while mw.ustring.sub(text,1,1) == " " do
		text=  mw.ustring.sub(text,2,-1);
	end
	while mw.ustring.sub(text,-1,-1) == " " do
		text=  mw.ustring.sub(text,1,-2);
	end
	return text;
end

local function CreateErrorText(code,info)
	-- 1 = Fehler bei "ends"; 2 = Fehler bei "points1" ; 3 = Fehler bei "points2" ; 4 = Wartungslink alte Angaben
	local text = ''
	if code == 1 then
		text = '<strong class="Error">Fehler! Unzulässige Angabe für Parameter "Ends"! ("'.. info .. '")</strong>'
		text = text .. '<span style="display:none;">[[Vorlage:Curlingspiel/Wartung/Ends]]</span>';
	elseif code == 2 then
		text = '<strong class="Error">Fehler! Unzulässige Angabe für Parameter "Points1"! ("'.. info .. '")</strong>'
		text = text .. '<span style="display:none;">[[Vorlage:Curlingspiel/Wartung/Points]]</span>';
	elseif code == 3 then
		text = '<strong class="Error">Fehler! Unzulässige Angabe für Parameter "Points2"! ("'.. info .. '")</strong>'
		text = text .. '<span style="display:none;">[[Vorlage:Curlingspiel/Wartung/Points]]</span>';
	elseif  code == 4 then
		text = '<strong class="Error">Fehler! Die Parameter "Points1" und "Points2" dürfen keine Schrägstriche mehr enthalten!</strong>'; 
		text = text .. '<span style="display:none;">[[Vorlage:Curlingspiel/Wartung/Slash]]</span>';
	elseif  code == 11 then
		text = '<strong class="Error">Fehler! Vorlage Curlingresult: Ungültiges Curlingergebnis angegeben. "Points1" und "Points2" dürfen jeweils nur eine Zahl >= 0 enthalten!</strong>'; 
		text = text .. '<span style="display:none;">[[Vorlage:Curlingspiel/Wartung/Result]]</span>';
	end
	return text;
end

local p = {}
	function p.Execute(frame)
		local Text     = "";
		local temptext = "";
		local Ends     = tonumber(trim(frame.args['Ends'] or '10'));
		local Hammer   = tonumber(trim(frame.args['LS'] or '3'));
		local Team1    = frame.args['Team1'] or 'Team1';
		local Team2    = frame.args['Team2'] or 'Team2';
		local Points1  = frame.args['Points1'] or '0000000000';
		local Points2  = frame.args['Points2'] or '0000000000';
		local Gewinner = 0;
		local Summe1   = 0;
		local Summe2   = 0;
		local Wert1    = 0;
		local Wert2    = 0;
		local Zeichen  = "";
		local HasSlash = false; -- Wartung: Slashs ist alter Stil
		local Lossbytime = 0; -- bei Zeitueberschreitung 1 oder 2
		if Ends < 4 or Ends > 20 then
			Text = CreateErrorText(1, tostring(Ends));
			return Text;
		end
		-- Points 1 und Points2 duerfen nur ASCII-Zeichen enthalten. Es reichen also die normalen Stringfunktionen
		Points1 = string.upper(Points1);
		Points2 = string.upper(Points2);
		--[=[
		Test auf Gueltigkeit von Points1 und Points2: 
		Bei der Kopie des Strings (temptext) werden alle erlaubten Zeichen entfernt.
		Ist der String danach leer, dann ist der urspruengliche String ok. gleichzeitug wird 
		ueberprueft, ob Schraegstriche enthalten sind.
		]=]
		-- tbl enthaelt die erlaubten Zeichen und das Slash fuer die spezielle Fehlermeldung
		local tbl = {'0','1','2','3','4','5','6','7','8','X','T','/'}; 
		temptext = Points1;
		for idx = 1, #Points1 do
			Zeichen= mw.ustring.sub(Points1,idx,idx) or '?';
			for i, z in ipairs(tbl) do
				if Zeichen == z then
					temptext = mw.ustring.gsub( temptext, z,'');
				end
			end
			if Zeichen == '/' then
				HasSlash = true;
			end
		end
		if temptext ~='' then
			Text = CreateErrorText(2,temptext);
			return Text;
		end
		temptext = Points2;
		for idx = 1, #Points2 do
			Zeichen= mw.ustring.sub(Points2,idx,idx) or '?';
			for i,c in ipairs(tbl) do
				if Zeichen == c then
					temptext = mw.ustring.gsub( temptext, c,'');
				end
			end
			if Zeichen == '/' then
				HasSlash = true;
			end
		end
		if temptext ~='' then
			Text = CreateErrorText(3,temptext);
			return Text;
		end
		-- Slash nicht mehr erlaubt, ergo ein besonderer Fehlerhinweis:
		if HasSlash then
			Text = CreateErrorText(4);
			return Text;
		end
		-- Anfuegen von 'X', damit bei zuwenig Werten aufgefuellt wird
		Points1 = Points1 .. 'XXXXXXXXXX';
		Points2 = Points2 .. 'XXXXXXXXXX';
		--[=[ Aufbau des Ausgabetextes, einer dreizeiligen HTML-Tabelle. 
		Weil erst nach dem Auswerten von Points1 und Points2 der Gewinner ermittelt ist
		und damit erst dann feststeht, welche Zelle fett dargestellt wird, kommt der
		Zeilenanfang am Schluss an den anfang des Strings
		]=]
		
		-- Die Zeilen werden spaltenweise zusammengesetzt
		local Kopf   = '<table class="wikitable" style="text-align: center;">';
		local Zeile0 = '<tr><th style="background:#ffffcc; width:16em;">Team</th>';
		local Zeile1 = '';
		local Zeile2 = '';
		if Hammer == 1 then
			Zeile0 = Zeile0 .. '<th style="background:#ffffcc; width:25px;"><br /></th>';
			Zeile1 = Zeile1 .. '<td>[[Datei:Hammer icon.svg|20x20px|Recht des letzten Steins|link=Curling#Recht des letzten Steins]]</td>';
			Zeile2 = Zeile2 .. '<td><br /></td>';
		elseif Hammer == 2 then
			Zeile0 = Zeile0 .. '<th style="background:#ffffcc; width:25px;"><br /></th>';
			Zeile1 = Zeile1 .. '<td><br /></td>';
			Zeile2 = Zeile2 .. '<td>[[Datei:Hammer icon.svg|20x20px|Recht des letzten Steins|link=Curling#Recht des letzten Steins]]</td>';
		else
			Zeile0 = Zeile0 .. '<th style="background:#ffffcc; width:25px;"><br /></th>';
			Zeile1 = Zeile1 .. '<td><br /></td>';
			Zeile2 = Zeile2 .. '<td><br /></td>';
		end
		for idx= 1 , Ends do
			if idx < 10 then 
				Zeile0 = Zeile0 .. '<th style="background:#ffffcc;width:0.3em;">' .. tostring(idx) .. '</th>';
			else
				Zeile0 = Zeile0 .. '<th style="background:#ffffcc;width:0.6em;">' .. tostring(idx) .. '</th>';
			end
			Zeichen= string.sub(Points1,idx,idx) or '?';
			if Gewinner == 0 and Zeichen == 'T' then 
				-- Zeitueberschreitung Team 1
				Gewinner = 2;
				Lossbytime = 1;
			end
			Zeile1 = Zeile1 .. '<td>' .. Zeichen .. '</td>';
			Wert = tonumber(Zeichen) or 0;   -- Ein 'X' oder 'T' wird Null gezaehlt.
			Summe1 = Summe1 + Wert;
			Zeichen= string.sub(Points2,idx,idx) or '?';
			if Gewinner == 0 and Zeichen == 'T' then
				-- Zeitueberschreitung Team 2
				Gewinner = 1;
				Lossbytime = 2;
			end
			Zeile2 = Zeile2 .. '<td>' .. Zeichen .. '</td>';
			Wert = tonumber(Zeichen) or 0;   -- Ein 'X' oder 'T' wird Null gezaehlt.
			Summe2 = Summe2 + Wert;
		end
		if Lossbytime == 0 and  Summe1 > Summe2 then
			Gewinner = 1;
		elseif Lossbytime == 0 and  Summe1 < Summe2 then
			Gewinner = 2;
		end
		if Lossbytime == 1 then
			Summe1 = '<span style="color:#FF0000;">T</span>';
			Summe2 = '-';
		elseif Lossbytime == 2 then
			Summe1 = '-';
			Summe2 = '<span style="color:#FF0000;">T</span>';
		end
		Zeile0 = Zeile0 .. '<th style="white-space:nowrap;background:#ffffcc;width:3em;">Gesamt</th></tr>'; 
		Zeile1 = Zeile1 .. '<td>' .. tostring(Summe1) .. '</td></tr>';
		Zeile2 = Zeile2 .. '<td>' .. tostring(Summe2) .. '</td></tr>';
		if Gewinner == 1 then
			Zeile1 = '<tr><td style="text-align:left; white-space:nowrap;"><b>' .. Team1 .. '</b></td>' .. Zeile1;
		else
			Zeile1 = '<tr><td style="text-align:left; white-space:nowrap;">'    .. Team1 ..     '</td>' .. Zeile1;
		end
		if Gewinner == 2 then
			Zeile2 = '<tr><td style="text-align:left; white-space:nowrap;"><b>' .. Team2 .. '</b></td>' .. Zeile2;
		else
			Zeile2 = '<tr><td style="text-align:left; white-space:nowrap;">'    .. Team2 ..     '</td>' .. Zeile2;
		end
		--Zusammensetzen
		Text = Kopf .. Zeile0 .. Zeile1 .. Zeile2 .. '</table>';
		return Text;
	end

	-- Funktion Result fuer den Fall, dass nur das Ergebnis bekannt ist.
	-- Aufruf mit "Vorlage:Curlingspiel/Result"
	function p.Result(frame)
		local Text    = "";
		local Team1   = frame.args['Team1'] or 'Team1';
		local IsLine  = frame.args['IsLine'] or '';
		local Team2   = frame.args['Team2'] or 'Team2';
		local Points1 = frame.args['Points1'] or ''; -- neuer Parameter
		local Points2 = frame.args['Points2'] or ''; -- neuer Parameter
		local Breite  = frame.args['Breite'] or '';
		local Gewinner = 0;
		local Lossbytime = 0;
		local Wert1 = '';
		local Wert2 = '';
		-- Points1 und Points2 duerfen nur ASCII-Zeichen enthalten. Es reichen also die normalen Stringfunktionen
		Points1 = string.upper(Points1);
		Points2 = string.upper(Points2);
		if Breite == '' then Breite = '40em'; end
		-- Sonderfall Zeitueberschreitung
		if string.sub(Points1,1,1) == 'T' then
			Wert1 = '<span style="color:#FF0000;">T</span>';
			Wert2 = '-';
			Gewinner = 2;
			Lossbytime = 1;
		elseif string.sub(Points2,1,1) == 'T' then
			Wert1 = '-';
			Wert2 = '<span style="color:#FF0000;">T</span>';
			Gewinner = 1;
			Lossbytime = 2;
		end
		if Lossbytime == 0 then
			-- Die Gueltigkeit wird durch numerische Auswertung getestet. Im Fehlerfall -1
			Wert1 = tonumber(Points1) or -1;
			Wert2 = tonumber(Points2) or -1;
			if Wert1 < 0 or Wert2 < 0 then
				Text = CreateErrorText(11);
				return Text;
			end;
			if Wert1 < Wert2 then
				Wert1 =  tostring(Wert1)
				Wert2 = '<b>'.. tostring(Wert2) .. '</b>'
				Gewinner = 2;
			elseif  Wert1 > Wert2 then
				Wert1 = '<b>'.. tostring(Wert1) .. '</b>'
				Wert2 = tostring(Wert2);
				Gewinner = 1;
			else
				Wert1 = tostring(Wert1);
				Wert2 = tostring(Wert2);
			end
		end
		if IsLine == '' then
			-- Aufbau des Ausgabetextes, einer zweizeiligen HTML-Tabelle
			local Kopf   = '<table class="wikitable" style="text-align: center; width:' .. Breite .. ';">';
			local Zeile0 = '';
			local Zeile1 = '<tr><td>' .. Wert1 .. '</td><td>' ..Wert2 .. '</td></tr>';
			if Gewinner==1 then
				Zeile0 = '<tr><td style="background:#ffffcc; width:50%;"><b>' .. Team1 .. '</b></td><td style="background:#ffffcc; width:50%;">' .. Team2 .. '</td></tr>';
			elseif  Gewinner==2 then
				Zeile0 = '<tr><td style="background:#ffffcc; width:50%;">' .. Team1 .. '</td><td style="background:#ffffcc; width:50%;"><b>' .. Team2 .. '</b></td></tr>';
			else
				Zeile0 = '<tr><td style="background:#ffffcc; width:50%;">' .. Team1 .. '</td><td style="background:#ffffcc; width:50%;">' .. Team2 .. '</td></tr>';
			end
			Text = Kopf .. Zeile0 .. Zeile1 ..'</table>';
		else -- Es wird nur eine Tabellenzeile erzeugt
			if Gewinner==1 then
				Text = '<tr><td><b>' .. Team1 .. '</b></td><td>' .. Team2 .. '</td>';
			elseif  Gewinner==2 then
				Text = '<tr><td>' .. Team1 .. '</td><td><b>' .. Team2 .. '</b></td>';
			else
				Text = '<tr><td>' .. Team1 .. '</td><td>' .. Team2 .. '</td>';
			end
			Text = Text .. '<td style="text-align:center;">' .. Wert1 .. ':' .. Wert2 .. '</td></tr>'
		end
		return Text;
	end;

	function p.Tableheader(frame)
		local Styles =  frame.args['Styles'] or '';
		Text = '<table class="wikitable" style="' .. Styles .. '"><tr><th>1. Team</th><th>2. Team</th><th>Ergebnis</th></tr>'
		return Text;
	end;

	function p.Tablefooter(frame)
		local Info =  frame.args['Info'] or '';
		Text = '</table>\n' .. Info;
		return Text;
	end;


return p;