// 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 <Mercator/Shader.h>
#include <Mercator/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);
    virtual ~GrassShader();

    /// Accessor for level above which the shader renders.
    const float lowThreshold() const { return m_lowThreshold; }
    /// Accessor for level below which the shader renders.
    const float highThreshold() const { return m_highThreshold; }
    /// Accessor for slope below which grass is opaque.
    const float cutoff() const { return m_cutoff; }
    /// Accessor for slope steeper than which no grass grows.
    const float intercept() const { return m_intercept; }

    virtual bool checkIntersect(const Segment &) const;
    virtual void shade(Surface &) const;
};

} // namespace Mercator

#endif // MERCATOR_FILL_GRASS_SHADER_H
