#!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,wmsVersion,layer,
	layerstyle,cql=""):
	if cql == "":
		return "%s?SERVICE=%s&REQUEST=GetMap&VERSION=%s&FORMAT=%s&TRANSPARENT=%s&LAYERS=%s&STYLES=%s&WIDTH=%s&HEIGHT=%s&CRS=%s&BBOX=%s" %(server,service,wmsVersion,format,transparency,layer,layerstyle,size[0],size[1],crs,boundingBox)
	else:
		return "%s?SERVICE=%s&REQUEST=GetMap&VERSION=%s&FORMAT=%s&TRANSPARENT=%s&LAYERS=%s&STYLES=%s&WIDTH=%s&HEIGHT=%s&CRS=%s&BBOX=%s&CQL_FILTER=%s" %(server,service,wmsVersion,format,transparency,layer,layerstyle,size[0],size[1],crs,boundingBox,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,form,
        service, boundingBox , crs , size, format,transparency,
	wmsVersion,Image_Array , messages , error):
        
	index = form.getvalue('LAYERS').index(layer);
	if len(form.getvalue('STYLES')) == 0 :
		layerstyle = "";
	else:
		layerstyle = form.getvalue('STYLES')[index];

	if CQL in form.keys():
		cql = form.getvalue(CQL)[index];
	else:
		cql = "";
        
        header = "http://%s/geoserver/%s/wms" %(socket.gethostbyname(socket.gethostname()),form.getvalue('portal')); 
        
	query = getQuery(header, service, boundingBox , crs , size, format,transparency,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 form.keys():
			Opacity = float(form.getvalue('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(form,CQL,Image_Array):
	if form.getvalue('REQUEST') == 'GetMap':
            
		boundingBox = form.getvalue('BBOX');
		crs = form.getvalue('CRS');
		size = ( form.getvalue('WIDTH') , form.getvalue('HEIGHT') );
		format = form.getvalue('FORMAT');
		transparency = form.getvalue('TRANSPARENT');
		wmsVersion = form.getvalue('VERSION');
		service = form.getvalue('SERVICE');
                
                form['LAYERS'].value = form.getvalue('LAYERS').split(',');
                
                if 'STYLES' in form.keys():
                    form['STYLES'].value = form.getvalue('STYLES').split(',');
                    
                if 'OPACITY' in form.keys():
                    form['OPACITY'].value = form.getvalue('OPACITY').split(',');
                
                cql = CQL.replace('&','').replace('=','');
                if cql in form.keys():
                    form[cql].value = form.getvalue(cql).split(';');
                    
		error = False;
		messages = [];	
		for layer in form.getvalue('LAYERS'):                     
			[ Image_Array , messages , error ] = setOpacity(layer,cql,form,
						service, boundingBox , crs , size, format,transparency,
						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)
                
	if 'OPACITY' in form.keys() or CQL in form.keys() : 
		Image_Array = [];
		treatment(form,CQL,Image_Array);
	else:
		http = urllib3.PoolManager()
		# Renvoie du png
                requete = createQuery(form);
		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/html\n\n')
	maing2c(form);
	#except:
	#	sys.stdout.write('Content-type: image/png\n\n')