//------------------------------------------------------------------------------
//    module exception.h                                                      //
//                                                                            //
//    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 by Lars Haendel                                      //
//    home: www.newty.de                                                      //
//                                                                            //
//    This program is free software; you can redistribute it and/or modify    //
//    it under the terms of the GNU General Public License as published by    //
//    the Free Software Foundation as version 2 of the License.               //
//                                                                            //
//    This program is distributed in the hope that it will be useful,         //
//    but WITHOUT ANY WARRANTY; without even the implied warranty of          //
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
//    GNU General Public License for more details.                            //
//                                                                            //
//    You should have received a copy of the GNU General Public License       //
//    along with this program; if not, write to the Free Software             //
//    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               //
//                                                                            //
//------------------------------------------------------------------------------

#ifndef EXCEPTION_H
#define EXCEPTION_H

#include <fstream>         // due to:     strcpy()  note: used instead of string.h which produces annoying warnings if
                           //                             compiled with BC5.02
#include <stdio>
#include "defines.h"       //             definition of DEBUG




//----------------------------------------------------------------------------------------------------------------------
// type 'A' and 'B' exception class: intended for program development only. Encapsulates the name of the function which
// throws the exception, the name of the file where this function is in and and an error description. (see below for
// the different types)
class TExceptionAB
{
private:
   char szMessage[STS];
   char szFunction[STS];      // function in which exception was raised and ...
   char szModule[STS];        // file in which this function is in

   mutable char szText[STS];  // error text composed from the above in member GetErrorText()
public:

   // constructor/destructor
   TExceptionAB(const char* _szMessage, const char* _szFunction=NULL, const char* _szModule=NULL); //
   TExceptionAB(){};                                                                               // copy constructor

   ~TExceptionAB(){};

   const char* GetErrorText(const bool& f_Verbose=true) const;  // compose error description
};



//----------------------------------------------------------------------------------------------------------------------
// type 'U' exception class: intended to be catched and shown to the user. Holds just an error description
class TExceptionU
{
private:
   char szMessage[STS];
public:

   // constructor/destructor
   TExceptionU(const char* _szMessage) { strcpy(szMessage, _szMessage); };       //
   TExceptionU(){};                                                              // copy constructor
   ~TExceptionU(){};

   const char* GetErrorText() const;  // get error description
};



//----------------------------------------------------------------------------------------------------------------------
// helper functions used to throw exceptions

// note: the difference between type 'A' and 'B' is, that type 'B' exceptions are only thrown if DEBUG is defined while
//       type 'A' is always thrown. Try to use type 'A' where ever it is possible, i.e. if the performance penalty is
//       acceptable.
void ThrowTypeA(const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL);
void IfTrueThrowTypeA(const bool f_Throw, const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL);

#ifdef DEBUG
void ThrowTypeB(const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL);
void IfTrueThrowTypeB(const bool f_Throw, const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL);
#else
inline void ThrowTypeB(const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL){};
inline void IfTrueThrowTypeB(const bool f_Throw, const char* szMessage, const char* szFunction=NULL, const char* szModule=NULL){};
#endif

void ThrowTypeU(const char* szMessage);
void IfTrueThrowTypeU(const bool f_Throw, const char* szMessage);

// throw type 'U' exception. 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 ThrowTypeU(const char* szFormat, const char* szString);
void IfTrueThrowTypeU(const bool f_Throw, const char* szFormat, const char* szString);


//----------------------------------------------------------------------------------------------------------------------
// functions to check globals for last exception
const bool& IsTypeUExcpetion();
const bool& IsTypeABExcpetion();
const TExceptionAB& GetLastExcpetionAB();
const TExceptionU&  GetLastExcpetionU ();
#endif