/*!\file Riftfront.h
 * \brief: header file for riftfront object
 */

#ifndef _RIFTFRONT_H_
#define _RIFTFRONT_H_

/*Headers:*/
/*{{{*/
#include "./Load.h"
class Hook;
class Parameters;
class Inputs;
class IoModel;
/*}}}*/

class Riftfront: public Load {

	public:
		int		id;
		int     analysis_type;

		/*hooks: */
		Hook* hnodes;
		Hook* helements;
		Hook* hmatpar;
		
		/*Corresponding fields*/
		Matpar   *matpar;
		Node    **nodes;
		Element **elements;

		/*computational: */
		int      penalty_lock;
		bool     active;
		bool     frozen;
		int      counter;
		bool     prestable;
		bool     material_converged;
		IssmDouble   normal[2];
		IssmDouble   length;
		IssmDouble   fraction;
		int      state;
		
		Parameters* parameters; //pointer to solution parameters
		Inputs*  inputs;


		/*Riftfrontconstructors,destructors: {{{*/
		Riftfront();
		Riftfront(int riftfront_id,int i, IoModel* iomodel,int analysis_type);
		~Riftfront();
		/*}}}*/
		/*Object virtual functions definitions:{{{ */
		void  Echo();
		void  DeepEcho();
		int   Id(); 
		int   MyRank();
		int   ObjectEnum();
		Object* copy();
		/*}}}*/
		/*Update virtual functions resolution: {{{*/
		void    InputUpdateFromVector(IssmDouble* vector, int name, int type);
		void    InputUpdateFromVector(int* vector, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromVector(bool* vector, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows,int ncols, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromVectorDakota(int* vector, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromVectorDakota(bool* vector, int name, int type){_error2_("Not implemented yet!");}
		void    InputUpdateFromConstant(IssmDouble constant, int name);
		void    InputUpdateFromConstant(int constant, int name){_error2_("Not implemented yet!");}
		void    InputUpdateFromConstant(bool constant, int name);
		void    InputUpdateFromSolution(IssmDouble* solution){_error2_("Not implemented yet!");}
		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error2_("not implemented yet");};
		/*}}}*/
		/*Load virtual functions definitions: {{{*/
		void  Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
		void  SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
		void  CreateKMatrix(Matrix* Kff, Matrix* Kfs);
		void  CreatePVector(Vector* pf);
		void  CreateJacobianMatrix(Matrix* Jff){_error2_("Not implemented yet");};
		void  PenaltyCreateJacobianMatrix(Matrix* Jff,IssmDouble kmax){_error2_("Not implemented yet");};
		void  PenaltyCreateKMatrix(Matrix* Kff, Matrix* kfs, IssmDouble kmax);
		void  PenaltyCreatePVector(Vector* pf, IssmDouble kmax);
		bool  InAnalysis(int analysis_type);
		/*}}}*/
		/*Riftfront specific routines: {{{*/
		bool  PreStable();
		ElementMatrix* PenaltyCreateKMatrixDiagnosticHoriz(IssmDouble kmax);
		ElementVector* PenaltyCreatePVectorDiagnosticHoriz(IssmDouble kmax);
		void  SetPreStable();
		int   PreConstrain(int* punstable);
		int   Constrain(int* punstable);
		void  FreezeConstraints(void);
		bool  IsFrozen(void);
		int   Penetration(IssmDouble* ppenetration);
		int   MaxPenetration(IssmDouble* ppenetration);
		int   PotentialUnstableConstraint(int* punstable);
		int   IsMaterialStable(void);
		bool  IsInput(int name);
		/*}}}*/
};

#endif  /* _RIFTFRONT_H_ */
