/*
 * ClusterPopulator.h
 *
 *  Created on: 8 mar 2010
 *      Author: Erik Ogenvik
 */

#ifndef CLUSTERPOPULATOR_H_
#define CLUSTERPOPULATOR_H_

#include "PlantPopulator.h"

namespace WFMath {
template<int>
class Ball;
}


namespace Ember::OgreView::Terrain {

template<typename>
class Buffer;

namespace Foliage {

typedef std::vector<WFMath::Ball<2>> ClusterStore;

class ClusterPopulator : public PlantPopulator {
public:
	ClusterPopulator(int layerIndex, std::unique_ptr<IScaler> scaler, size_t plantIndex);

	~ClusterPopulator() override = default;

	void populate(PlantAreaQueryResult& result, SegmentRefPtr segmentRef) override;

	void setMinClusterRadius(float theValue);

	float getMinClusterRadius() const;

	void setMaxClusterRadius(float theValue);

	float getMaxClusterRadius() const;

	void setDensity(float theValue);

	float getDensity() const;

	void setFalloff(float theValue);

	float getFalloff() const;

	void setClusterDistance(float theValue);

	float getClusterDistance() const;

	void setThreshold(unsigned char theValue);

	float getTreshold() const;

protected:

	void getClustersForArea(const SegmentRefPtr& segmentRef, const WFMath::AxisBox<2>& area, ClusterStore& clusters);

	void populateWithClusters(const SegmentRefPtr& segmentRef,
							  PlantAreaQueryResult& result,
							  const WFMath::AxisBox<2>& area,
							  const ClusterStore& clusters,
							  const Buffer<unsigned char>& combinedCoverage);

	void populateWithCluster(const SegmentRefPtr& segmentRef,
							 PlantAreaQueryResult& result,
							 const WFMath::AxisBox<2>& area,
							 const WFMath::Ball<2>& cluster,
							 const Buffer<unsigned char>& combinedCoverage);

	float mMinClusterRadius;
	float mMaxClusterRadius;
	float mClusterDistance;
	float mDensity;
	float mFalloff;
	unsigned char mThreshold;
};

}

}


#endif /* CLUSTERPOPULATOR_H_ */
