#include <Date.au3>
#include <Array.au3>

Global Const $S_SPEICHERORT = @ScriptDir ;ohne letztes Backslash!!
Global $bZusammenfassen

Switch MsgBox(64 + 3, "Dateiumwandler", "Hier trägst du deine Nachricht ein." & @CRLF & _
										@CRLF & _
										"Wenn du mehrere Dateien einzeln umwandeln möchtest, klick auf Ja." & @CRLF & _
										"Wenn du mehrere Vorgänge zusammenfassen möchtest, klick auf Nein." & @CRLF & _
										"Um keine Datei zu konvertieren klick auf Abbrechen.")
	Case 6 ; Einzelne Dateien umwandeln (nicht zusammenfassen)
		$bZusammenfassen = False

	Case 7 ; Mehrere Dateien mit dem selben Vorgang zusammenfassen
		$bZusammenfassen = True

	Case 2 ;Es wurde auf Abbrechen gedrückt
		Exit 0
EndSwitch

$sFileName = FileOpenDialog("Bitte wählen sie die Datei aus.", @DesktopDir & "\", "Alle Dateien (*.txt)", $FD_FILEMUSTEXIST + $FD_PATHMUSTEXIST + $FD_MULTISELECT)
If $sFileName = "" Then
	MsgBox(16, "Fehler", "Es wurde keine Datei ausgewählt!")
	Exit 0
EndIf

$aSplitFileNames = StringSplit($sFileName, "|", 3)
If UBound($aSplitFileNames) = 1 Then Local $aSplitFileNames[2] = [StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1), StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1))]

Local $aFileName[UBound($aSplitFileNames) - 1]
Local $aZusammenfassenVorgaenge[UBound($aFileName)][3]

For $iFile = 0 To UBound($aFileName) - 1
	$aFileName[$iFile] = $aSplitFileNames[0] & "\" & $aSplitFileNames[$iFile + 1]
	$sFile = FileRead($aFileName[$iFile])

	; --- Header ---
	$sEndFile = "BEGINN_MESSUNG" & @CRLF

	$aArtikel = StringRegExp($sFile, "Prüfplan\s+(\d+\.\d+)", 3)
	If Not UBound($aArtikel) Then _Error("Artikel")
	$sEndFile &= "ARTIKEL=" & $aArtikel[0] & @CRLF

	$aAuftrag = StringRegExp($sFile, "Auftrag\s+(\d+/\d+)", 3)
	If Not UBound($aAuftrag) Then _Error("Auftrag")
	$sEndFile &= "AUFTRAG=" & $aAuftrag[0] & @CRLF

	$aME_Nummer = StringRegExp($sFile, "ME-Nummer\s+(\d+)", 3)
	If Not UBound($aME_Nummer) Then _Error("ME-Nummer")
	$sEndFile &= "ME-NUMMER=" & $aME_Nummer[0] & @CRLF

	$aPruefer = StringRegExp($sFile, "Prüfernummer\s+(\d+)", 3)
	If Not UBound($aPruefer) Then _Error("Prüfernummer")
	$sEndFile &= "PRUEFER=" & $aPruefer[0] & @CRLF

	$aMaschine = StringRegExp($sFile, "Maschinennummer\s+(\d+-\d+)", 3)
	If Not UBound($aMaschine) Then _Error("Maschinennummer")
	$sEndFile &= "MASCHINE=" & $aMaschine[0] & @CRLF

	$aBemerkung = StringRegExp($sFile, "Bemerkungen\s+(.+?)\s+\R", 3)
	If Not UBound($aBemerkung) Then _Error("Bemerkungen")
	$sEndFile &= "BEMERKUNG=" & $aBemerkung[0] & @CRLF

	$aDatum = StringRegExp($sFile, "Datum\s+(\d+\.\s(?:Januar|Februar|März|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember)\s\d+)", 3)
	$aUhrzeit = StringRegExp($sFile, "Uhrzeit\s(\d+:\d+:\d+)", 3)
	If Not UBound($aDatum) Then _Error("Datum")
	If Not UBound($aUhrzeit) Then _Error("Uhrzeit")
	;Datum wird weiter unten gesetzt
	; --- Header ---

	; --- Vorgänge ---
	$sFile = StringRegExpReplace($sFile, "Schleife beendet \d+/\d+", "") ;Bisschen säubern damit das Pattern unten greift.
	$aVorgaenge = StringRegExp($sFile, "(\d+)\s+(.+?)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(\d+\.\d+)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(.+?)\R", 3)
	Local $aNeueVorgaenge[0][2] ;[n][0] = Name, [n][1] = Wert1, [n+1][0] = Name2

	For $i = 0 To UBound($aVorgaenge) - 8 Step 8 ;Es gibt 8 Einträge pro Zeile, Größe -9 ist also der letzte Index des 1. Eintrages
		$bVorgangExistiertBereits = False

		For $j = 0 To UBound($aNeueVorgaenge) - 1
			If $aNeueVorgaenge[$j][0] = $aVorgaenge[$i] Then
				Local $bErweitereArray = True

				;Prüfen ob das Array überhaupt erweitert werden muss
				For $k = 0 To UBound($aNeueVorgaenge, 2) - 1
					If $aNeueVorgaenge[$j][$k] = "" Then
						$bErweitereArray = False
						ExitLoop
					EndIf
				Next

				If $bErweitereArray Then
					ReDim $aNeueVorgaenge[UBound($aNeueVorgaenge)][UBound($aNeueVorgaenge, 2) + 1]
					$aNeueVorgaenge[$j][UBound($aNeueVorgaenge, 2) - 1] = $aVorgaenge[$i + 2]
				Else
					;Schleifenindex k zeigt auf einen Index der frei ist
					$aNeueVorgaenge[$j][$k] = $aVorgaenge[$i + 2]
				EndIf

				$bVorgangExistiertBereits = True
				ExitLoop
			EndIf
		Next

		If Not $bVorgangExistiertBereits Then
			ReDim $aNeueVorgaenge[UBound($aNeueVorgaenge) + 1][UBound($aNeueVorgaenge, 2)]
			$aNeueVorgaenge[UBound($aNeueVorgaenge) - 1][0] = $aVorgaenge[$i]
			$aNeueVorgaenge[UBound($aNeueVorgaenge) - 1][1] = $aVorgaenge[$i + 2]
		EndIf
	Next

	If Not $bZusammenfassen Then
		$sEndFile &= "ZEIT=" & _DatumFormatieren($aDatum[0]) & "/" & _NullenHinzufuegen($aUhrzeit[0]) & @CRLF

		For $i = 0 To UBound($aNeueVorgaenge) - 1
			$sEndFile &= "VORGANG=" & @CRLF
			$sEndFile &= "PRÜFPUNKT=" & @CRLF
			$sEndFile &= "MERKMAL=" & $aNeueVorgaenge[$i][0] & @CRLF
			$sEndFile &= "UMFANG=" & _ZaehleVorgang($aNeueVorgaenge, $i) & @CRLF
			$sEndFile &= "BEGINN_WERTE" & @CRLF

			For $j = 1 To UBound($aNeueVorgaenge, 2) - 1
				If $aNeueVorgaenge[$i][$j] = "" Then ExitLoop

				$sEndFile &= $aNeueVorgaenge[$i][$j] & @CRLF
			Next

			$sEndFile &= "ENDE_WERTE" & @CRLF & @CRLF
		Next

		; --- Vorgänge ---

		$sEndFile &= "ENDE_MESSUNG" & @CRLF

		;Dateinamen extrahieren
		$sDateiname = StringTrimLeft($aFileName[$iFile], StringInStr($aFileName[$iFile], "\", 0, -1) - 1)
		$sDateiname = StringTrimRight($sDateiname, 4) & ".dfq" ;Endung abschneiden und .dfq dranhängen

		;Wenn die Datei existiert soll sie vorher gelöscht werden
		FileDelete($S_SPEICHERORT & "\" & $sDateiname)
		FileWrite($S_SPEICHERORT & "\" & $sDateiname, $sEndFile)

		;Alte Datei löschen
		FileDelete($aFileName[$iFile])
	Else ;$bZusammenfassen
		$aZusammenfassenVorgaenge[$iFile][0] = $sFile
		$aZusammenfassenVorgaenge[$iFile][1] = _DatumFormatieren($aDatum[0])
		$aZusammenfassenVorgaenge[$iFile][2] = _NullenHinzufuegen($aUhrzeit[0])

		If $iFile = UBound($aFileName) - 1 Then
			;Zusammengefasste Vorgänge erstmal nach Datum sortieren, älteste zuerst
			$aZusammenfassenVorgaenge = _SortiereVorgaengeNachDatum($aZusammenfassenVorgaenge)
			$sEndFile &= "ZEIT=" & $aZusammenfassenVorgaenge[UBound($aZusammenfassenVorgaenge) - 1][1] & "/" & $aZusammenfassenVorgaenge[UBound($aZusammenfassenVorgaenge) - 1][2] & @CRLF

			$sZusammgefassteDatei = ""
			For $i = 0 To UBound($aZusammenfassenVorgaenge) - 1
				$sZusammgefassteDatei &= $aZusammenfassenVorgaenge[$i][0] & @CRLF
			Next

			$aVorgaenge = StringRegExp($sZusammgefassteDatei, "(\d+)\s+(.+?)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(\d+\.\d+)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(.+?)\R", 3)
			Local $aNeueVorgaenge[0][2] ;[n][0] = Name, [n][1] = Wert1, [n+1][0] = Name2

			For $i = 0 To UBound($aVorgaenge) - 8 Step 8 ;Es gibt 8 Einträge pro Zeile, Größe -9 ist also der letzte Index des 1. Eintrages
				$bVorgangExistiertBereits = False

				For $j = 0 To UBound($aNeueVorgaenge) - 1
					If $aNeueVorgaenge[$j][0] = $aVorgaenge[$i] Then
						Local $bErweitereArray = True

						;Prüfen ob das Array überhaupt erweitert werden muss
						For $k = 0 To UBound($aNeueVorgaenge, 2) - 1
							If $aNeueVorgaenge[$j][$k] = "" Then
								$bErweitereArray = False
								ExitLoop
							EndIf
						Next

						If $bErweitereArray Then
							ReDim $aNeueVorgaenge[UBound($aNeueVorgaenge)][UBound($aNeueVorgaenge, 2) + 1]
							$aNeueVorgaenge[$j][UBound($aNeueVorgaenge, 2) - 1] = $aVorgaenge[$i + 2]
						Else
							;Schleifenindex k zeigt auf einen Index der frei ist
							$aNeueVorgaenge[$j][$k] = $aVorgaenge[$i + 2]
						EndIf

						$bVorgangExistiertBereits = True
						ExitLoop
					EndIf
				Next

				If Not $bVorgangExistiertBereits Then
					ReDim $aNeueVorgaenge[UBound($aNeueVorgaenge) + 1][UBound($aNeueVorgaenge, 2)]
					$aNeueVorgaenge[UBound($aNeueVorgaenge) - 1][0] = $aVorgaenge[$i]
					$aNeueVorgaenge[UBound($aNeueVorgaenge) - 1][1] = $aVorgaenge[$i + 2]
				EndIf
			Next

			For $i = 0 To UBound($aNeueVorgaenge) - 1
				$sEndFile &= "VORGANG=" & @CRLF
				$sEndFile &= "PRÜFPUNKT=" & @CRLF
				$sEndFile &= "MERKMAL=" & $aNeueVorgaenge[$i][0] & @CRLF
				$sEndFile &= "UMFANG=" & _ZaehleVorgang($aNeueVorgaenge, $i) & @CRLF
				$sEndFile &= "BEGINN_WERTE" & @CRLF

				For $j = 1 To UBound($aNeueVorgaenge, 2) - 1
					If $aNeueVorgaenge[$i][$j] = "" Then ExitLoop

					$sEndFile &= $aNeueVorgaenge[$i][$j] & @CRLF
				Next

				$sEndFile &= "ENDE_WERTE" & @CRLF & @CRLF
			Next

			;Dateinamen extrahieren
			$sDateiname = StringTrimLeft($aFileName[$iFile], StringInStr($aFileName[$iFile], "\", 0, -1) - 1)
			$sDateiname = StringTrimRight($sDateiname, 4) & "_zusammenfassung.dfq" ;Endung abschneiden und .dfq dranhängen

			;Wenn die Datei existiert soll sie vorher gelöscht werden
			FileDelete($S_SPEICHERORT & "\" & $sDateiname)
			FileWrite($S_SPEICHERORT & "\" & $sDateiname, $sEndFile)

			;Alte Dateien löschen
			For $k = 0 To UBound($aFileName) - 1
				FileDelete($aFileName[$k])
			Next
		EndIf
	EndIf
Next

Func _SortiereVorgaengeNachDatum($aZusammengefassteVorgaenge)
	;Sortiere mit GnomeSort (jaja ich weiß, ist langsam aber sehr schnell implementiert)

	For $i = 0 To UBound($aZusammenfassenVorgaenge) - 2
		$aDate1 = StringSplit($aZusammenfassenVorgaenge[$i][1], ".", 3)
		$aDate2 = StringSplit($aZusammenfassenVorgaenge[$i + 1][1], ".", 3)

		$sLeftDate = $aDate1[2] & "/" & $aDate1[1] & "/" & $aDate1[0] & " " & $aZusammenfassenVorgaenge[$i][2]
		$sRightDate = $aDate2[2] & "/" & $aDate2[1] & "/" & $aDate2[0] & " " & $aZusammenfassenVorgaenge[$i][2]

		If _DateDiff("s", $sLeftDate, $sRightDate) > 0 Then ; Rechtes Datum ist früher, also wechseln und Index zurück
			Local $aTmp[3] = [$aZusammenfassenVorgaenge[$i + 1][0], $aZusammenfassenVorgaenge[$i + 1][1], $aZusammenfassenVorgaenge[$i + 1][2]]
			$aZusammenfassenVorgaenge[$i + 1][0] = $aZusammenfassenVorgaenge[$i][0]
			$aZusammenfassenVorgaenge[$i + 1][1] = $aZusammenfassenVorgaenge[$i][1]
			$aZusammenfassenVorgaenge[$i + 1][2] = $aZusammenfassenVorgaenge[$i][2]
			$aZusammenfassenVorgaenge[$i][1] = $aTmp[0]
			$aZusammenfassenVorgaenge[$i][2] = $aTmp[1]
			$aZusammenfassenVorgaenge[$i][3] = $aTmp[2]

			$i -= 1
		EndIf
	Next

	Return $aZusammenfassenVorgaenge
EndFunc

;Anzahl der Sollwerte in einem Vorgang zählen (wird für UMFANG benötigt)
Func _ZaehleVorgang($aVorgaenge, $iIndex)
	Local $iCounter = 0

	For $i = 1 To UBound($aVorgaenge, 2) - 1
		If $aVorgaenge[$iIndex][$i] = "" Then ExitLoop
		$iCounter += 1
	Next

	Return $iCounter
EndFunc

;Einfache Errormeldung. Zeigt welcher Parameter nicht extrahiert werden konnte
Func _Error($sMsg)
	MsgBox(16, "Fehler", $sMsg & " konnte nicht korrekt gelesen werden.")
	Exit 0
EndFunc

;Wandelt das Datum (8. Januar 2018) zu (08.01.2018) um.
Func _DatumFormatieren($sDatum)
	Local $aMonate[] = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]

	Local $aSplit = StringSplit($sDatum, " ", 3)

	$aSplit[0] = StringTrimRight($aSplit[0], 1) ; Punkt entfernen
	If StringLen($aSplit[0]) < 2 Then $aSplit[0] = "0" & $aSplit[0] ; Führende Null dranhängen

	For $i = 0 to UBound($aMonate) - 1
		If $aSplit[1] = $aMonate[$i] Then $aSplit[1] = ($i < 10 ? "0" : "") & $i + 1 ; Einfach Index aus der Schleife als Monatszahl nehmen
	Next

	Return $aSplit[0] & "." & $aSplit[1] & "." & $aSplit[2]
EndFunc

;Fügt führende Nullen zur Uhrzeit hinzu
Func _NullenHinzufuegen($sUhrzeit)
	$aSplit = StringSplit($sUhrzeit, ":", 3)

	For $i = 0 To UBound($aSplit) - 1
		If Number($aSplit[$i]) < 10 Then $aSplit[$i] = "0" & Number($aSplit[$i])
	Next

	Return $aSplit[0] & ":" & $aSplit[1] & ":" & $aSplit[2]
EndFunc