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

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

#include <stdio.h>
#include <string.h>
#include "../objects.h"
#include "../../EnumDefinitions/EnumDefinitions.h"
#include "../../shared/shared.h"
#include "../../Container/Container.h"
#include "../../include/include.h"

/*IntInput constructors and destructor*/
/*FUNCTION IntInput::IntInput(){{{*/
IntInput::IntInput(){
	return;
}
/*}}}*/
/*FUNCTION IntInput::IntInput(IssmDouble* values){{{*/
IntInput::IntInput(int in_enum_type,IssmInt in_value){

	enum_type=in_enum_type;
	value=in_value;
}
/*}}}*/
/*FUNCTION IntInput::~IntInput(){{{*/
IntInput::~IntInput(){
	return;
}
/*}}}*/

/*Object virtual functions definitions:*/
/*FUNCTION IntInput::DeepEcho{{{*/
void IntInput::DeepEcho(void){

	_printLine_("IntInput:");
	_printLine_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")");
	_printLine_("   value: " << (int)this->value);
}
/*}}}*/
/*FUNCTION IntInput::Id{{{*/
int    IntInput::Id(void){ return -1; }
/*}}}*/
/*FUNCTION IntInput::MyRank{{{*/
int    IntInput::MyRank(void){ 
	extern int my_rank;
	return my_rank; 
}
/*}}}*/
/*FUNCTION IntInput::ObjectEnum{{{*/
int IntInput::ObjectEnum(void){

	return IntInputEnum;

}
/*}}}*/
/*FUNCTION IntInput::copy{{{*/
Object* IntInput::copy() {
	
	return new IntInput(this->enum_type,this->value);

}
/*}}}*/

/*IntInput management*/
/*FUNCTION IntInput::Echo {{{*/
void IntInput::Echo(void){
	this->DeepEcho();
}
/*}}}*/
/*FUNCTION IntInput::InstanceEnum{{{*/
int IntInput::InstanceEnum(void){

	return this->enum_type;

}
/*}}}*/
/*FUNCTION IntInput::SpawnTriaInput{{{*/
Input* IntInput::SpawnTriaInput(int* indices){

	/*output*/
	IntInput* outinput=new IntInput();

	/*only copy current value*/
	outinput->enum_type=this->enum_type;
	outinput->value=this->value;

	/*Assign output*/
	return outinput;
}
/*}}}*/
/*FUNCTION IntInput::SpawnResult{{{*/
ElementResult* IntInput::SpawnResult(int step, IssmDouble time){
	
	_error2_("not supported yet!");

}
/*}}}*/

/*Object functions*/
/*FUNCTION IntInput::GetInputValue(bool* pvalue) {{{*/
void IntInput::GetInputValue(bool* pvalue){_error2_("not supported yet!");}
/*}}}*/
/*FUNCTION IntInput::GetInputValue(int* pvalue){{{*/
void IntInput::GetInputValue(int* pvalue){
	*pvalue=value;
}
/*}}}*/
/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue){{{*/
void IntInput::GetInputValue(IssmDouble* pvalue){
	_error2_("IntInput cannot return a IssmDouble in parallel");
}
/*}}}*/
/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
void IntInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error2_("not supported yet!");}
/*}}}*/
/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
void IntInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error2_("not supported yet!");}
/*}}}*/
/*FUNCTION IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
void IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error2_("not supported yet!");}
/*}}}*/
/*FUNCTION IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
void IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error2_("not supported yet!");}
/*}}}*/
/*FUNCTION IntInput::ChangeEnum{{{*/
void IntInput::ChangeEnum(int newenumtype){
	this->enum_type=newenumtype;
}
/*}}}*/
/*FUNCTION IntInput::SquareMin{{{*/
void IntInput::SquareMin(IssmDouble* psquaremin, bool process_units,Parameters* parameters){

	/*square min of an integer is the square of the integer itself: */
	*psquaremin=pow((IssmDouble)value,2);
}
/*}}}*/
/*FUNCTION IntInput::Scale{{{*/
void IntInput::Scale(IssmDouble scale_factor){
	IssmDouble dvalue=(IssmDouble)value*scale_factor;
	value=reCast<int>(dvalue);
}
/*}}}*/
/*FUNCTION IntInput::AXPY{{{*/
void IntInput::AXPY(Input* xinput,IssmDouble scalar){

	IssmDouble dvalue;
	IntInput*  xintinput=NULL;

	/*xinput is of the same type, so cast it: */
	xintinput=(IntInput*)xinput;

	/*Carry out the AXPY operation depending on type:*/
	switch(xinput->ObjectEnum()){

		case IntInputEnum:
			dvalue=(IssmDouble)this->value+scalar*(IssmDouble)xintinput->value;
			this->value=reCast<int>(dvalue);
			return;

		default:
			_error2_("not implemented yet");
	}

}
/*}}}*/
/*FUNCTION IntInput::Constrain{{{*/
void IntInput::Constrain(IssmDouble cm_min, IssmDouble cm_max){

	if(!xIsNan<IssmDouble>(cm_min)) if (this->value<cm_min)this->value=reCast<int>(cm_min);
	if(!xIsNan<IssmDouble>(cm_max)) if (this->value>cm_max)this->value=reCast<int>(cm_max);

}
/*}}}*/
/*FUNCTION IntInput::GetVectorFromInputs{{{*/
void IntInput::GetVectorFromInputs(Vector* vector,int* doflist){

	_error2_("not supporte yet!");

}
/*}}}*/
/*FUNCTION IntInput::GetValuesPtr{{{*/
void IntInput::GetValuesPtr(IssmDouble** pvalues,int* pnum_values){

	_error2_("not supported yet!");

}
/*}}}*/
/*FUNCTION IntInput::Configure{{{*/
void IntInput::Configure(Parameters* parameters){
	/*do nothing: */
}
/*}}}*/
