# -*- encoding: iso-8859-1 -*-

"""Verwalter eines Eintrags
"""

import re, sys


class Entry:
	"""vereinheitlicht das Format der Wörterbucheinträge. Macht die einzelnen 
	Informationseinheiten innerhalb des Eintrags zugänglich.
	"""

	def __init__(self, entry):
		"""bekommt einen kompletten Wörterbucheintrag in einer Liste. Legt für 
		jede Informationseinheiten ein Klassenattribut an. Ruft die Funktion 
		_parse auf.
		"""
		self.ident = str(entry[0])
		self.wl2 = ""
		self.zDic = {}
		self.qDic = {}
		self.date = ""
		self.author = ""
		self.unknown = []
		self._parse(entry)


	def _parse(self, entry):
		"""bekommt einen kompletten Wörterbucheintrag in einer Liste. 
		Weist durch reguläre Ausdrücke den folgenden Klassenattributen 
		einen Wert zu: self.wl1, self.wl2, self.ibed, self.rectyp, 
		self.zDic, self.qList, self.author, self.date, self.unknown.
		Matcht ein Element auf keinen der regulären Ausdrücke, wird dieses 
		Element als unbekannt gespeichert, um zu vermeiden, dass Elemente 
		verloren gehen.
		"""
		for line in entry[1:]:
			switch = 0

			mat = re.search("^WL1:(.*)\s\s\s\s\s+([A-Z]+)", line)
			if mat:
				self.wl1 = mat.group(1).strip()
				switch += 1
				if mat.group(2):
					self.author = mat.group(2).strip()
					switch += 1

			mat = re.search("^WL2:\s?(.*)\s+([0-9]{4,8})?",line.strip())
			if mat:
				self.wl2 = mat.group(1).strip()
				if mat.group(2):
					self.date = mat.group(2).strip()
					switch += 1
				switch += 1

			mat = re.search("^IBED\s+=\s+([0-9]*)", line.strip())
			if mat:
				self.ibed = mat.group(1)
				switch = 2

			mat = re.search("^RECTYP\s+=\s+([0-9]*)", line.strip())
			if mat:
				self.rectyp = mat.group(1)
				switch = 2
					
			mat = re.search(
				"(^Z\s*[0-9]+)\s*=((\s+[0-9]+){4,4})",line.strip())
			if mat:
				self.zDic[mat.group(1)] = tuple(mat.group(2).split())
				switch = 2
			
			mat = re.search(
 				"(^Q[(]?\s?[0-9]+[)]?)[:=](((\s*[a-z0-9()=\s]*\s*[(]?\s*[0-9]+[)]?,?)){4,4})",
					line.strip())

			if mat:
				switch = self._parseQ(mat)

			if switch < 2 and len(line.strip()) > 2:
				self.unknown.append(line)
				failt = open("../../res/teilergebnisse/01unknown.txt", "a")
				failt.write("in entry " + self.wl1 + " not found: " + line + "\n")

	
	def _parseQ(self, mat):
		"""entfernt Kommata und Leerzeichen aus den Q-Zeilen. Vereinheitlicht die 
		'='Zeichen Setzung.
		"""
		key = re.sub("[()\s]", "", mat.group(1))
		tmp = re.sub("[(),]","",mat.group(2))
		tmp = re.findall("[a-z]+[0-9]?\s*=?\s*[0-9]+|[0-9]+", tmp)
		valList = []
		for i in tmp:
			if re.search("[a-z]+[0-9]*\s+[^=][0-9]+",i): 
				# manche Q-Zeilen sind statt dem Muster kknum1=1 ohne "=" Zeichen kodiert. 
				# Das "=" wird hier zur Vereinheitlichung eingefügt
				i = re.sub("\s+", "=", i)	
			i = re.sub("\s", "", i)
			valList.append(i)
		if not len(valList) == 4:
			return 0			
		self.qDic[key]= valList
		return 2
		
		
	def _cmpKey(self, tup1, tup2):
		"""bekommt zwei Tupel, in deren erstem Element ein Buchstabe und eine Zahl als
		String gespeichert stehen. Vergleicht die Zahlen der beiden Strings miteinander.
		"""
		num1 = re.search("[0-9]+", tup1[0]).group()
		num2 = re.search("[0-9]+", tup2[0]).group()
		return cmp(int(num1), int(num2))
		

	"""die folgenden Funktionen machen die verschiedenen Einheiten eines Lexikoneintrags
	für die Außenwelt zugänglich.
	"""	
	
	def getIdent(self):
		"""gibt die ID-Nummer als String zurück
		"""	
		return self.ident	


	def getWl1(self):
		"""gibt das Wortlemma1 als String zurück
		"""	
		return self.wl1


	def getWl2(self):
		"""gibt das Wortlemma2 als String zurück
		"""		
		return self.wl2


	def getIbed(self):
		"""gibt die Bedeutungsnummer als String zurück.
		"""	
		return self.ibed


	def getRectyp(self):
		"""gibt den Rektionstyp als String zurück.
		"""	
		return self.rectyp


	def getAuthor(self):
		"""gibt einen String zurück, der vermutlich den Autor des 
		WDG-Eintrags enthält.
		"""	
		return self.author


	def getDate(self):
		"""gibt Zahlen - vermutlich das Eintragungsdatum - als String zurück.
		"""	
		return self.date
		
			
	def getZ(self):
		"""gibt alle Z-Zeilen in einer Liste mit Tupeln zurück. Das 
		Tupel besteht aus dem Kopf der Zeile und aus einem Quadrupel
		der folgenden vier Elemente, z.B.:
		[('Z1', ('0', '4', '0', '9')), ('Z2', ('1', '2', '0', '2')), ...]
		Sortiert die Liste nach Größe des erste Tupel-Elements, also z1 
		vor Z2 vor Z18.
		"""	
		zList = []
		zList = self.zDic.items()
		zList.sort(self._cmpKey)
		return zList

		
	def getQ(self):
		"""gibt alle Q-Zeilen in einer Liste mit Tupeln zurück. Das 
		Tupel besteht aus dem Kopf der Zeile und aus einem Vierer-Tupel 
		mit den vier folgenden Elementen, z.B.:
		[('Q1', ('0', 'jwk=40', 'jstw=0', 'jbed=9')), 
		('Q15', ('ksubk=1', 'kgrph=2', 'kkla1=0', 'kkla2=0')), 
		...]
		Sortiert die Liste nach Größe des erste Tupel-Elements, also 
		Q1 vor Q2 vor Q18.
		"""	
		qList = []
		qList = self.qDic.items()
		qList.sort(self._cmpKey)
		return qList


	def getUnknown(self):
		"""gibt einen String von Daten zurück, die in keines der definierten 
		Schemen passen.
		"""	
		return self.unknown





