// ************************************************************************* //
//  File: avtH5PartRandomSampleFilter.C
// ************************************************************************* //

#include <avtH5PartRandomSampleFilter.h>
#include <vtkDataSet.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkVisItUtility.h>
#include <vtkIdTypeArray.h>
#include <vtkCell.h>
#include <vtkCellData.h>
#include <vtkCellLocator.h>
#include <vtkGenericCell.h>



// ****************************************************************************
//  Method: avtH5PartRandomSampleFilter constructor
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
// ****************************************************************************

avtH5PartRandomSampleFilter::avtH5PartRandomSampleFilter()
{
	idList = vtkIdList::New();
	npoints = 0;
}


// ****************************************************************************
//  Method: avtH5PartRandomSampleFilter destructor
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
//  Modifications:
//
// ****************************************************************************

avtH5PartRandomSampleFilter::~avtH5PartRandomSampleFilter()
{
}


// ****************************************************************************
//  Method:  avtH5PartRandomSampleFilter::Create
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
// ****************************************************************************

avtFilter *
avtH5PartRandomSampleFilter::Create()
{
    return new avtH5PartRandomSampleFilter();
}


// ****************************************************************************
//  Method:      avtH5PartRandomSampleFilter::SetAtts
//
//  Purpose:
//      Sets the state of the filter based on the attribute object.
//
//  Arguments:
//      a        The attributes to use.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
// ****************************************************************************

void
avtH5PartRandomSampleFilter::SetAtts(const AttributeGroup *a)
{
    atts = *(const H5PartRandomSampleAttributes*)a;
}


// ****************************************************************************
//  Method: avtH5PartRandomSampleFilter::Equivalent
//
//  Purpose:
//      Returns true if creating a new avtH5PartRandomSampleFilter with the given
//      parameters would result in an equivalent avtH5PartRandomSampleFilter.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
// ****************************************************************************

bool
avtH5PartRandomSampleFilter::Equivalent(const AttributeGroup *a)
{
    return (atts == *(H5PartRandomSampleAttributes*)a);
}


// ****************************************************************************
//  Method: avtH5PartRandomSampleFilter::ExecuteData
//
//  Purpose:
//      Sends the specified input and output through the H5PartRandomSample filter.
//
//  Arguments:
//      in_ds      The input dataset.
//      <unused>   The domain number.
//      <unused>   The label.
//
//  Returns:       The output dataset.
//
//  Programmer: cristina -- generated by xml2avt
//  Creation:   Thu Mar 2 13:48:31 PST 2006
//
// ****************************************************************************

vtkDataSet *
avtH5PartRandomSampleFilter::ExecuteData(vtkDataSet *in_ds, int, std::string)
{

	float factor = atts.GetFactor();
	int nspace = 3;
	int update = 0;


	if (factor >= 1.0) {
		in_ds->Register(NULL);
		return in_ds;
	} else if (factor < 0){
		factor = 0.0;
	}
	vtkIdType nPoints = in_ds->GetNumberOfPoints();

	vtkPointData *inPD = in_ds->GetPointData();
  vtkPolyData *out_ds = vtkPolyData::New();
  vtkPoints *pts = vtkPoints::New();
	pts->SetNumberOfPoints((vtkIdType) (nPoints*factor));
	out_ds->SetPoints(pts);
	out_ds->Allocate(nspace*((vtkIdType) (nPoints*factor)));

	vtkPointData *outPD = out_ds->GetPointData();
	outPD->CopyAllocate(inPD, 0, (vtkIdType) (nPoints*factor));

  double sfactor = (double) (nPoints-1)/RAND_MAX;
	seed=12;
  srand(seed);

	vtkIdType i, index;
  vtkIdType newId = 0;
  vtkIdType onevertex[1];
	for (vtkIdType i = 0; newId < (vtkIdType)(nPoints*factor); i++) {
		index = (vtkIdType) (sfactor * rand());
		if (idList->IsId(index) != -1){
			 continue;
		} else {
			idList->InsertNextId(index);
		}
		outPD->CopyData(inPD, index, newId);		
    float pt[3];
		in_ds->GetPoint(index, pt);
    pts->SetPoint(newId, pt);
    onevertex[0] = newId;
		out_ds->InsertNextCell(VTK_VERTEX, 1, onevertex);
		newId++;
	}
	idList->Reset();
	idList->Delete();
	pts->Delete();

	return out_ds;


}
