/*
 * DataSet.h:
 * \brief Class that holds objects.
 * \file DataSet.h This prototype defines a DataSet, capable of holding any type of 
 * objects (using the abstract class Object). 
 */


#ifndef DATASET_H_
#define DATASET_H_

#include "../objects/Object.h"
#include "../objects/ParameterInputs.h"
#include <vector>
#include "../toolkits/toolkits.h"

using namespace std;

class DataSet {
	
	private: 
		/*internals: */
		vector<Object*> objects;
		
		/*type of dataset: */
		int             enum_type;
		
		/*sorting: */
		int             sorted;
		int             presorted;
		int*            sorted_ids;
		int*            id_offsets;

	public:
		DataSet();
		DataSet(int enum_type);
		~DataSet();

		int   GetEnum();
		void  Echo();
		char* Marshall();
		int   MarshallSize();
		int   AddObject(Object* object);
		int   DeleteObject(int id);
		int   Size();
		int   FindParam(void* pvalue, char* name);
		void  NodeRank(int* ranks);
		void  DistributeDofs(int numberofnodes,int numdofspernode);
		void  CreatePartitioningVector(Vec* ppartition,int numnods,int numdofspernode);
		void  DistributeNumDofs(int** pnumdofspernode,int numberofnodes,int analysis_type);
		void  FlagClones(int numberofnodes);
		int   NumberOfDofs();
		int   NumberOfRgbs();
		void  SetupSpcs(DataSet* nodes,Vec yg);
		void  SetupMpcs(Mat Rmg,DataSet* nodes);
		void  FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s);
		void  clear();
		void  Configure(DataSet* elements,DataSet* loads, DataSet* nodes, DataSet* materials);
		Object* GetObjectByOffset(int offset);
		Object* GetObjectById(int* poffset,int eid);
		void  Presort();
		void  SetSorting(int* in_sorted_ids,int* in_id_offsets);
		void  Sort();
		void  CreateKMatrix(Mat Kgg,ParameterInputs* inputs, int analysis_type);
		void  CreatePVector(Vec pg,ParameterInputs* inputs, int analysis_type);
		void  UpdateFromInputs(ParameterInputs* inputs);
		void  PenaltyCreateKMatrix(Mat Kgg,ParameterInputs* inputs,double kmax,int analysis_type);
		void  PenaltyCreatePVector(Vec pg,ParameterInputs* inputs,double kmax,int analysis_type);
		int   RiftIsPresent();
		void  RiftConstraints(int* pnum_unstable_constraints,ParameterInputs* inputs,int analysis_type);
		int   MeltingIsPresent();
		void  MeltingConstraints(int* pnum_unstable_constraints,ParameterInputs* inputs,int analysis_type);
		DataSet* Copy(void);
		void  Du(Vec du_g,double*  u_g,double* u_g_obs,ParameterInputs* inputs,int analysis_type);
		void  Gradj(Vec grad_g,double*  u_g,double* lambda_g,ParameterInputs* inputs,int analysis_type,char* control_type);
		void  Misfit(double* pJ, double* u_g,double* u_g_obs,ParameterInputs* inputs,int analysis_type);



};


/*This routine cannot be object oriented, but need for demarshalling: */
DataSet* DataSetDemarshall(char* marshalled_dataset);

#endif
