// This file may be redistributed and modified only under the terms of
// the GNU General Public License (See COPYING for details).
// Copyright (C) 2003 Alistair Riddoch

#ifndef MERCATOR_FILL_GRASS_SHADER_H
#define MERCATOR_FILL_GRASS_SHADER_H

#include "Shader.h"
#include "Surface.h"

/* alpha ^
 *       |
 *     1 |_______________________ cutoff
 *       |                       \ 
 *       |                        \ 
 *       |                         \ 
 *       |                          \ 
 *       |                           \ 
 *       |                            \ 
 *       |                             \ 
 *       |                              \ 
 *       |                               \ 
 *       |                                \  intercept
 *     0 |_________________________________\_________________________> slope
 *
 * This shader is used to add grassy vegetation to some terrain.
 * The mask generated by this shader depends on two factors. The altitude
 * of the terrain, and its slope. Two parameter specify the low and high
 * altitude values between which vegetation grows. The low value will typically
 * be just above sea level, and the high value could be anything up to the
 * height above which plants cannot grow.
 *
 * The cutoff parameter specifies the slope below which the vegetation is
 * completely opaque. The intercept parameter specifies the slope above which
 * vegetetation will not grow on the terrain. Between these values the
 * vegetation is blended onto the terrain to give an impression of a light
 * covering.
 */

namespace Mercator {

/// \brief Shader for adding grass to the terrain.
///
/// This shader is used to add grassy vegetation to some terrain.
/// The mask generated by this shader depends on two factors. The altitude
/// of the terrain, and its slope. Two parameter specify the low and high
/// altitude values between which vegetation grows. The low value will
/// typically be just above sea level, and the high value could be anything
/// up to the height above which plants cannot grow.
class GrassShader : public Shader {
private:
	/// The level above which the shader renders.
	float m_lowThreshold;
	/// The level below which the shader renders.
	float m_highThreshold;
	/// The slope below which grass is opaque.
	float m_cutoff;
	/// The slope steeper than which no grass grows.
	float m_intercept;

	/// \brief Determine the alpha value for grass for a given slope
	///
	/// Determine the alpha value used when applying grass to the
	/// terrain at a point with given height and average slope.
	/// @param height the altitude of the specified point.
	/// @param slope the steepness of the terrain at the specified point.
	ColorT slopeToAlpha(float height, float slope) const;

public:
	/// Key string used when specifying the low threshold parameter.
	static const std::string key_lowThreshold;
	/// Key string used when specifying the high threshold parameter.
	static const std::string key_highThreshold;
	/// Key string used when specifying the cutoff parameter.
	static const std::string key_cutoff;
	/// Key string used when specifying the intercept parameter.
	static const std::string key_intercept;

	/// Default level above which the shader renders.
	static const float default_lowThreshold;
	/// Default level below which the shader renders.
	static const float default_highThreshold;
	/// Default slope below which grass is opaque.
	static const float default_cutoff;
	/// Default slope steeper than which no grass grows.
	static const float default_intercept;

	/// \brief Constructor
	///
	/// @param lowThreshold level above which the shader renders.
	/// @param highThreshold level above which the shader renders.
	/// @param cutoff slope below which grass is opaque.
	/// @param intercept slope steeper than which no grass grows.
	explicit GrassShader(float lowThreshold = default_lowThreshold,
						 float highThreshold = default_highThreshold,
						 float cutoff = default_cutoff,
						 float intercept = default_intercept);

	/// \brief Constructor
	///
	/// @param params a map of parameters for the shader.
	explicit GrassShader(const Parameters& params);

	~GrassShader() override;

	/// Accessor for level above which the shader renders.
	float lowThreshold() const { return m_lowThreshold; }

	/// Accessor for level below which the shader renders.
	float highThreshold() const { return m_highThreshold; }

	/// Accessor for slope below which grass is opaque.
	float cutoff() const { return m_cutoff; }

	/// Accessor for slope steeper than which no grass grows.
	float intercept() const { return m_intercept; }

	bool checkIntersect(const Segment&) const override;

	void shade(Surface&) const override;
};

} // namespace Mercator

#endif // MERCATOR_FILL_GRASS_SHADER_H
