#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

import sqlite3
import os.path
import sys
import pygame
import time
import math

from helper import *
from leute import *
from wege import Wege

#		BASISKLASSE GEBÄUDE
#===================================
#	Diese Klasse definiert die Warenfluss Prozesse für alle Gebäude (einkaufen, verkaufen, einkaufen2 (Häuser))
class Batiment(object):
	def __init__(self,neu,dic,pos):
		if dic == {}:
			self.typ = 	neu["type"]
			self.aura = []
			self.speicher = {}
			self.pos = pos
			
			self.verbrauch = {}
			for key in neu:
				if key[0:6] == "verbr_":
					self.verbrauch[ int(key[-3:]) ] = neu[key]
					self.speicher[ int(key[-3:]) ]  = 0

			if neu.get("prod") != None:
				self.prod = neu["prod"]
				self.prodv	= neu["prodv"]
				self.speicher = {self.prod:0}

			if neu.get("reqgut") != None:
				self.reqgut	= neu["reqgut"]
			if neu.get("reqfeld") != None:	
				self.reqfeld = neu["reqfeld"]			
				
		else:
			self.typ = dic["typ"]
			self.aura = dic["aura"]
			self.speicher = dic["spe"]
			self.pos = pos
			
			if dic.get("prod") != None:
				self.prod = dic["prod"]
				self.prodv = dic["prodv"]
			if dic.get("reqfeld"):
				self.reqfeld = dic["reqfeld"]
			if dic.get("verbrauch"):
				self.verbrauch = dic["verbrauch"]	
				
			if dic.get("reqgut") != None:
				self.reqgut	= dic["reqgut"]
	
	def __next_markthaus__(self,player):
		markthaus = [None,1]
		for t in [15]:
			for geb in player.geb[t]:
				l = math.sqrt( ( player.geb[t][geb].pos[0] - self.pos[0])**2 + ( player.geb[t][geb].pos[1] - self.pos[1])**2)  
				if (l > markthaus[1]) and (self.pos in player.geb[t][geb].aura):
					markthaus = [player.geb[t][geb] , l]
		return markthaus
		
	def __unterwegs__(self,player,ziel,typ):
		unterwegs = False
		for l in player.leute.leute:
			if (l.end.pos == self.pos) and (l.start.pos == ziel.pos):
				if (l.todo[0][0] == typ):
					unterwegs = True 		
		return unterwegs
		
	def einkaufen(self,player,monde):
		
		##	Herraussuchen des Luftlinienmässig am nächsten gelegenen Markthaus 
		markthaus = self.__next_markthaus__(player)
		
		##	Schicke jemanden Die Ware zu holen 
		if markthaus[0] != None:
			anschluss_markt = anschluss_geb(monde.monde , markthaus[0].pos)
			anschluss_haus = anschluss_geb(monde.monde , self.pos)	
			
			# prüfe ob jemand schon unterwegs ist
			unterwegs = self.__unterwegs__(player,markthaus[0],self.reqgut)
			
			if (anschluss_markt != []) and (anschluss_haus != []) and (unterwegs == False):
				player.leute.leute.append( Traeger(monde , start=anschluss_markt, stop=anschluss_haus , geb=[markthaus[0] , self]) )
				if player.leute.leute[-1].route != []:
					player.leute.leute[-1].todo.append( [self.reqgut , -1*player.leute.leute[-1].max_spe] )
					player.leute.leute[-1].todo.append( [self.reqgut ,    player.leute.leute[-1].max_spe] )
					print "einkaufen GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)
				else:		# gibt es keinen Weg zwischen den Gebäuden, so löschen den Träger wieder
					del player.leute.leute[-1]	
					print "del träger GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)	
				
		
	def verkaufen(self,player,monde):
		##	Herraussuchen des Luftlinienmässig am nächsten gelegenen Markthaus 
		markthaus = self.__next_markthaus__(player)
	
		##	Schicke jemanden Die Ware zu holen 
		if markthaus[0] != None:
			anschluss_markt = anschluss_geb(monde.monde , markthaus[0].pos)
			anschluss_haus = anschluss_geb(monde.monde , self.pos)	
			# prüfe ob jemand schon unterwegs ist
			unterwegs = self.__unterwegs__(player,markthaus[0],self.prod)
						
			if (anschluss_markt != []) and (anschluss_haus != []) and (unterwegs == False):
				player.leute.leute.append( Traeger(monde , start=anschluss_markt, stop=anschluss_haus , geb=[markthaus[0] , self]) )
				if player.leute.leute[-1].route != []:
					player.leute.leute[-1].todo.append( [self.prod ,   player.leute.leute[-1].max_spe] )
					player.leute.leute[-1].todo.append( [self.prod ,-1*player.leute.leute[-1].max_spe] )
					print "verkaufen GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)
				else:		# gibt es keinen Weg zwischen den Gebäuden, so löschen den Träger wieder
					del player.leute.leute[-1]	
					print "del träger GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)	
				
	def einkaufen2(self,player,monde,gueter):
		##	Herraussuchen des Luftlinienmässig am nächsten gelegenen Markthaus 
		markthaus = self.__next_markthaus__(player)

		##	Schicke jemanden Die Ware zu holen 
		if markthaus[0] != None:
			anschluss_markt = anschluss_geb(monde.monde , markthaus[0].pos)
			anschluss_haus = anschluss_geb(monde.monde , self.pos)	
			
			# prüfe ob jemand schon unterwegs ist
			unterwegs = self.__unterwegs__(player,markthaus[0],gueter[0])
			
			if gueter != []:
				if (anschluss_markt != []) and (anschluss_haus != []) and (unterwegs == False):
					player.leute.leute.append( Einwohner(monde , start=anschluss_markt, stop=anschluss_haus , geb=[markthaus[0] , self]) )
					if player.leute.leute[-1].route != []:
						player.leute.leute[-1].todo.append( [gueter[0] , -1*player.leute.leute[-1].max_spe] )
						player.leute.leute[-1].todo.append( [gueter[0] ,    player.leute.leute[-1].max_spe] )
						print "einkaufen2 GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)
					else:		# gibt es keinen Weg zwischen den Gebäuden, so löschen den Träger wieder
						del player.leute.leute[-1]	
						print "del träger GebTyp:" + str(self.typ) + " GebPos:" + str(self.pos)	

	
#		GETREIDE FARM KLASSE 
#===================================
#	Definiert das Gebäude Getreidefarm 	
class Farm(Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		Batiment.__init__(self,neu,dic,pos)

	def ernte(self,monde):
		for f in self.aura:
			if monde[f[0]][f[1]].islink() == False:
				if monde[f[0]][f[1]].typ == self.reqfeld:
					self.speicher[self.prod] = self.speicher[self.prod] + self.prodv
	
	def speicherIO(self,typ,quant):
		if self.speicher.get(typ) == None:
			self.speicher[typ] = 0
		if self.speicher[typ] - quant != 0:
			#print "Speicher IO " + str(quant) + " " + str(typ)  
			self.speicher[typ] = self.speicher[typ] - quant 			# Vorzeichen : -quant oder +quant
	
	def dump(self):
		return {"typ":self.typ , "prod":self.prod , "prodv":self.prodv , "reqfeld":self.reqfeld , "aura":self.aura , "spe":self.speicher}  


#		FORSTHAUS KLASSE 
#===================================
#	Definiert das Gebäude Forsthaus, Erbt Farm (s.o.) 
class Forsthaus(Farm,Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		Farm.__init__(self,neu,dic)
		Batiment.__init__(self,neu,dic,pos)

		
#		HAUS KLASSE 
#===================================
#	Definiert das Gebäude Einwohnerhaus 
class Haus(Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		Batiment.__init__(self,neu,dic,pos)
		
		if dic == {}:
			self.zufrieden = {}
			for key in self.verbrauch:
				self.zufrieden[key] = 100
			self.einwohner = 1
			self.max_einwohner = neu["max_einwohner"]
			self.stimmung = 100
			self.next_zuwachs = 0
		else:
			self.zufrieden = dic["zufrieden"]
			self.stimmung = dic["stimmung"]
			self.max_einwohner = dic["max_einwohner"]
			self.einwohner = dic["einwohner"]
			self.next_zuwachs = 0 

	def speicherIO(self,typ,quant):
		if self.speicher.get(typ) == None:
			self.speicher[typ] = 0
		if self.speicher[typ] - quant != 0:
			#print "Speicher IO " + str(quant) + " " + str(typ)  
			self.speicher[typ] = self.speicher[typ] - quant 			# Vorzeichen : -quant oder +quant
			
	def konsum(self):
		total_stimmung = 0
		for gut in self.verbrauch:
			if self.speicher.get(gut) != None:
				if self.speicher[gut] - self.verbrauch[gut] >= 0:
					if self.zufrieden[gut] < 100:
						self.zufrieden[gut] = self.zufrieden[gut] +5  
					self.speicher[gut] = self.speicher[gut] - self.verbrauch[gut]
				else:
					if self.zufrieden[gut] >0 :
						self.zufrieden[gut] = self.zufrieden[gut] -5 
			total_stimmung = total_stimmung + self.zufrieden[gut]
		self.stimmung = total_stimmung / len(self.zufrieden)  		
	
	def dump(self):
		return {"typ":self.typ , "aura":self.aura , "spe":self.speicher , "verbrauch": self.verbrauch, "zufrieden":self.zufrieden , "stimmung" : self.stimmung , "max_einwohner" : self.max_einwohner , "einwohner" : self.einwohner}  


#		GETRIDE MÜHLE KLASSE 
#===================================
#	Definiert das Gebäude Mühle 
class Muehle(Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		Batiment.__init__(self,neu,dic,pos)

			
	def produktion(self):
		if self.speicher.get(self.reqgut) != None:
			if self.speicher[self.reqgut] - self.prodv*self.prod >= 0:
				self.speicher[self.reqgut] = self.speicher[self.reqgut] - self.prodv*self.prod
				self.speicher[self.prod] = self.speicher[self.prod] +  self.prodv*self.prod
		 	
			
	def speicherIO(self,typ,quant):
		if self.speicher.get(typ) == None:
			self.speicher[typ] = 0
		if self.speicher[typ] - quant >= 0:
			#print "Speicher IO " + str(quant) + " " + str(typ)  
			self.speicher[typ] = self.speicher[typ] - quant 			# Vorzeichen : -quant oder +quant
		else:
			print "nicht genügend Gut im Speicher"
	
	def dump(self):
		return {"typ":self.typ , "prod":self.prod , "prodv":self.prodv , "reqgut":self.reqgut , "aura":self.aura , "spe":self.speicher}  


#		BÄCKER KLASSE 
#===================================
#	Definiert das Gebäude Bäcker 
class Baecker(Muehle,Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		#Batiment.__init__(self,neu,dic,pos)
		#print self.pos
		if dic == {}:
			Muehle.__init__(self,neu=neu,pos=pos)
		else:
			Muehle.__init__(self,neu=neu,dic=dic,pos=pos)

	
#		MARKTHAUS alias KONTOR KLASSE 
#===================================
#	Definiert das Gebäude Kontor 		
class Markthaus(Batiment):
	def __init__(self,neu={},dic={},pos=[]):
		Batiment.__init__(self,neu,dic,pos)

	def speicherIO(self,player,typ,quant):
		print "markthaus.speicherIO depreciated ... use player.speicherIO instead"
		if self.speicher.get(typ) == None:
			self.speicher[typ] = 0	
		if player.spe.get(typ) == None:
			player.spe[typ] = 0
		if player.spe[typ] - quant >= 0:
			#print "Speicher IO " + str(quant) + " " + str(typ)  
			self.speicher[typ] = self.speicher[typ] - quant 			# Vorzeichen : -quant oder +quant
			player.spe[typ] = player.spe[typ] - quant 			# Vorzeichen : -quant oder +quant
			
	def dump(self):
		return {"typ":self.typ , "aura":self.aura , "spe":self.speicher}  
	
		
#		BASISKLASSE FÜR ALLE FELDER DES SPIELFELDES 
#======================================================
#	Definiert die case objekte, die in monde.monde gelagert werden
class Case(object):
	def __init__(self,pos,size,datei,typ,bauen,neu,link=None):
		self.pos = pos
		if link == None:
			self.neu = neu
			self.dpos = [0,0]
			self.npos = [0,0]
			self.typ = typ
			self.datei = datei
			self.zoom = int(self.datei[-7])
			self.light = self.datei[-5] 
			if self.zoom == 1:
				size2 =  [neu[self.typ]["size2"][0]/2 , neu[self.typ]["size2"][1]/2]
			elif self.zoom == 2:
				size2 =  neu[self.typ]["size2"]
			elif self.zoom == 0:
				size2 =  [neu[self.typ]["size2"][0]/4 , neu[self.typ]["size2"][1]/4]
			
			## dateinamen sind IMMER in der Form name-zx-t.png (wobei x die zoomzahl (1,2 oder 3) und t der typ (d,n oder b) ist)
			if neu[self.typ].get("multifr") == 1:
				self.multiframe = [1,size2]
				self.img= []
				for im in self.neu[self.typ]["img-z"+str(self.zoom)+"-"+str(self.datei[-5])]:
					self.img.append(im.copy())
				self.rect = self.img[0].get_rect()
			else:	
				self.multiframe = [0,size2]
				self.img = self.neu[self.typ]["img-z"+str(self.datei[-7])+"-"+str(self.light)].copy()
				self.rect = self.img.get_rect()
				
			self.korr =0
			self.bauen = bauen
			self.size = size
			self.link = None
		else:
			self.link = link 
	def islink(self):
		if self.link == None:
			return False
		else:
			return True
	
	def __light__(self,t):
		## dateinamen sind IMMER in der Form name-zx-t.png (wobei x die zoomzahl (1,2 oder 3) und t der typ (d,n oder b) ist)
		self.datei = self.datei[:-6] + "-"+t+".png" 
		self.light = t
		z = str(self.zoom)
		if self.multiframe[0] == 1:
			self.img = []
			for im in self.neu[self.typ]["img-z"+str(z)+"-"+str(t)]:
				self.img.append(im.copy())
		else:
			self.img = self.neu[self.typ]["img-z"+str(z)+"-"+str(t)].copy()

	def highlight(self):
		self.__light__("b")

	def darken(self):
		self.__light__("d") 
	def unhighlight(self):
		self.__light__("n")
		
	def load_img(self):
		self.unhighlight()
		if self.multiframe[0] == 1:
			self.rect = self.img[0].get_rect()
		else:	
			self.rect = self.img.get_rect()
	
	def calc_korrektur(self,s):
		self.korr = self.rect.height - self.size[1]*s[1] +((self.size[1]-1)*(s[1]/2))		# warum +60? ## +((bauen["size"][1]-1)*(s[1]/2)) --> try&error , weitere Korrektur, da das Erste Feld der belegten Felder genutzt wird, dann aber ein Unterschied zwischen den oberen linken ecken besteht , bei neuberrechnung (init_monde), wird dieser schritt unnötig
	def do_korrektur(self):
		self.dpos = [ self.npos[0], self.npos[1]-self.korr]
		if self.multiframe[0] == 0:
			self.rect = self.img.get_rect().move(self.dpos)
		else:
			self.rect = self.img[0].get_rect().move(self.dpos)
			
	def debug(self):
		print ""
		if self.link == None:
			print "pos: " + str(self.pos) + "\n" + "npos: " + str(self.npos) + "\n" + "dpos: " + str(self.dpos) + "\n" + "korr: " + str(self.korr) + "\n" + "size: " + str(self.size) + "\n" + "datei: " + str(self.datei) + "\n" + "typ: " + str(self.typ)
			print "impgObj: " + str(self.img) + "\n" + "rectObj: " + str(self.rect)
		else:
			print "pos: " + str(self.pos) + "\n" + "npos: " + str(self.npos) + "\n"+"link: " + str(self.link)
		print ""
		
		
		
		
#		DIE WELT 
#===================================
#	Definiert die Welt und alle interaktionen 

class Monde(object):
	def __init__(self,datei):
		
		## neu	
		##########################
		datei_bgr = open("bgruppen.txt","r",1)
		conf=""
		# alle lines in eine var schreiben
		ok = False		# nur zwischen begin[ebjects] und end[objects] suchen
		for line in datei_bgr.readlines():
			if line == "begin[objects]\n":
				ok = True
			if line == "end[objects]\n":
				ok = False
				break
			if ok == True:
				conf=conf+line
		datei_bgr.close()		# schliesse datei
	
		conf = conf.expandtabs() # alle tab zeichen in spaces umwandels
		neu={}
		while conf.strip("\n").strip() != "":		# es bleiben eventuell noch spaces und line breaks (wenn die nicht verschwinden -> endloschleife)
			o={}	
			i = conf.find("{")	# anfang
			i2 = conf.find("}")	# ende
			item = conf[i+1:i2]	
			item = item.split("\n")
			for e in item:	
				if e != "":
					e= e.split(":")
					e[1] = e[1].strip().strip('"').strip()	# entferne " von den values der optionen
					e[0] = e[0].strip()		# entferne spaces von index der optionen
					o[e[0]] = e[1].strip().strip('"').strip()	
			neu[int(o["type"])] = o			# erstellung von neu (index muss int sein)
			conf = conf[i2+1:]		# decremenierung um {...}
	
		# types
		for r in neu:
			for r2 in neu[r]:
				# stings bleiben strings
				if neu[r][r2][0] == "[" and neu[r][r2][-1] == "]":		# arrays
					neu[r][r2] = neu[r][r2].strip("[]").split(",")
					for i in range(len(neu[r][r2])):
						neu[r][r2][i] = int(neu[r][r2][i])
				elif neu[r][r2].isdigit():			# ints
					neu[r][r2] = int(neu[r][r2])
				elif neu[r][r2].split(".")[0].isdigit() and neu[r][r2].split(".")[1].isdigit():			# floats
					neu[r][r2] = float(neu[r][r2])
	
		for n in neu:
			for z in [["0",0.25],["1",0.5],["2",1]]:
				for t in ["n","b","d"]:
					if neu[n].get("multifr") == 1:
						neu[n]["img-z"+str(z[0])+"-"+str(t)] = load_multiframe(neu[n]["datei"][:-7]+str(z[0])+ "-"+str(t)+".png"  ,  [ int(neu[n]["size2"][0]*z[1]) , int(neu[n]["size2"][1]*z[1]) ])
					else:
						neu[n]["img-z"+str(z[0])+"-"+str(t)] = pygame.image.load( neu[n]["datei"][:-7]+str(z[0])+ "-"+str(t)+".png" ).convert_alpha()	

		self.neu = neu


		## monde	
		##########################
		if os.path.exists(datei) == False:
			print "Datei '" + str(datei) + "' existiert nicht"
			sys.exit()
		else:
			con = sqlite3.connect(datei)		
			con.row_factory = sqlite3.Row	# um später bei fetchone() mit listen arbeiten zu können 
			c= con.cursor()		
			c.execute('''select * from monde''') 	# alles aus monde laden
			
			ok = True		# tempvariabel, fetchone gibt none aus wen nichts mehr da ist, vermeidung einer Endloschleife 
			monde = []
			while ok == True:
				r = c.fetchone()	# nächste row holen
				if r != None:
					keys= r.keys()	# monde keys in den dicts
					t={}
					for k in keys:
						t[k]=str(r[k])
						# konvertiren der datatypes
						# stings bleiben strings
						if t[k] != "":
							if t[k][0] == "[" and t[k][-1] == "]":		# arrays
								t[k] = t[k].strip("[]").split(",")
								t[k][0] = int(t[k][0])
								t[k][1] = int(t[k][1])
							elif t[k].isdigit() or (t[k][0] == "-" and t[k][1:].isdigit()):			# ints
								t[k] = int(t[k])
							elif t[k] == "None":
								del t[k] 
					monde.append(t)
				else:
					ok = False 
			con.close()		# schliesse datei

			
			## neues array initialisieren
			#--------------------
			monde2=[]
			k=0
			for j in monde:
				if j != {}:
					if j["pos"][0] > k:
						k =  j["pos"][0]
			n=0
			for m in monde:
				if m != {}:
					if m["pos"][1] > n:
						n = m["pos"][1]
			
			for each in range (0,k+1):
				monde2.append([])
				for each in range(0,n+1):
					monde2[-1].append([])
					
			## neues array füllen
			#--------------------
			
			for l in monde:
				if l != {}:
					if l.get("link") == None:
						monde2[ l["pos"][0] ][ l["pos"][1] ] = Case(l["pos"],l["size"],l["datei"],l["type"],l["bauen"],self.neu)
					else:
						monde2[ l["pos"][0] ][ l["pos"][1] ] = Case(l["pos"],None,None,None,None,self.neu,l["link"])

			
			
		## 	Sonstige	
		##########################
		self.monde = monde2
		self.draw=[]
		self.bauen_mouse_state = False
		self.gebaut = []
		self.wege = Wege(self.monde)
		self.bauen = []
		self.zoom = 2
		self.champs = [1,3]
		self.batiments = [10,11,15,20,21,22,23]
		self.chemins = [2]
		self.zoom_size = [[26,15],[52,30],[104,60]]
		self.players = None
	
	def get(self,pos):
		return self.monde[pos[0]][pos[1]]
	def get_zoomsize(self):
		return self.zoom_size[self.zoom]
	
	
	#		SPIELBRETT 
	#===================================
	#	Ist für das Schachbrettmuster der Welt zuständig (errechnet korrekturen) 
	def Spielbrett(self,z,begin=[0,0]):
		
		### bestimmen von den verschiedenen zoom grössen
		s=[]
		if z == 0:
			s = [26,15]
		elif z == 1:
			s = [52,30]
		elif z == 2:
			s = [104,60]
		### rechne positionen (dpos) aus		
		x=begin[0]-(s[1]/2)-10*z
		y=begin[1]-(s[1]/2)
		for i in range(0 , self.monde[-1][-1].pos[1] +1):
			for i2 in range(0 , self.monde[-1][i].pos[0] +1):
				x= x + (s[0]/2)		# alt 52
				y= y - (s[1]/2)		# alt 30
				if self.monde[i2][i].link == None:
					korrektur1 = self.monde[i2][i].rect.height - self.monde[i2][i].size[1]*(s[1])		# alt 60
					korrektur2 = (self.monde[i2][i].size[0] - 1)*(s[1]/2)		# alt 30
					self.monde[i2][i].rect = self.monde[i2][i].rect.move(x,y-korrektur1-korrektur2)
					self.monde[i2][i].dpos = [x,y-korrektur1-korrektur2]
					self.monde[i2][i].korr = korrektur1
					self.monde[i2][i].npos = [x,y-korrektur2]
				elif self.monde[i2][i].link != None:
					self.monde[i2][i].npos = [x,y]
					
			y= begin[1]+(s[1]/2)*i		# alt 30
			x= begin[0]+(s[0]/2)*i		# alt 52
	
	
			
	#		ZOOM 
	#===================================
	#	Zoomt die Welt ein oder aus 	
	def do_zoom(self,p,(width,height)):
		f = self.zoom
		player = self.players.players[p]
		mouse = pygame.mouse.get_pos()
		point_fixe = None
		# datei ändern (-zk -> -zk+1)
		for x in self.monde:
			for o in x:
				if o.islink() == False:
					o.datei = o.datei[:-9] + "-z"+str(f) + o.datei[-6:]
					o.zoom = f
		# neu berechnung von monde
		### lade bild dateien	 
		for row in self.monde:
			for obj in row:
				if obj.islink() == False:
					if obj.rect.collidepoint(mouse) and (point_fixe == None):
						point_fixe = [obj.pos[:],obj.npos[:]]
					if self.neu[obj.typ].get("multifr") == 1:
						if self.zoom == 0:
							size2 = [int(self.neu[obj.typ]["size2"][0]*0.25) , int(self.neu[obj.typ]["size2"][1]*0.25)]
						elif self.zoom == 1:
							size2 = [int(self.neu[obj.typ]["size2"][0]*0.5) , int(self.neu[obj.typ]["size2"][1]*0.5)]
						elif self.zoom == 2:
							size2 = self.neu[obj.typ]["size2"]
						obj.multiframe = [1,size2]
						obj.img= []
						for im in self.neu[obj.typ]["img-z"+str(f)+"-"+str(obj.light)]:
							obj.img.append(im.copy())
						obj.rect = obj.img[0].get_rect()
					else:	
						obj.multiframe = [0,self.neu[obj.typ]["size2"]]
						obj.img = self.neu[obj.typ]["img-z"+str(f)+"-"+str(obj.light)].copy()
						obj.rect = obj.img.get_rect()

		self.Spielbrett(f)
		
		for l in player.leute.leute:
			if self.zoom == 0:
				size2 = [int(self.neu[l.typ]["size2"][0]*0.25) , int(self.neu[l.typ]["size2"][1]*0.25)]
			elif self.zoom == 1:
				size2 = [int(self.neu[l.typ]["size2"][0]*0.5) , int(self.neu[l.typ]["size2"][1]*0.5)]
			elif self.zoom == 2:
				size2 = self.neu[l.typ]["size2"]
			l.multiframe[1] = size2
			l.datei = l.datei[:-9]+"-z"+str(self.zoom)+"-n.png"
			l.load_img(self)
			l.dpos=self.get(l.route[0]).dpos[:]
		
		if point_fixe != None:
			move = [point_fixe[1][0]-self.get(point_fixe[0]).npos[0] , point_fixe[1][1]-self.get(point_fixe[0]).npos[1]]
			self.scroll(p,(width,height),0,move)
		# änderung von neu, so dass die richtigen grössen gebaut werden können
		for key in self.neu:
			self.neu[key]["datei"] = self.neu[key]["datei"][:-9] + "-z"+ str(f) + self.neu[key]["datei"][-6:]
		for n in range(0,50):
			if self.neu.get(n) != None:
				self.neu[n]["img"] = pygame.image.load(self.neu[n]["datei"]).convert_alpha()
				self.neu[n]["rect"] =  self.neu[n]["img"].get_rect()



	#		SCROLL
	#===================================
	#	updated die karte wenn der Spieler scrollt	erstellt auch die 'Reparaturen' für die Perspektive		
	def scroll(self,p,(width,height),speed,move=[0,0]):
		player = self.players.players[p]
		self.draw=[]
		mouse = pygame.mouse.get_pos()
		if move == [0,0]:
			if mouse[0] > (width - 10) :	# x richtung
				move=[-1*speed,0]
			if mouse[0] < 10:			# -x richtung
				move=[1*speed,0]
			if mouse[1] > (height -10) :	# y richtung
				move=[0,-1*speed]
			if mouse[1] < 10:		# -y richtung
				move=[0,1*speed]
		
		# draw muss in -x und +y Richtung aufgebaut werden !, wegen der Perspektive
		# also muss monde[] rückwärts durchlaufen werden

		maisons = []
		l=len(self.monde[-1])-1
		for y in range(0,l+1):
			l2 = len(self.monde)-1
			for x in range(l2,-1,-1):
				o = self.monde[x][y]
				if o.link == None:	
					o.dpos[0] =  o.dpos[0] + move[0]
					o.dpos[1] =  o.dpos[1] + move[1]
					o.npos[0] =  o.npos[0] + move[0]
					o.npos[1] =  o.npos[1] + move[1]
					if -512 < o.dpos[0] < (width +512)  and -512 < o.dpos[1] < (height + 512):
						self.draw.append(o)
						if self.neu[self.draw[-1].typ].get("multifr") == 1: 
							self.draw[-1].rect = o.img[0].get_rect().move(o.dpos)
						else:
							self.draw[-1].rect = o.img.get_rect().move(o.dpos)
						self.draw[-1].img = o.img
						
						if o.size != [1,1]:
							maisons.append(o) 
				elif o.link != None:
					self.draw.append(o)
					o.npos[0] =  o.npos[0] + move[0]
					o.npos[1] =  o.npos[1] + move[1]
		
		del x,y
		self.draw_repair = []
		for m in maisons:
			r = []
			## gehe den "Schatten" des hauses durch, dh den Bereich hinter dem Haus, der von den anderen Feldern nicht überlagert werden soll
			## diese Reparatur ist nötig, weil der hinrere Teil des Hauses durch andere Felder überlagert wird 
			for y in range(m.pos[1] , m.pos[1]+m.size[1]):	
				for x in range(m.pos[0]+m.size[0] , m.pos[0]+m.size[0] + 3):	
					if len(self.monde) > x:
						if len(self.monde[x]) > y:
							if self.monde[x][y].islink() == False:
								if m.rect.colliderect(self.monde[x][y].rect):	# überlagert- sich überhaupt etwas
									img = pygame.Surface( (self.monde[x][y].rect.width,self.monde[x][y].rect.height) , flags=pygame.SRCALPHA)	
									rect = img.get_rect()
									# zeichne die überlagerten Teile auf eine neue Surface neu. dabei muss der Bereich stimmen (mit delta der positionen)
									if self.neu[m.typ].get("multifr") == None:
										img.blit(m.img , pygame.Rect(m.rect.topleft[0]-self.monde[x][y].rect.topleft[0],m.rect.topleft[1]-self.monde[x][y].rect.topleft[1],10,10))
									else:
										img.blit(m.img[0] , pygame.Rect(m.rect.topleft[0]-self.monde[x][y].rect.topleft[0],m.rect.topleft[1]-self.monde[x][y].rect.topleft[1],10,10))
									self.draw_repair.append( [img , rect.move(self.monde[x][y].dpos), [m.pos[0]-1,m.pos[1]+m.size[1]-1]] )			# die letzte Liste bestimmt nach welchem Feld die Reparatur gezeichnet werden muss
							
		
		## die sich bewegende leute scrollen
		for l in player.leute.leute:
			pos = l.route[0]
			l.dpos[0] = l.dpos[0] + move[0]
			l.dpos[1] = l.dpos[1] + move[1]
			if -416 < l.dpos[0] < (width +416)  and -240 < l.dpos[1] < (height + 240):
				if l.multiframe[0] == 1:
					l.rect = l.img[0].get_rect().move(l.dpos)	
				else:
					l.rect = l.img.get_rect().move(l.dpos)	
					
			## Reparatur für die Leute. Sie werden über die fertige Karte geblittet und müssen daher inter den Häusern "verschwinden"
				
			# wegen der Blit-Vorgänge muss mit einer Kopie des img gearbeitet werden, Sie ist es, die auf das Spielfeldes geblittet wird
			if l.multiframe[0] == 1:
				l.dimg = l.img[0].copy()
			else:
				l.dimg = l.img.copy() 
				
			# gehe die Felder "unter" dem man durch und siche heraus, welche Felder sich mit dem man überlagern müssten
			# es wird in der x-Axis rückwärts gegangen, wegen der Perspektive (ansonsten "Phantombilder")
			for y in range(pos[1] , pos[1]+10):
				for x in range(pos[0]+6 , pos[0]-6,-1):
					#nur wenn die Felder nicht ausserhalb der Karte liegen !!
					if len(self.monde) > x:
						if len(self.monde[x]) > y:
							if (not self.monde[x][y].islink()) and ([x,y] != pos):
								if (self.monde[x][y].typ in self.batiments) or (self.monde[x][y].typ in [4,5]):
									# Die position an der Geblittet wird is definiert durch die Differenz der beiden Bilder, die 10px grösse des Rects sind nur dummy
									if self.monde[x][y].multiframe[0] ==0:
										l.dimg.blit(self.monde[x][y].img , pygame.Rect( (self.monde[x][y].rect[0]-l.rect[0],self.monde[x][y].rect[1]-l.rect[1]) , (10,10)))
									else:
										l.dimg.blit(self.monde[x][y].img[0] , pygame.Rect( (self.monde[x][y].rect[0]-l.rect[0],self.monde[x][y].rect[1]-l.rect[1]) , (10,10)))
	
	
	#		BAUEN 
	#===================================
	#	Im baumodus wird diese Funtion geloopt, Sie erstellt die Bauvorschau und 'baut' das haus letztendlich .. für player.geb siehe main.py 	
	def Bauen(self,b):
		s=[];r=0
		cost=0
		mouse = pygame.mouse.get_pos()
		if self.zoom == 0:
			s = [26,15]
			r=10
		elif self.zoom == 1:
			s = [52,30]
			r=20
		elif self.zoom == 2:
			s = [104,60]
			r=40

		### heraussuchen des aktuellen Felds aus den angezeigten Felder 
		for o in self.draw:
			if o.islink() == False:
				if o.rect.contains(pygame.Rect((mouse[0]-(r/2),mouse[1]-(r/2),r,r))):
				
				
					if (b in self.batiments) or (b == -1):
						if b != -1:
							# bebaubar test
							overlay = []
							if ((o.pos[0] +self.neu[b]["size"][0]) <= self.monde[-1][-1].pos[0]) and ((o.pos[01] + self.neu[b]["size"][1]) <= self.monde[-1][-1].pos[1]): 
								for x in range(o.pos[0] , o.pos[0] + self.neu[b]["size"][0]):		# von position bis position + size
									for y in range(o.pos[1] , o.pos[1] + self.neu[b]["size"][1]):
										# gehe links nach
										if self.monde[x][y].islink() == True:
											#self.monde[ self.monde[x][y].link[0] ][ self.monde[x][y].link[1] ].debug()
											if self.monde[ self.monde[x][y].link[0] ][ self.monde[x][y].link[1] ].bauen == 0:
												overlay.append([x,y])
										# gibt est eine Koordinate, die nicht bebaubar ist, wird ok = False							
										elif self.monde[x][y].bauen == 0:
											overlay.append([x,y])
								del x , y   	# da x und y häufig sind
								
							if len(overlay) == 0:				
								self.bauen = [Case(o.pos[:], self.neu[b]["size"][:], self.neu[b]["datei"][:], b, 1, self.neu)]
								self.bauen[0].npos = o.npos[:]
								self.bauen[0].dpos = self.bauen[0].npos[:]
								self.bauen[0].calc_korrektur(self.get_zoomsize())
								self.bauen[0].do_korrektur()
								#self.bauen[0].debug()
							else:
								self.bauen = []
								for ol in overlay:
									t= self.monde[ol[0]][ol[1]]
									self.bauen.append(Case(t.pos, [1,1],"bild/no_bauen-z"+str(self.zoom)+"-n.png", 0, 1, self.neu))
									self.bauen[-1].dpos = t.npos[:]
									if t.islink() == False:
										self.bauen[-1].dpos[1] = self.bauen[-1].dpos[1] + ((t.size[1]-1)*(self.get_zoomsize()[1]/2)) # korrektur2 aufheben
									self.bauen[-1].rect = self.bauen[-1].img.get_rect().move(self.bauen[-1].dpos)

						
						elif (b==-1) and (pygame.mouse.get_pressed()[0] == True):
							if o.size != [1,1]:
								for x in range(o.pos[0] , o.pos[0] + o.size[0]):		# von position bis position + size
									for y in range(o.pos[1] , o.pos[1] + o.size[1]):
										#if not ((x == o.pos[0]) and (y == o.pos[1])):		# erste koordinate natürlich nicht überschreiben 
										npos = self.monde[x][y].npos
										self.bauen.append( Case(self.monde[x][y].pos,[1,1],self.neu[1]["datei"],1,1,self.neu) )
										self.bauen[-1].rect = self.bauen[-1].img.get_rect().move( self.bauen[-1].npos )
										self.bauen[-1].npos = npos
										self.bauen[-1].dpos = self.bauen[-1].npos[:]
										self.bauen[-1].korr =0
								del x , y   	# da x und y häufig sind	
		
		
		
					if ((b in self.champs) or (b in self.chemins) or (b==-1) ) and (pygame.mouse.get_pressed()[0] == True):
						self.bauen_mouse_state = True
						if o.size == [1,1]:
							obj = self.monde[o.pos[0]][o.pos[1]]		# temp variabel, so das das arbeiten einfacher wird
							if b != -1:
								tmp = Case(obj.pos[:], self.neu[b]["size"][:], self.neu[b]["datei"][:], b, 1, self.neu)
							else:
								tmp = Case(obj.pos[:], [1,1], self.neu[1]["datei"][:], 1, 1, self.neu)
							tmp.npos = obj.npos[:]
							tmp.dpos = obj.npos[:]
							tmp.calc_korrektur(self.get_zoomsize())
							tmp.do_korrektur()											
							
							## erstes Feld markiert begin des zu zeichnenden Feldes 
							if self.bauen == []:		
								self.bauen.append(tmp)  
							## aktuelles Feld markiert ende des Feld Rechtecks	
							if len(self.bauen) == 1:		# überschreibe das erste Feld nicht, wenn das Erste == das Letzte 
								self.bauen.append(tmp) 
							else:
								self.bauen[-1] = tmp
								
							rect = [[],[]]
							## Rechteck erstellen
							if self.bauen[-1].pos[0] - self.bauen[0].pos[0] >= 0:	## x richtung
								rect[0] = range(self.bauen[0].pos[0] , self.bauen[-1].pos[0]+1)
							if self.bauen[-1].pos[0] - self.bauen[0].pos[0] <= 0:	## -x richtung
								rect[0] = range(self.bauen[-1].pos[0] , self.bauen[0].pos[0]+1)
							if self.bauen[-1].pos[1] - self.bauen[0].pos[1] >= 0:	## y richtung
								rect[1] = range(self.bauen[0].pos[1] , self.bauen[-1].pos[1]+1)
							if self.bauen[-1].pos[1] - self.bauen[0].pos[1] <= 0:	## -y richtung
								rect[1] = range(self.bauen[-1].pos[1] , self.bauen[0].pos[1]+1)	
							
							self.bauen = [self.bauen[0],self.bauen[-1]]		# bauen auf Anfang und Ende zurücksetzen
							for i in rect[0]:
								for i2 in rect[1]:	
								
								
									if (b in self.champs) or (b==-1):						
										if (self.monde[i][i2].islink() == False): 
											if (self.monde[i][i2].bauen == 1 ) and (b != -1): #or ((self.monde[i][i2].islink()) and (self.monde[self.monde[i][i2].link[0]][self.monde[i][i2].link[1]].bauen == 1 )):					
												tmp = Case(self.monde[i][i2].pos[:], self.neu[b]["size"][:], self.neu[b]["datei"][:], b, 1, self.neu)
												tmp.npos = self.monde[i][i2].npos[:]
												tmp.dpos = self.monde[i][i2].npos[:]
												tmp.calc_korrektur(self.get_zoomsize())
												tmp.do_korrektur()											
												self.bauen.insert(1,tmp)		# andere Felder zwischen Anfang und Ende !!wichtig!!
															
											if (b == -1) and (self.monde[i][i2].bauen == 1):
				
												tmp = Case(self.monde[i][i2].pos[:], [1,1], self.neu[1]["datei"][:], 1, 1, self.neu)
												
												tmp.npos = self.monde[i][i2].npos[:]
												tmp.dpos = self.monde[i][i2].npos[:]
												tmp.calc_korrektur(self.get_zoomsize())
												tmp.do_korrektur()											
												self.bauen.insert(1,tmp)		# andere Felder zwischen Anfang und Ende !!wichtig!!
											
											
									elif (b in self.chemins):
										#							i=end[0]
										#							 |	
										#							 v		
										#i2=begin[1]	->	b=========
										#i2!=begin[1]	->	        ||
										#i2!=begin[1]	->	        ||
										#		    			    e
										# baue weg nur wenn die aktuelle y koord die des begins  ist (horizontal) oder wenn die aktuelle x variabel die des endes ist (vertikal)
										if (i2 == self.bauen[0].pos[1]) or (i2 != self.bauen[0].pos[1] and i == self.bauen[-1].pos[0]):
											# ist link inexistent und bauen genemigt
											if ((self.monde[i][i2].islink() == False) and (self.monde[i][i2].bauen == 1 )):
												tmp = Case(self.monde[i][i2].pos[:], self.neu[b]["size"][:], self.neu[b]["datei"][:], b, 1, self.neu)
												tmp.npos = self.monde[i][i2].npos[:]
												tmp.dpos = self.monde[i][i2].npos[:]
												tmp.calc_korrektur(self.get_zoomsize())
												tmp.do_korrektur()											
												self.bauen.insert(1,tmp)		# andere Felder zwischen Anfang und Ende !!wichtig!!
						
		
		if (pygame.mouse.get_pressed()[0] == True):
			if (b in self.batiments) or (b==-1):
				if (b in self.batiments):
					self.gebaut = []
					ok = True
					for ba in self.bauen:
						if ba.datei[0:13] == "bild/no_bauen":
							ok = False
							break
				
					if ok == True:
						for ba in self.bauen:
							self.monde[ ba.pos[0] ][ ba.pos[1]] = ba
							self.monde[ ba.pos[0] ][ ba.pos[1]].bauen = 0
							self.gebaut.append( self.monde[ ba.pos[0] ][ ba.pos[1]] )
							
							# baue links für Gebäude		
							for x in range(ba.pos[0] , ba.pos[0] + self.neu[b]["size"][0]):		# von position bis position + size
								for y in range(ba.pos[1] , ba.pos[1] + self.neu[b]["size"][1]):
									if not ((x == ba.pos[0]) and (y == ba.pos[1])):		# erste koordinate natürlich nicht überschreiben (ref)
										npos = self.monde[x][y].npos
										self.monde[x][y] = Case(self.monde[x][y].pos,None,None,None,None,self.neu,ba.pos[:])
										self.monde[x][y].npos = npos
							del x , y   	# da x und y häufig sind	
					self.bauen = []
				elif (b==-1):
					self.gebaut=[]
					for ba in self.bauen:
						self.monde[ ba.pos[0] ][ ba.pos[1]] = ba
						self.gebaut.append( self.monde[ ba.pos[0] ][ ba.pos[1]] )


					
		
										
		if (self.bauen_mouse_state ==True) and (pygame.mouse.get_pressed()[0] == False):				
			if (b in self.champs) or (b in self.chemins) or (b == -1):
			
				for ba in self.bauen:
					self.monde[ ba.pos[0] ][ ba.pos[1]] = ba	
				self.bauen = []
				self.bauen_mouse_state = False
			
				
		self.wege = Wege(self.monde)	
		
							
	#		UPDATE 
	#===================================
	#	lässt farmen produzieren und Häuser konsumieren, ist auch für den Warenaustausch der Gebäude verantwortlich 
	def update(self,players):
		for p in players:
			### Farmen
			for t in [20,23]:
				for g in p.geb[t]:
					p.geb[t][g].ernte(self.monde)
			### Mühlen
			for t in [21,22]:
				for g in p.geb[t]:
					p.geb[t][g].produktion()
			### Häuser
			for t in [10]:
				for g in p.geb[t]:
					p.geb[t][g].konsum()
		
			
			### Waren ver- unda ankauf !!!!
			for t in p.geb:
				for geb in t:
					# nur abholen (Getreidefarm, Forsthaus)
					if (t[geb].typ in [20,23]):
						if t[geb].speicher[ t[geb].prod ] > self.neu[40].get("max_spe"):
							t[geb].verkaufen(p,self)
					# abholen und holen (Müle, Bäcker)
					if (t[geb].typ in [21,22]):
						if t[geb].speicher[ t[geb].prod ] > self.neu[40].get("max_spe"):
							t[geb].verkaufen(p,self)
						if (t[geb].speicher.get(t[geb].reqgut) < 5) and (p.spe.get( t[geb].reqgut ) != None) :
							t[geb].einkaufen(p,self)
					# Einwohner : verbraucher 
					if (t[geb].typ in [10]):
						einkaufen = []
						for  gut in t[geb].verbrauch:
							if (t[geb].speicher[gut] < 3) and (p.spe.get( gut ) != None):
								if (p.spe.get( gut ) > self.neu[41].get("max_spe")):
									einkaufen.append(gut)
							if len(einkaufen) == 1:
								break	
								
						if einkaufen != []:
							t[geb].einkaufen2(p,self,einkaufen)
							
							
	
	#		SPEICHERN 
	#===================================
	#	Speichert Monde UND player in eine Datei 					
	def save(self,filen,players):
		gebkeys = ["pos","prod","prodv","spe","reqfeld"]
		if os.path.exists(filen) == False:
			print "Die Datei " + filen + " exestiert nicht ... sie wird angelegt"
			create_file(filen)
		con = sqlite3.connect(filen)
		con.row_factory = sqlite3.Row
		c= con.cursor()
		
		### Save monde
		c.execute('''delete from monde''')
		con.commit()
		for r in self.monde:
			for e in r:
				if e.islink() == False:
					ins = [ 
					str(e.pos),
					str(e.datei),
					str(e.typ),
					str(e.bauen),
					str(e.size),
					None]		# diese Reienfolge ist wichtig !!!
				else:
					ins = [str(e.pos),None,None,None,None,str(e.link)]		# diese Reienfilge ist wichtig !!!
				c.execute('''insert into monde values(?,?,?,?,?,?)''',ins)
		con.commit()

		## save players
		c.execute('''delete from players''')
		c.execute('''delete from farmen''')
		c.execute('''delete from muehlen''')
		c.execute('''delete from markthauser''')
		c.execute('''delete from hauser''')
		c.execute('''delete from forsthauser''')
		c.execute('''delete from baecker''')
		con.commit()
		for p in players:
			exe = [players.index(p), str(p.name) , p.cash, 0,0,0,str(p.spe)]		# ID , Name , Cash , Population , Ausgaben , Einnahmen, Speicher
			c.execute('''insert into players values(?,?,?,?,?,?,?)''',exe)
			## save gebäude
			for geb_typ in p.geb:
				for obj in geb_typ:
					dic = geb_typ[obj].dump()
					dicstr = {}
					for e in dic:
						dicstr[e] = str(dic[e])
					## Farmen
					if dic["typ"] in [20,23]:
						savlist = [players.index(p),
						dic["typ"],
						obj,
						dicstr["prod"],
						dicstr["prodv"],
						dicstr["spe"],
						dicstr["reqfeld"],
						dicstr["aura"]]
					if dic["typ"] == 20:
						c.execute('''insert into farmen values(?,?,?,?,?,?,?,?)''',savlist)
					if dic["typ"] == 23:
						c.execute('''insert into forsthauser values(?,?,?,?,?,?,?,?)''',savlist)
					## Mühlen
					if dic["typ"] in [21,22]:
						savlist = [players.index(p),
						dic["typ"],
						obj,
						dicstr["prod"],
						dicstr["prodv"],
						dicstr["spe"],
						dicstr["reqgut"],
						dicstr["aura"]]
						if dic["typ"] == 21:
							c.execute('''insert into muehlen values(?,?,?,?,?,?,?,?)''',savlist)
						elif dic["typ"] == 22:
							c.execute('''insert into baecker values(?,?,?,?,?,?,?,?)''',savlist)
					## Markthäuser
					elif dic["typ"] in [15]:
						savlist = [players.index(p),dic["typ"],obj,dicstr["spe"],dicstr["aura"]]
						c.execute('''insert into markthauser values(?,?,?,?,?)''',savlist)
					## Häuser
					elif dic["typ"] in [10]:
						savlist = [players.index(p),dic["typ"],obj,dicstr["spe"],dicstr["aura"],dicstr["verbrauch"],dicstr["zufrieden"],dicstr["stimmung"],dicstr["max_einwohner"],dicstr["einwohner"]]
						c.execute('''insert into hauser values(?,?,?,?,?,?,?,?,?,?)''',savlist)
		con.commit()
		c.close()
		print "Welt in Datei " + filen + " gespeichert"
