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

/*Headers:*/
/*{{{*/
#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"
/*}}}*/

/*Object constructors and destructor*/
/*FUNCTION ElementHook::ElementHook(){{{*/
ElementHook::ElementHook(){
	numanalyses=UNDEF;
	this->hnodes     = NULL;
	this->hvertices  = NULL;
	this->hmaterial  = NULL;
	this->hmatpar    = NULL;
	this->hneighbors = NULL;
}
/*}}}*/
/*FUNCTION ElementHook::~ElementHook(){{{*/
ElementHook::~ElementHook(){

	int i;

	for(i=0;i<this->numanalyses;i++){
		if (this->hnodes[i]) delete this->hnodes[i];
	}
	delete [] this->hnodes;
	delete hvertices;
	delete hmaterial;
	delete hmatpar;
	delete hneighbors;
}
/*}}}*/
/*FUNCTION ElementHook::ElementHook(int in_numanalyses,int element_id, int numvertices,IoModel* iomodel){{{*/
ElementHook::ElementHook(int in_numanalyses,int element_id,int numvertices,IoModel* iomodel){

	/*intermediary: */
	int matpar_id;
	int material_id;

	/*retrieve material_id: */
	matpar_id = iomodel->numberofelements+1;

	/*retrieve material_id*/
	material_id = element_id;

	/*retrieve vertices ids*/
	int* vertex_ids = xNew<int>(numvertices);
	for(int i=0;i<numvertices;i++){ 
		vertex_ids[i]=reCast<int>(iomodel->elements[(element_id-1)*numvertices+i]);
	}

	this->numanalyses = in_numanalyses;
	this->hnodes      = new Hook*[in_numanalyses];
	this->hvertices   = new Hook(&vertex_ids[0],numvertices);
	this->hmaterial   = new Hook(&material_id,1);
	this->hmatpar     = new Hook(&matpar_id,1);
	this->hneighbors  = NULL;

	/*Initialize hnodes as NULL*/
	for(int i=0;i<this->numanalyses;i++){
		this->hnodes[i]=NULL;
	}

	/*Clean up*/
	xDelete<int>(vertex_ids);

}
/*}}}*/

/*FUNCTION ElementHook::SetHookNodes{{{*/
void ElementHook::SetHookNodes(int* node_ids,int numnodes,int analysis_counter){
	this->hnodes[analysis_counter]= new Hook(node_ids,numnodes);
}
/*}}}*/
/*FUNCTION ElementHook::InitHookNeighbors{{{*/
void ElementHook::InitHookNeighbors(int* element_ids){
	this->hneighbors=new Hook(element_ids,2);
}
/*}}}*/
/*FUNCTION ElementHook::SpawnTriaHook{{{*/
void ElementHook::SpawnTriaHook(ElementHook* triahook,int location){

	/*Create arrow of indices depending on location (0=base 1=surface)*/
	int indices[3];
	switch(location){
		case 0:
			indices[0] = 0;
			indices[1] = 1;
			indices[2] = 2;
			break;
		case 1:
			indices[0] = 3;
			indices[1] = 4;
			indices[2] = 5;
			break;
		default:
			_error_("case "<<location<<" not supported");
	}

	triahook->numanalyses=this->numanalyses;

	/*Spawn nodes hook*/
	triahook->hnodes=new Hook*[this->numanalyses];
	for(int i=0;i<this->numanalyses;i++){
		/*Do not do anything if Hook is empty*/
		if (!this->hnodes[i] || this->hnodes[i]->GetNum()==0){
			triahook->hnodes[i]=NULL;
		}
		else{
			triahook->hnodes[i]=this->hnodes[i]->Spawn(indices,3);
		}
	}

	/*do not spawn hmaterial. material will be taken care of by Penta*/
	triahook->hmaterial=NULL;
	triahook->hvertices=(Hook*)this->hvertices->Spawn(indices,3);
	triahook->hmatpar=(Hook*)this->hmatpar->copy();
}
/*}}}*/
