#!C:/Python27/python.exe
# -*- coding: utf-8 -*-


import sys , cgi ,cStringIO,socket
from StringIO import StringIO
from PIL import Image
#import multiprocessing as mp
import numpy as np
import xml.etree.ElementTree as ET
import urllib3


def getQuery (server , service, boundingBox , crs , size,
	format,transparency,tiled,wmsVersion,layer,
	layerstyle,cql=""):
	if cql == "":
		return "%s?SERVICE=%s&REQUEST=GetMap&VERSION=%s&FORMAT=%s&TRANSPARENT=%s&LAYERS=%s&STYLES=%s&tiled=%s&WIDTH=%s&HEIGHT=%s&CRS=%s&BBOX=%s,%s,%s,%s" %(server,service,wmsVersion,format,transparency,layer,layerstyle,tiled,size[0],size[1],crs,boundingBox[0],boundingBox[1],boundingBox[2],boundingBox[3])
	else:
		return "%s?SERVICE=%s&REQUEST=GetMap&VERSION=%s&FORMAT=%s&TRANSPARENT=%s&LAYERS=%s&STYLES=%s&tiled=%s&WIDTH=%s&HEIGHT=%s&CRS=%s&BBOX=%s,%s,%s,%s&CQL_FILTER=%s" %(server,service,wmsVersion,format,transparency,layer,layerstyle,tiled,size[0],size[1],crs,boundingBox[0],boundingBox[1],boundingBox[2],boundingBox[3],cql)

def createQuery(form):
	keys = form.keys();
	requete = ""
	for s in keys:
		field = form.getvalue(s);
		query = "%s=%s" %(s,field);
		if "portal" in s:
			requete = "http://%s/geoserver/%s/wms?%s" %(socket.gethostbyname(socket.gethostname()),field,requete)
		else:
			if requete == "":
				requete = "%s" %query
			else:
				requete = "%s&%s" %(requete,query)
	if 'STYLES' not in keys:
		requete = '%s&STYLES=' %requete
	return requete

def setOpacity(layer,CQL,wmsSplitted,querySplitted,
	service, boundingBox , crs , size, format,transparency,tiled,
	wmsVersion,Image_Array , messages , error):

	index = wmsSplitted['LAYERS'].index(layer);	
	if len(wmsSplitted['STYLES']) == 0 :
		layerstyle = "";
	else:
		layerstyle = wmsSplitted['STYLES'][index];

	THECQL = CQL.replace('&','').replace('=','');
	if THECQL in wmsSplitted.keys():
		cql = wmsSplitted[THECQL][index];
	else:
		cql = "";
	query = getQuery(querySplitted[0], service, boundingBox , crs , size, format,transparency,tiled,wmsVersion,layer,layerstyle,cql);
	query = query.replace(' ','%20')
	http = urllib3.PoolManager();
	img = http.request('GET', query).data;
	try:
		image = Image.open(StringIO(img)).convert("RGBA");
		x = np.array(image)
		r, g, b, a = np.rollaxis(x, axis=-1)
		# Opacity traitement
		if 'OPACITY' in wmsSplitted.keys():
			Opacity = float(wmsSplitted['OPACITY'][index]);
			for sel in range(len(a)):
				a[sel] = (a[sel]*float(Opacity)).astype(int);
			x = np.dstack([r, g, b, a])				
			image = Image.fromarray(x , "RGBA")
		
		else:
			Opacity = "";

		Image_Array.append(image);
		return [ Image_Array , messages , error ];
	except:
		error = True;
		messages.append(img);
		Image_Array.append("noLayer");
		return [ Image_Array , messages , error ];
		
		


def treatment(wmsSplitted,CQL,querySplitted,Image_Array):
	if wmsSplitted['REQUEST'] == 'GetMap':
		boundingBox = wmsSplitted['BBOX'];
		crs = wmsSplitted['CRS'];
		size = ( wmsSplitted['WIDTH'] , wmsSplitted['HEIGHT'] );
		format = wmsSplitted['FORMAT'];
		transparency = wmsSplitted['TRANSPARENT'];
                try :
                    tiled = wmsSplitted['tiled'] ;
                except KeyError:
                    tiled = wmsSplitted['TILED'] ;
		wmsVersion = wmsSplitted['VERSION'];
		#tilesorigin = wmsSplitted['tilesorigin'];
		service = wmsSplitted['SERVICE'];
		error = False;
		messages = [];	
		for layer in wmsSplitted['LAYERS']:
			[ Image_Array , messages , error ] = setOpacity(layer,CQL,wmsSplitted,querySplitted,
						service, boundingBox , crs , size, format,transparency,tiled,
						wmsVersion , Image_Array , messages , error)

		if error:
			sys.stdout.write('Content-type: text/plain\n\n')
			for message in messages:
				print message
		else:
			if Image_Array[0] != "noLayer":
				image_Final = Image_Array[0];

			index = 1 ;
			while index < len(Image_Array):
				if Image_Array[index-1] != "noLayer" and Image_Array[index] != "noLayer":
					image_Final = Image.alpha_composite(image_Final , Image_Array[index]);
				else:
					if Image_Array[index] != "noLayer":
						image_Final = Image_Array[index];
				index += 1;

			f = cStringIO.StringIO()
			image_Final.save(f, 'png')
			f.seek(0)
			# Renvoie du png
			sys.stdout.write('Content-type: image/png\n\n')
			sys.stdout.write(f.getvalue())
			
def maing2c(form):
	
	CQL = "&CQL_FILTER="
	if sys.platform == "win32":
		import os, msvcrt
		# sinon \n (0x0A) est transformé en \rn (0xOD 0x0A)
		msvcrt.setmode(1,os.O_BINARY)
	requete = createQuery(form);
	if 'OPACITY' in requete or CQL in requete :
		querySplitted = requete.split("?");
		part2 = querySplitted[1];
		Arraydata = part2.split("&");
		wmsSplitted = {};
		for n in Arraydata :
			if "=" not in n :
				n = "%s=" %n;
			ArraySplit = n.split("=",1);
			Array = ArraySplit[1].split(",");
			if len(Array) > 1 or ArraySplit[0] == 'LAYERS' or ArraySplit[0] == 'STYLES' or ArraySplit[0] in CQL or ArraySplit[0] == 'OPACITY':
				wmsSplitted[ArraySplit[0]] = Array;		
			else :
				wmsSplitted[ArraySplit[0]] = ArraySplit[1];
		Image_Array = [];
		treatment(wmsSplitted,CQL,querySplitted,Image_Array);
	else:
		http = urllib3.PoolManager()
		# Renvoie du png
		requete =  requete.replace('&STYLES&','&STYLES=&')
		reponse = http.request('GET', requete).data;
		try:
                        sys.stdout.write('Content-type: image/png\n\n')
			sys.stdout.write(reponse);
		except:
			sys.stdout.write('Content-type: text/html\n\n')
			print img;

if __name__ == "__main__":
	form = cgi.FieldStorage();
	#try:
	#sys.stdout.write('Content-type: text/plain\n\n')
	maing2c(form);
	#except:
	#	sys.stdout.write('Content-type: image/png\n\n')