/*!\file SegInput.c
 * \brief: implementation of the SegInput object
 */

#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include "../classes.h"
#include "../../shared/shared.h"

/*SegInput constructors and destructor*/
/*FUNCTION SegInput::SegInput(){{{*/
SegInput::SegInput(){
	values = NULL;
}
/*}}}*/
/*FUNCTION SegInput::SegInput(int in_enum_type,IssmDouble* invalues,element_type_in){{{*/
SegInput::SegInput(int in_enum_type,IssmDouble* in_values,int element_type_in)
	:SegRef(1)
{

	/*Set SegRef*/
	this->SetElementType(element_type_in,0);
	this->element_type=element_type_in;

	/*Set Enum*/
	enum_type=in_enum_type;

	/*Set values*/
	this->values=xNew<IssmDouble>(this->NumberofNodes());
	for(int i=0;i<this->NumberofNodes();i++) values[i]=in_values[i];
}
/*}}}*/
/*FUNCTION SegInput::~SegInput(){{{*/
SegInput::~SegInput(){
	xDelete<IssmDouble>(this->values);
}
/*}}}*/

/*Object virtual functions definitions:*/
/*FUNCTION SegInput::Echo {{{*/
void SegInput::Echo(void){
	this->DeepEcho();
}
/*}}}*/
/*FUNCTION SegInput::DeepEcho{{{*/
void SegInput::DeepEcho(void){

	_printf_(setw(15)<<"   SegInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" [");
	for(int i=0;i<this->NumberofNodes();i++) _printf_(" "<<this->values[i]);
	_printf_("]\n");
}
/*}}}*/
/*FUNCTION SegInput::Id{{{*/
int    SegInput::Id(void){ return -1; }
/*}}}*/
/*FUNCTION SegInput::ObjectEnum{{{*/
int SegInput::ObjectEnum(void){

	return SegInputEnum;

}
/*}}}*/
/*FUNCTION SegInput::copy{{{*/
Object* SegInput::copy() {

	return new SegInput(this->enum_type,this->values,this->element_type);

}
/*}}}*/

/*SegInput management*/
/*FUNCTION SegInput::InstanceEnum{{{*/
int SegInput::InstanceEnum(void){

	return this->enum_type;

}
/*}}}*/

/*Object functions*/
/*FUNCTION SegInput::GetInputAverage{{{*/
void SegInput::GetInputAverage(IssmDouble* pvalue){

	int        numnodes  = this->NumberofNodes();
	IssmDouble numnodesd = reCast<int,IssmDouble>(numnodes);
	IssmDouble value     = 0.;

	for(int i=0;i<numnodes;i++) value+=values[i];
	value = value/numnodesd;

	*pvalue=value;
}
/*}}}*/
/*FUNCTION SegInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
void SegInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){

	/*Call SegRef function*/
	_assert_(gauss->Enum()==GaussSegEnum);
	SegRef::GetInputValue(pvalue,&values[0],(GaussSeg*)gauss);

}
/*}}}*/
/*FUNCTION SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
void SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list,Gauss* gauss){

	/*Call SegRef function*/
	_assert_(gauss->Enum()==GaussSegEnum);
	SegRef::GetInputDerivativeValue(p,&values[0],xyz_list,(GaussSeg*)gauss);
}
/*}}}*/
/*FUNCTION SegInput::Configure{{{*/
void SegInput::Configure(Parameters* parameters){
	/*do nothing: */
}
/*}}}*/
/*FUNCTION SegInput::Min{{{*/
IssmDouble SegInput::Min(void){

	const int  numnodes=this->NumberofNodes();
	IssmDouble min=values[0];

	for(int i=1;i<numnodes;i++){
		if(values[i]<min) min=values[i];
	}
	return min;
}
/*}}}*/
