//------------------------------------------------------------------------------
//    module exception.cpp                                                    //
//                                                                            //
//    exception classes and helper functions                                  //
//    Exceptions are thrown using the functions ThrowTypeX() and              //
//    IfTrueThrowTypeX(). 'X' can be one of 'A', 'B' or 'U' and corresponds   //
//    to the type of the exception. Type 'A' and 'B' are for program          //
//    development only and should never been thrown. Type 'B' exceptions are  //
//    only generated in debug mode (DEBUG is defined). Type 'U' is intended   //
//    to be catched and shown to the user; it may occur in practise.          //
//                                                                            //
//    copyright (c) 2002-2003 by Lars Haendel                                 //
//    home: www.newty.de                                                      //
//                                                                            //
//    This program is free software and can be used under the terms of the    //
//    GNU licence. See header file for further information and disclaimer.    //
//                                                                            //
//------------------------------------------------------------------------------


#include "exception.h"


//----------------------------------------------------------------------------------------------------------------------
// globals which store the last exception thrown
bool f_TypeU=false, f_TypeAB=false;                            // indicates the type of exception thrown last
TExceptionAB LastExceptionAB;
TExceptionU LastExceptionU;
const bool& IsTypeUExcpetion()  { return f_TypeU; };
const bool& IsTypeABExcpetion() { return f_TypeAB; };
const TExceptionAB& GetLastExcpetionAB() { f_TypeAB=false; return LastExceptionAB; };
const TExceptionU&  GetLastExcpetionU () { f_TypeU=false;  return LastExceptionU;  };




//----------------------------------------------------------------------------------------------------------------------
// constructor type 'A' or 'B' exceptions
TExceptionAB::TExceptionAB(const char* _szMessage, const char* _szFunction/*=NULL*/, const char* _szModule/*=NULL*/)
{
   strcpy(szMessage, _szMessage);            // copy error description

   if(_szFunction)                           // copy function name if given ...
      strcpy(szFunction, _szFunction);
   else
      strcpy(szFunction, "?");               // else set default text

   if(_szModule)                             // copy model name if given ...
      strcpy(szModule, _szModule);
   else
      strcpy(szModule, "?");                 // else set default text
}


//----------------------------------------------------------------------------------------------------------------------
// get error description
const char* TExceptionU::GetErrorText() const
{
   f_TypeU = false;
   return szMessage;
}


//----------------------------------------------------------------------------------------------------------------------
// compose error description
const char* TExceptionAB::GetErrorText(const bool& f_Verbose/*=true*/) const
{
   f_TypeAB=false;   // reset error flag


   // compose error text
   if(f_Verbose)
      sprintf(szText, "Error in module '%s' in %s: %s!", szModule, szFunction, szMessage); // verbose version
   else
      strcpy(szText, szMessage);                                                           // or else just message body

   return szText; // return
}


//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'A' exception
void ThrowTypeA(const char* szMessage, const char* szFunction/*=NULL*/, const char* szModule/*=NULL*/)
{
   f_TypeAB = true;
   LastExceptionAB = TExceptionAB(szMessage, szFunction, szModule);     // instantiate
   throw LastExceptionAB;                                               // throw
}


//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'A' exception if flag 'f_Throw' is set
void IfTrueThrowTypeA(const bool f_Throw, const char* szMessage, const char* szFunction/*=NULL*/,
                        const char* szModule/*=NULL*/)
{
   if(f_Throw)
   {
      f_TypeAB = true;
      LastExceptionAB = TExceptionAB(szMessage, szFunction, szModule);           // instantiate
      throw LastExceptionAB;                                                     // throw
   }
}


#ifdef DEBUG    // type 'B' exceptions are not thrown but replaced by empty inline functions if DEBUG is not defined
//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'B' exception
void ThrowTypeB(const char* szMessage, const char* szFunction/*=NULL*/, const char* szModule/*=NULL*/)
{
   f_TypeAB = true;
   LastExceptionAB = TExceptionAB(szMessage, szFunction, szModule);              // instantiate
   throw LastExceptionAB;                                                        // throw
}

//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'B' exception if flag 'f_Throw' is set
void IfTrueThrowTypeB(const bool f_Throw, const char* szMessage, const char* szFunction/*=NULL*/,
                      const char* szModule/*=NULL*/)
{
   if(f_Throw)
   {
      f_TypeAB = true;
      LastExceptionAB = TExceptionAB(szMessage, szFunction, szModule);           // instantiate
      throw LastExceptionAB;                                                     // throw
   }
}
#endif


//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'U' exception
void ThrowTypeU(const char* szMessage)
{
   f_TypeU = true;
   LastExceptionU = TExceptionU(szMessage);                    // instantiate
   throw LastExceptionU;                                       // throw
}

//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'U' exception if flag 'f_Throw' is set
void IfTrueThrowTypeU(const bool f_Throw, const char* szMessage)
{
   if(f_Throw)
   {
      f_TypeU = true;
      LastExceptionU = TExceptionU(szMessage);                 // instantiate
      throw LastExceptionU;                                    // throw
   }
}


//----------------------------------------------------------------------------------------------------------------------
// helper function: throw type 'U' exception if flag 'f_Throw' is set. Allow format string (which is passed to
// sprintf) with one(!) '%s' (string) inside. The content of 'szString' will be inserted at the position of the '%s'.
// Beware: There are no checks!
void IfTrueThrowTypeU(const bool f_Throw, const char* szFormat, const char* szString)
{
   if(f_Throw)
   {
      f_TypeU = true;

      char szText[1024];
      sprintf(szText, szFormat, szString);                  // compose error description
      LastExceptionU = TExceptionU(szText);                 // instantiate
      throw LastExceptionU;                                 // throw
   }
}

// helper function like above
void ThrowTypeU(const char* szFormat, const char* szString)
{
   f_TypeU = true;

   char szText[1024];
   sprintf(szText, szFormat, szString);                     // compose error description
   LastExceptionU = TExceptionU(szText);                    // instantiate
   throw LastExceptionU;                                    // throw
}