/*! \file Seg.h 
 *  \brief: header file for seg object
 */

#ifndef _SEG_H_
#define _SEG_H_

/*Headers:*/
/*{{{*/
#include "./Element.h"
#include "./ElementHook.h"
#include "./SegRef.h"
class Parameters;
class Inputs;
class IoModel;
class Results;
class Node;
class Material;
class Matpar;
class ElementMatrix;
class ElementVector;
class Vertex;

#include "../../shared/Exceptions/exceptions.h"
#include "../../shared/Enum/Enum.h"
/*}}}*/

class Seg: public Element,public ElementHook,public SegRef{

	public:

		/*Seg constructors, destructors {{{*/
		Seg(){};
		Seg(int seg_id,int seg_sid,int i, IoModel* iomodel,int nummodels);
		~Seg();
		/*}}}*/
		/*Object virtual functions definitions:{{{ */
		int     ObjectEnum();
		Object *copy();
		/*}}}*/
		/*Update virtual functions resolution: {{{*/
		void  InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int inputenum){_error_("not implemented yet");};
		void  InputUpdateFromSolutionOneDof(IssmDouble* solution,int inputenum){_error_("not implemented yet");};
		void  InputUpdateFromVector(IssmDouble* vector, int name, int type){_error_("not implemented yet");};
#ifdef _HAVE_DAKOTA_
		void  InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){_error_("not implemented yet");};
		void  InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type){_error_("not implemented yet");};
#endif
		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
		/*}}}*/
		/*Element virtual functions definitions: {{{*/
		void        AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum){_error_("not implemented yet");};
		void        AddInput(int input_enum, IssmDouble* values, int interpolation_enum){_error_("not implemented yet");};
		IssmDouble  CharacteristicLength(void);
		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b){_error_("not implemented yet");};
		void        ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
		void        ComputeStressTensor(){_error_("not implemented yet");};
		void        Configure(Elements* elements,Loads* loads,Nodes* nodesin,Vertices* verticesin,Materials* materials,Parameters* parameters){_error_("not implemented yet");};
		void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters){_error_("not implemented yet");};
		void        Delta18oParameterization(void){_error_("not implemented yet");};
		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");};
		int         FiniteElement(void);
		Element*    GetUpperElement(void){_error_("not implemented yet");};
	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
		Element*    GetBasalElement(void){_error_("not implemented yet");};
		int         GetNodeIndex(Node* node){_error_("not implemented yet");};
		int         GetNumberOfNodes(void);
		int         GetNumberOfVertices(void);
		void        GetVerticesCoordinates(IssmDouble** pxyz_list);
		void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list){_error_("not implemented yet");};
		void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list){_error_("not implemented yet");};
		bool        IsOnBed(){_error_("not implemented yet");};
		bool        IsOnSurface(){_error_("not implemented yet");};
		bool        IsNodeOnShelfFromFlags(IssmDouble* flags){_error_("not implemented yet");};
		void        JacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
		void        JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
		void        JacobianDeterminantSurface(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
		void        JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){_error_("not implemented yet");};
		void        JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){_error_("not implemented yet");};
		IssmDouble  MinEdgeLength(IssmDouble* xyz_list){_error_("not implemented yet");};
		void        NodalFunctions(IssmDouble* basis,Gauss* gauss);
		void        NodalFunctionsP1(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
		void        NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
		void        NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
		void        NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
		void        NormalTop(IssmDouble* normal,IssmDouble* xyz_list){_error_("not implemented yet");};
		void        NormalBase(IssmDouble* normal,IssmDouble* xyz_list){_error_("not implemented yet");};
		int         NumberofNodesVelocity(void){_error_("not implemented yet");};
		int         NumberofNodesPressure(void){_error_("not implemented yet");};
	   Element*    SpawnBasalElement(void){_error_("not implemented yet");};
		Element*    SpawnTopElement(void){_error_("not implemented yet");};
		IssmDouble  StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){_error_("not implemented yet");};
		int         PressureInterpolation(void){_error_("not implemented yet");};
		void        ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){_error_("not implemented yet");};
		void        ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
		int         VelocityInterpolation(void){_error_("not implemented yet");};
		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating){_error_("not implemented yet");};
		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list){_error_("not implemented yet");};
		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
		Node*       GetNode(int node_number){_error_("Not implemented");};
		IssmDouble  GetXcoord(Gauss* gauss){_error_("Not implemented");};
		IssmDouble  GetYcoord(Gauss* gauss){_error_("Not implemented");};
		IssmDouble  GetZcoord(Gauss* gauss){_error_("not implemented yet");};
		int         GetElementType(void){_error_("not implemented yet");};
		Gauss*      NewGauss(void);
		Gauss*      NewGauss(int order);
      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order);
      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){_error_("not implemented yet");};
      Gauss*      NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){_error_("not implemented yet");};
		Gauss*      NewGaussBase(int order){_error_("not implemented yet");};
		Gauss*      NewGaussLine(int vertex1,int vertex2,int order){_error_("not implemented yet");};
		Gauss*      NewGaussTop(int order){_error_("not implemented yet");};
		int         VertexConnectivity(int vertexindex){_error_("not implemented yet");};
		void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
		void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
		bool        IsZeroLevelset(int levelset_enum){_error_("not implemented");};
		bool		   IsIcefront(void);
		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};
		void		   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
		void        GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};

		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type){_error_("not implemented yet");};
		void        GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum){_error_("not implemented yet");};
		void        InputDepthAverageAtBase(int enum_type,int average_enum_type){_error_("not implemented yet");};
		void        InputDuplicate(int original_enum,int new_enum){_error_("not implemented yet");};
		void        InputScale(int enum_type,IssmDouble scale_factor){_error_("not implemented yet");};
		void        MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
		int         NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){_error_("not implemented yet");};
		void        PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){_error_("not implemented yet");};
		void        ResetFSBasalBoundaryCondition(void){_error_("not implemented yet");};
		void        ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){_error_("not implemented yet");};
		void        SetTemporaryElementType(int element_type_in){_error_("not implemented yet");};
		void	      SmbGradients(){_error_("not implemented yet");};
		IssmDouble  SurfaceArea(void){_error_("not implemented yet");};
		void        Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finitelement){_error_("not implemented yet");};
		IssmDouble  TimeAdapt(){_error_("not implemented yet");};
		void UpdateConstraintsExtrudeFromBase(){_error_("not implemented");};
		void UpdateConstraintsExtrudeFromTop(){_error_("not implemented");};

		void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){_error_("not implemented yet");};
		IssmDouble IceVolume(void){_error_("not implemented yet");};
		IssmDouble IceVolumeAboveFloatation(void){_error_("not implemented yet");};
		IssmDouble TotalSmb(void){_error_("not implemented yet");};
		void       MinVel(IssmDouble* pminvel){_error_("not implemented yet");};
		void       MinVx(IssmDouble* pminvx){_error_("not implemented yet");};
		void       MinVy(IssmDouble* pminvy){_error_("not implemented yet");};
		void       MinVz(IssmDouble* pminvz){_error_("not implemented yet");};
		IssmDouble MassFlux(IssmDouble* segment){_error_("not implemented yet");};
		IssmDouble MassFlux(IssmDouble x1,IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){_error_("not implemented yet");}
		void       MaxAbsVx(IssmDouble* pmaxabsvx){_error_("not implemented yet");};
		void       MaxAbsVy(IssmDouble* pmaxabsvy){_error_("not implemented yet");};
		void       MaxAbsVz(IssmDouble* pmaxabsvz){_error_("not implemented yet");};
		void       ElementResponse(IssmDouble* presponse,int response_enum){_error_("not implemented yet");};
		void       MaxVel(IssmDouble* pmaxvel){_error_("not implemented yet");};
		void       MaxVx(IssmDouble* pmaxvx){_error_("not implemented yet");};
		void       MaxVy(IssmDouble* pmaxvy){_error_("not implemented yet");};
		void       MaxVz(IssmDouble* pmaxvz){_error_("not implemented yet");};
		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum){_error_("not implemented yet");};
		IssmDouble MisfitArea(int weightsenum){_error_("not implemented yet");};

#ifdef _HAVE_GIA_
		void   GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x,IssmDouble* y){_error_("not implemented yet");};
#endif

		IssmDouble DragCoefficientAbsGradient(void){_error_("not implemented yet");};
		void       GradientIndexing(int* indexing,int control_index){_error_("not implemented yet");};
		void       Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){_error_("not implemented yet");};
		void       GradjBGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjBSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDragFS(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjDhDtBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjVxBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjVyBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GradjThicknessBalancethicknessSoft(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
		void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");};
		void       SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){_error_("not implemented yet");};
		void       ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){_error_("not implemented yet");};
		void       ControlInputScaleGradient(int enum_type,IssmDouble scale){_error_("not implemented yet");};
		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){_error_("not implemented yet");};
		void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){_error_("not implemented yet");};
		IssmDouble RheologyBbarAbsGradient(void){_error_("not implemented yet");};
		IssmDouble ThicknessAbsMisfit(void){_error_("not implemented yet");};
		IssmDouble SurfaceAbsVelMisfit(void){_error_("not implemented yet");};
		IssmDouble ThicknessAbsGradient(void){_error_("not implemented yet");};
		IssmDouble ThicknessAlongGradient(void){_error_("not implemented yet");};
		IssmDouble ThicknessAcrossGradient(void){_error_("not implemented yet");};
		IssmDouble BalancethicknessMisfit(void){_error_("not implemented yet");};
		IssmDouble SurfaceRelVelMisfit(void){_error_("not implemented yet");};
		IssmDouble SurfaceLogVelMisfit(void){_error_("not implemented yet");};
		IssmDouble SurfaceLogVxVyMisfit(void){_error_("not implemented yet");};
		IssmDouble SurfaceAverageVelMisfit(void){_error_("not implemented yet");};
		void       InputControlUpdate(IssmDouble scalar,bool save_parameter){_error_("not implemented yet");};

		void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
		void   MigrateGroundingLine(IssmDouble* sheet_ungrounding){_error_("not implemented yet");};
		int    UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){_error_("not implemented yet");};
		/*}}}*/
};
#endif  /* _SEG_H */
