from math import isnan
import numpy as npy

def processdata(md,data,options):
	"""
	PROCESSDATA - process data to be plotted

		datatype = 1 -> elements
		datatype = 2 -> nodes
		datatype = 3 -> node quivers
		datatype = 4 -> patch

		Usage:
			data,datatype=processdata(md,data,options);

		See also: PLOTMODEL, PROCESSMESH
	"""

	#check format
	if (len(data)==0 or (len(data)==1 and not isinstance(data,dict) and isnan(data).all())):
		raise ValueError("processdata error message: 'data' provided is empty")

	#needed later on
	if 'numberofvertices2d' in dir(md.mesh):
		numberofvertices2d=md.mesh.numberofvertices2d
		numberofelements2d=md.mesh.numberofelements2d
	else:
		numberofvertices2d=npy.nan
		numberofelements2d=npy.nan

	procdata=npy.copy(data)

	#process patch

	#initialize datatype
	datatype=0

	#get datasize
	if npy.ndim(procdata)==1:
		datasize=npy.array([len(procdata),1])
	else:
		datasize=npy.shape(procdata)
	
	#process NaN's if any
	nanfill=options.getfieldvalue('nan',-9999)
	if npy.any(npy.isnan(procdata)):
		lb=npy.min(data[~npy.isnan(data)])
		ub=npy.max(data[~npy.isnan(data)])
		if lb==ub:
			lb=lb-0.5
			ub=ub+0.5
			nanfill=lb-1
		procdata[npy.isnan(procdata)]=nanfill
		options.addfielddefault('clim',[lb,ub])
		options.addfielddefault('cmap_set_under','1')
		print "WARNING: nan's treated as", nanfill, "by default.  Change using pairoption 'nan',nan_fill_value in plotmodel call"

	#non-patch processing 

	#element data
	if datasize[0]==md.mesh.numberofelements and datasize[1]==1:
		
		#initialize datatype if non patch
		if datatype!=4 and datatype!=5:
			datatype=1

		#mask?

		#log?

	#node data
	if datasize[0]==md.mesh.numberofvertices and datasize[1]==1:
		datatype=2

		#mask?

		#log?

	#layer projection?

	#control arrow density if quiver plot

	#convert rank-2 array to rank-1
	if npy.ndim(procdata)==2 and npy.shape(procdata)[1]==1:
		procdata=procdata.reshape(-1,)

	#if datatype is still zero, error out
	if datatype==0:
		raise ValueError("processdata error: data provided not recognized or not supported")
	else:
		return procdata, datatype
