/*****************************************************************************/
// Copyright 2006-2019 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/

/** \file
 * C++ exception support for DNG SDK.
*/

/*****************************************************************************/

#ifndef __dng_exceptions__
#define __dng_exceptions__

/*****************************************************************************/

#include "dng_errors.h"
#include "dng_flags.h"

/*****************************************************************************/

#ifndef DNG_NO_RETURN
#ifdef __GNUC__
#define DNG_NO_RETURN __attribute__((noreturn))
#else
#define DNG_NO_RETURN
#endif
#endif

/*****************************************************************************/

/// Display a warning message. Note that this may just eat the message.

void ReportWarning (const char *message,
				    const char *sub_message = NULL);
	
/*****************************************************************************/

/// Display an error message. Note that this may just eat the message.

void ReportError (const char *message,
				  const char *sub_message = NULL);
	
/*****************************************************************************/

/// \brief All exceptions thrown by the DNG SDK use this exception class.

class dng_exception
	{
	
	private:
	
		dng_error_code fErrorCode;
	
	public:
	
		/// Construct an exception representing the given error code.
		/// \param code Error code this exception is for.
		
		dng_exception (dng_error_code code)
		
			: fErrorCode (code)
			
			{
			}
		
		virtual ~dng_exception ()
			{ 
			}

		/// Getter for error code of this exception
		/// \retval The error code of this exception.
		
		dng_error_code ErrorCode () const
			{
			return fErrorCode;
			}

	};
	
/******************************************************************************/

/// \brief Throw an exception based on an arbitrary error code.

void Throw_dng_error (dng_error_code err,
					  const char * message = NULL,
					  const char * sub_message = NULL,
					  bool silent = false) DNG_NO_RETURN;

/******************************************************************************/

/// \brief Convenience function to throw dng_exception with error code if
/// error_code is not dng_error_none .

inline void Fail_dng_error (dng_error_code err)
	{
	
	if (err != dng_error_none)
		{
		
		Throw_dng_error (err);
		
		}
		
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_unknown .

inline void ThrowProgramError (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_unknown, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_overflow.

inline void ThrowOverflow (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_overflow, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code 
/// dng_error_not_yet_implemented .

inline void ThrowNotYetImplemented (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_not_yet_implemented, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_silent .

inline void ThrowSilentError ()
	{
	
	Throw_dng_error (dng_error_silent);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_user_canceled .

inline void ThrowUserCanceled ()
	{
	
	Throw_dng_error (dng_error_user_canceled);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_host_insufficient .

inline void ThrowHostInsufficient (const char * sub_message = NULL,
                                   bool silent = false)
	{
	
	Throw_dng_error (dng_error_host_insufficient, NULL, sub_message, silent);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_memory .

inline void ThrowMemoryFull (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_memory, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_bad_format .

inline void ThrowBadFormat (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_bad_format, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_matrix_math .

inline void ThrowMatrixMath (const char * sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_matrix_math, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_open_file .

inline void ThrowOpenFile (const char * sub_message = NULL, bool silent = false)
	{
	
	Throw_dng_error (dng_error_open_file, NULL, sub_message, silent);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_read_file .

inline void ThrowReadFile (const char *sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_read_file, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_write_file .

inline void ThrowWriteFile (const char *sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_write_file, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_end_of_file .

inline void ThrowEndOfFile (const char *sub_message = NULL)
	{
	
	Throw_dng_error (dng_error_end_of_file, NULL, sub_message);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_file_is_damaged .

inline void ThrowFileIsDamaged ()
	{
	
	Throw_dng_error (dng_error_file_is_damaged);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_image_too_big_dng .

inline void ThrowImageTooBigDNG ()
	{
	
	Throw_dng_error (dng_error_image_too_big_dng);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_image_too_big_tiff .

inline void ThrowImageTooBigTIFF ()
	{
	
	Throw_dng_error (dng_error_image_too_big_tiff);
	
	}

/*****************************************************************************/

/// \brief Convenience function to throw dng_exception with error code
/// dng_error_unsupported_dng .

inline void ThrowUnsupportedDNG ()
	{
	
	Throw_dng_error (dng_error_unsupported_dng);
	
	}

/*****************************************************************************/

#endif
	
/*****************************************************************************/
