/*!\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*/
ElementHook::ElementHook(){/*{{{*/
	numanalyses=UNDEF;
	this->hnodes     = NULL;
	this->hvertices  = NULL;
	this->hmaterial  = NULL;
	this->hmatpar    = NULL;
	this->hneighbors = NULL;
}
/*}}}*/
ElementHook::~ElementHook(){/*{{{*/

	if(this->hnodes){
		for(int 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;
}
/*}}}*/
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);

}
/*}}}*/

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

	/*Create arrow of indices depending on location (0=base 1=surface)*/
	int indices[3];
	indices[0] = index1;
	indices[1] = index2;
	indices[2] = index3;

	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();
}
/*}}}*/
void ElementHook::SpawnSegHook(ElementHook* triahook,int index1,int index2){/*{{{*/

	triahook->numanalyses=this->numanalyses;

	int indices[2];
	indices[0]=index1;
	indices[1]=index2;

	/*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,2);
		}
	}

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