/*!\file:  Input.h
 * \brief abstract class for Input object
 */ 

#ifndef _INPUT_H_
#define _INPUT_H_

/*Headers:*/
/*{{{*/
#include "../../datastructures/datastructures.h"
#include "../../shared/shared.h"
class Node;
class ElementResult;
class GaussTria;
class Parameters;
class GaussPenta;
template <class doubletype> class Vector;
/*}}}*/

class Input: public Object{

	public: 

		virtual        ~Input(){};

		virtual int  InstanceEnum()=0; 
		virtual void GetInputValue(bool* pvalue)=0;
		virtual void GetInputValue(int* pvalue)=0;
		virtual void GetInputValue(IssmDouble* pvalue)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index)=0;
		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int index)=0;
		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss)=0;
		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void GetInputAverage(IssmDouble* pvalue)=0;
		virtual void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes)=0;
		virtual void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime)=0;
		virtual void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss)=0;
		virtual void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss)=0;
		virtual void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss)=0;
		virtual void ChangeEnum(int newenumtype)=0;
		virtual void Configure(Parameters* parameters)=0;

		virtual void   SquareMin(IssmDouble* psquaremin,Parameters* parameters)=0;
		virtual void   ConstrainMin(IssmDouble minimum)=0;
		virtual IssmDouble InfinityNorm(void)=0;
		virtual IssmDouble MaxAbs(void)=0;
		virtual IssmDouble MinAbs(void)=0;
		virtual IssmDouble Max(void)=0;
		virtual IssmDouble Min(void)=0;
		virtual void   Scale(IssmDouble scale_factor)=0;
		virtual void   ArtificialNoise(IssmDouble min,IssmDouble max)=0;
		virtual void   AXPY(Input* xinput,IssmDouble scalar)=0;
		virtual void   Constrain(IssmDouble cm_min, IssmDouble cm_max)=0;
		virtual void   VerticallyIntegrate(Input* thickness_input)=0;
		virtual void   Extrude()=0;
		virtual void   GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist)=0;

		virtual Input* SpawnTriaInput(int location)=0;
		virtual Input* PointwiseDivide(Input* inputB)=0;
		virtual Input* PointwiseMax(Input* inputmax)=0;
		virtual Input* PointwiseMin(Input* inputmin)=0;
		virtual ElementResult* SpawnResult(int step, IssmDouble time)=0;
};
#endif
