/**
    Set the maximum value for the contrast enhancement. The second parameter is option an is for performace improvements. If you know you are immediately going to set the Maximum value or the contrast enhancement algorithm, you can elect to not generate the lookup tale. By default it will be generated.

    @param theValue The new minimum value for the band
    @param generateTable Flag to overide automatic look up table generation
*/
void QgsContrastEnhancement::setMinimumValue( double theValue, bool generateTable )
{
  QgsDebugMsg( "called value: " + QString::number( theValue ) + " generate lookup table: " + QString::number( static_cast< int >( generateTable ) ) );

  if ( theValue < minimumValuePossible( mRasterDataType ) )
  {
    mMinimumValue = minimumValuePossible( mRasterDataType );
  }
  else
  {
    mMinimumValue = theValue;
  }

  if ( mContrastEnhancementFunction )
  {
    mContrastEnhancementFunction->setMinimumValue( theValue );
  }

  mEnhancementDirty = true;

  if ( generateTable )
  {
    generateLookupTable();
  }
}
/**
    Set the contrast enhancement algorithm. The second parameter is optional and is for performace improvements. If you know you are immediately going to set the Minimum or Maximum value, you can elect to not generate the lookup tale. By default it will be generated.

    @param theAlgorithm The new contrast enhancement algorithm
    @param generateTable Flag to overide automatic look up table generation
*/
void QgsContrastEnhancement::setContrastEnhancementAlgorithm( ContrastEnhancementAlgorithm theAlgorithm, bool generateTable )
{
  QgsDebugMsg( "called algorithm: " + QString::number(( int )theAlgorithm ) + " generate lookup table: " + QString::number(( int )generateTable ) );

  if ( theAlgorithm != mContrastEnhancementAlgorithm )
  {
    switch ( theAlgorithm )
    {
      case StretchToMinimumMaximum :
        mContrastEnhancementFunction = new QgsLinearMinMaxEnhancement( mRasterDataType, mMinimumValue, mMaximumValue );
        break;
      case StretchAndClipToMinimumMaximum :
        mContrastEnhancementFunction = new QgsLinearMinMaxEnhancementWithClip( mRasterDataType, mMinimumValue, mMaximumValue );
        break;
      case ClipToMinimumMaximum :
        mContrastEnhancementFunction = new QgsClipToMinMaxEnhancement( mRasterDataType, mMinimumValue, mMaximumValue );
        break;
      case UserDefinedEnhancement :
        //Do nothing
        break;
      default:
        mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );
        break;
    }

    mEnhancementDirty = true;
    mContrastEnhancementAlgorithm = theAlgorithm;

    if ( generateTable )
    {
      generateLookupTable();
    }
  }
}
/**
    A public function that allows the user to set their own custom contrast enhancement function.

    @param theFunction The new contrast enhancement function
*/
void QgsContrastEnhancement::setContrastEnhancementFunction( QgsContrastEnhancementFunction* theFunction )
{
  QgsDebugMsg( "called" );

  if ( 0 != theFunction )
  {
    mContrastEnhancementFunction = theFunction;
    mContrastEnhancementAlgorithm = UserDefinedEnhancement;
    generateLookupTable();
  }
}
/**
    Public function to generate the enhanced for enhanceContrasted value for a given input.

    @param theValue The pixel value to enhance
*/
int QgsContrastEnhancement::enhanceContrast( double theValue )
{
  if ( mEnhancementDirty )
  {
    generateLookupTable();
  }

  if ( mLookupTable && NoEnhancement != mContrastEnhancementAlgorithm )
  {
    return mLookupTable[static_cast <int>( theValue + mLookupTableOffset )];
  }
  else
  {
    // Even if the contrast enhancement algorithms is set to NoEnhancement
    // The input values will still have to be scaled for all data types
    // greater than 1 byte.
    return mContrastEnhancementFunction->enhance( theValue );
  }
}