import numpy as N
import re
import sys
import os
from uncertainties import ufloat
from uncertainties.umath import * 

def process_raw_results(rawfile, savedir,rho_mirror):
	"""
	rawfile - the 'simul' file that generated by SOLSTICE
	savedir - the directy for saving the organised results
	"""

	# FIXME this approach seems fundamentally a bit messy... we are carefully
	# load the text output from 'solppraw' and then assuming that we can
	# correctly find the right bits of data in the right place. Wouldn't it
	# be easier and more robust to modify solppraw to create output that can
	# be directly loaded, along with data labels, eg a YAML file? Or to
	# create 'result-raw.csv' directly?

	rows = []
	index = 0
	with open(rawfile) as f:
		for r in f.readlines():
			if index<20:
				pass #sys.stderr.write("Line %d: %s"%(index,r))

			if r[0] == "#":
				#sys.stderr.write("^------Comment\n")
				#comment line
				rows.append([r])
			else:
				rows.append(r.split())			
			index+=1

	results=N.array([])

	# sun direction

	#sys.stderr.write("SUN DIRECTION?\n")
	#sys.stderr.write(rows[0][0]+"\n")
	sun=re.findall("[-+]?\d*\.\d+|\d+", rows[0][0])
	#sys.stderr.write("SUN = %s\n"%(repr(sun),))

	azimuth=sun[0]
	elevation=sun[1]

	def get_rc(row,col):
		return float(rows[row][col])

	# Global results

	num_res=int(get_rc(1,0)) # number of global results
	num_rec=int(get_rc(1,1))
	num_hst=get_rc(1,2)
	num_rays=get_rc(1,3)

	potential=get_rc(2,0) #W
	potential_err=get_rc(2,1)

	absorbed=get_rc(3,0)
	absorbed_err=get_rc(3,1)    

	Fcos=get_rc(4,0)
	Fcos_err=get_rc(4,1)  

	shadow_loss=get_rc(5,0)
	shadow_err=get_rc(5,1)    

	missing_loss=get_rc(6,0)
	missing_err=get_rc(6,1) 

	material_loss=get_rc(7,0)
	material_err=get_rc(7,1)    

	atmospheric_loss=get_rc(8,0)
	atmospheric_err=get_rc(8,1)  

	# Target (receiver)
	# 0 receiver name
	# 1 - 2 id and area
	# 3 - 24 (total 22) front
	# 25- 46 (total 22) back 
	rec_area=get_rc(num_res+2,2) # m2  
	
	rec_front_income=get_rc(num_res+2,3)
	rec_front_income_err=get_rc(num_res+2,4)
	#rec_no_material_loss=get_rc(num_res+2,5)
	#rec_no_material_loss_err=get_rc(num_res+2,6)
	#rec_no_atmo_loss=get_rc(num_res+2,7)
	#rec_no_atmo_loss_err=get_rc(num_res+2,8)
	#rec_material_loss=get_rc(num_res+2,9)
	#rec_material_loss_err=get_rc(num_res+2,10)
	rec_front_absorbed=get_rc(num_res+2,13)
	rec_front_absorbed_err=get_rc(num_res+2,14)
	rec_front_eff=get_rc(num_res+2,23)
	rec_front_eff_err=get_rc(num_res+2,24)

	rec_back_income=get_rc(num_res+2,25)
	rec_back_income_err=get_rc(num_res+2,26)
	rec_back_absorbed=get_rc(num_res+2,35)
	rec_back_absorbed_err=get_rc(num_res+2,36)
	rec_back_eff=get_rc(num_res+2,-2)
	rec_back_eff_err=get_rc(num_res+2,-1)

	if num_rec>1:
		#Virtual target
		vir_area=get_rc(num_res+3,2)
		vir_income=get_rc(num_res+3,3)
		vir_income_err=get_rc(num_res+3,4)
	
	raw_res=N.array([
		['name','value', 'error']
		,['sun_azimuth', azimuth,'']
		,['sun_elevation', elevation, '']
		,['num hst', num_hst,'']
		,['num rays',num_rays, '']
		,['potential flux', potential, potential_err]
		,['absorbed flux', absorbed, absorbed_err]
		,['Cosine factor', Fcos, Fcos_err]
		,['shadow loss', shadow_loss, shadow_err]
		,['Mising loss', missing_loss, missing_err]
		,['materials loss', material_loss, material_err]
		,['atomospheric loss', atmospheric_loss, atmospheric_err]
		,['','','']
		,['Target', '','']
		,['area', rec_area, '']
		,['front income flux', rec_front_income, rec_front_income_err]
		,['back income flux', rec_back_income, rec_back_income_err]
		,['front absorbed flux', rec_front_absorbed, rec_front_absorbed_err]
		,['back absorbed flux', rec_back_absorbed, rec_back_absorbed_err]
		,['front efficiency', rec_front_eff, rec_front_eff_err]
		,['back efficiency', rec_back_eff, rec_back_eff_err]
		,['','','']
		,['Virtual plane','','']
		,['area', vir_area, '']
		,['income flux', vir_income,vir_income_err]
	])

	#sys.stderr.write(repr(raw_res))
	#sys.stderr.write("SHAPE = %s" % (repr(raw_res.shape)))

	N.savetxt(savedir+'/result-raw.csv', raw_res, fmt='%s', delimiter=',')

	Qtotal=ufloat(potential, 0)
	Fcos=ufloat(Fcos,Fcos_err) 
	Qcos=Qtotal*(1.-Fcos)
	Qshade=ufloat(shadow_loss,shadow_err)
	Qfield_abs=(Qtotal-Qcos-Qshade)*(1.-float(rho_mirror))
	Qatm=ufloat(atmospheric_loss, atmospheric_err)
	Qspil=ufloat(vir_income,vir_income_err)
	Qabs=ufloat(absorbed, absorbed_err)
	Qrefl=ufloat(rec_front_income,rec_front_income_err)+ufloat(rec_back_income,rec_back_income_err)-Qabs
	Qblock=Qtotal-Qcos-Qshade-Qfield_abs-Qspil-Qabs-Qrefl-Qatm

	organised=N.array([
		'Name', 'Value', '+/-Error', 
		'Qall (kW)', Qtotal.n/1000., Qtotal.s/1000., 
		'Qcos (kW)', Qcos.n/1000.,Qcos.s/1000.,
		'Qshad (kW)', Qshade.n/1000., Qshade.s/1000.,
		'Qfield_abs (kW)', Qfield_abs.n/1000., Qfield_abs.s/1000., 
		'Qblcok (kW)', Qblock.n/1000.,  Qblock.s/1000., 
		'Qatm (kW)',Qatm.n/1000., Qatm.s/1000., 
		'Qspil (kW)', Qspil.n/1000., Qspil.s/1000., 
		'Qrefl (kW)', Qrefl.n/1000.,Qrefl.s/1000., 
		'Qabs (kW)', Qabs.n/1000., Qabs.s/1000., 
		'rays', num_rays,'-'
	])
	N.savetxt(savedir+'/result-formatted.csv', organised.reshape(len(organised)/3,3), fmt='%s', delimiter=',')
	efficiency_total=Qabs/Qtotal

	return efficiency_total

if __name__=='__main__':
	eta = proces_raw_results(sys.argv[1], sys.argv[2], sys.argv[3])
	sys.stderr.write('\nTotal efficiency: %s\n'%(repr(eta),))


