import numpy as np
from fielddisplay import fielddisplay
from checkfield import checkfield
from WriteData import WriteData
from isnans import isnans
import MatlabFuncs as m

class rifts(object):
	"""
	RIFTS class definition

	   Usage:
	      rifts=rifts();
	"""

	def __init__(self): # {{{
		self.riftstruct     = []
		self.riftproperties = []

		#set defaults
		self.setdefaultparameters()

		#}}}
	def __repr__(self): # {{{
		string='   rifts parameters:'

		string="%s\n%s"%(string,fielddisplay(self,'riftstruct','structure containing all rift information (vertices coordinates, segments, type of melange, ...)'))
		string="%s\n%s"%(string,fielddisplay(self,'riftproperties',''))
		return string
		#}}}
	def setdefaultparameters(self): # {{{
		return self
	#}}}
	def checkconsistency(self,md,solution,analyses):    # {{{
		if (not self.riftstruct) or np.any(isnans(self.riftstruct)):
			numrifts=0
		else:
			numrifts=len(self.riftstruct)

		if numrifts:
			if not m.strcmp(md.mesh.domaintype(),'2Dhorizontal'):
				md.checkmessage("models with rifts are only supported in 2d for now!")
			if not isinstance(self.riftstruct,list):
				md.checkmessage("rifts.riftstruct should be a structure!")
			if np.any(md.mesh.segmentmarkers>=2):
				#We have segments with rift markers, but no rift structure!
				md.checkmessage("model should be processed for rifts (run meshprocessrifts)!")
			for i,rift in enumerate(self.riftstruct):
				md = checkfield(md,'fieldname',"rifts.riftstruct[%d]['fill']" % i,'values',['Water','Air','Ice','Melange',0,1,2,3])
		else:
			if self.riftstruct and np.any(np.logical_not(isnans(self.riftstruct))):
				md.checkmessage("riftstruct should be NaN since numrifts is 0!")

		return md
	# }}}
	def marshall(self,prefix,md,fid):    # {{{

		#Process rift info
		if (not self.riftstruct) or np.any(isnans(self.riftstruct)):
			numrifts=0
		else:
			numrifts=len(self.riftstruct)

		numpairs=0
		for rift in self.riftstruct:
			numpairs+=np.size(rift['penaltypairs'],axis=0)

		# Convert strings in riftstruct to hard coded numbers
		FillDict={'Air':0,
							'Ice':1,
							'Melange':2,
							'Water':3}
		for rift in self.riftstruct:
			if rift['fill'] in ['Air','Ice','Melange','Water']:
				rift['fill'] = FillDict[rift['fill']]

		# 2 for nodes + 2 for elements+ 2 for  normals + 1 for length + 1 for fill + 1 for friction + 1 for fraction + 1 for fractionincrement + 1 for state.
		data=np.zeros((numpairs,12))
		count=0
		for rift in self.riftstruct:
			numpairsforthisrift=np.size(rift['penaltypairs'],0)
			data[count:count+numpairsforthisrift,0:7]=rift['penaltypairs']
			data[count:count+numpairsforthisrift,7]=rift['fill']
			data[count:count+numpairsforthisrift,8]=rift['friction']
			data[count:count+numpairsforthisrift,9]=rift['fraction']
			data[count:count+numpairsforthisrift,10]=rift['fractionincrement']
			data[count:count+numpairsforthisrift,11]=rift['state'].reshape(-1)
			count+=numpairsforthisrift

		WriteData(fid,prefix,'data',numrifts,'name','md.rifts.numrifts','format','Integer')
		WriteData(fid,prefix,'data',data,'name','md.rifts.riftstruct','format','DoubleMat','mattype',3)
	# }}}
