/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkFEMException.h,v $
  Language:  C++
  Date:      $Date: 2003/09/10 14:29:41 $
  Version:   $Revision: 1.9 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __itkFEMException_h
#define __itkFEMException_h

#include <typeinfo>
#include <string>

#include "itkMacro.h"

namespace itk {
namespace fem {

/**
 * \file itkFEMException.h
 * \brief Declaration of several exception classes that are used
    within the FEM code.
 */

/**
 * \class FEMException
 * \brief Base class for all exception's that can occur within FEM classes.
 */
class FEMException : public itk::ExceptionObject
{
public:
  /**
   * Constructor. Must provide a string, that specifies name of
   * the file where the exception occured and an integer for the
   * line number. An optional argument specifies the location
   * (usually the name of the class and member function). Normally
   * you should use __FILE__ and __LINE__ macros to specify file name
   * and line number.
   */
  FEMException(const char *file, unsigned int lineNumber, std::string location="Unknown");

  /** Virtual destructor needed for subclasses. Has to have empty throw(). */
  virtual ~FEMException() throw() {}

  /** Type related information. */
  itkTypeMacro(FEMException, ExceptionObject);
};




/**
 * \class FEMExceptionIO
 * \brief Base class for all IO exception's that can occur within FEM classe.
 *
 * This class is normally used when reading or writing objects from/to stream.
 */
class FEMExceptionIO : public FEMException
{
public:
  /**
   * Constructor. In order to construct this exception object, four parameters
   * must be provided: file, lineNumber, location and a detailed description
   * of the exception.
   */
  FEMExceptionIO(const char *file, unsigned int lineNumber, std::string location, std::string moreDescription);

  /** Virtual destructor needed for subclasses. Has to have empty throw(). */
  virtual ~FEMExceptionIO() throw() {}
  
  /** Type related information. */
  itkTypeMacro(FEMExceptionIO,FEMException);
};




/**
 * \class FEMExceptionWrongClass
 * \brief Bad object exception.
 * 
 * This exception occures, when a the pointer that was passed to a
 * function or member, was pointing to the wrong class of object.
 * Usially this means that the dynamic_cast operator failed.
 * This exception object is normally  generated by catching the
 * std::bad_cast exception.
 *
 * FIXME: Note that there are big differences between compilers
 * when it comes to catching standard exceptions. MSVC, for
 * example DOESN'T properly catch std::bad_cast generated by
 * a failed dynamic_cast operator. It does, however catch the
 * std:exception. Update the bad_cast in ALL files to
 * accomodate this differences. Currently they are ignored.
 */
class FEMExceptionWrongClass : public FEMException
{
public:
  FEMExceptionWrongClass(const char *file, unsigned int lineNumber, std::string location);

  /** Virtual destructor needed for subclasses. Has to have empty throw(). */
  virtual ~FEMExceptionWrongClass() throw() {}
  
  /** Type related information. */
  itkTypeMacro(FEMExceptionWrongClass,FEMException);
};




/**
 * \class FEMExceptionObjectNotFound
 * \brief Object not found exception.
 *
 * This exception occures, when a search for an object with given
 * global number was unsuccessful.
 */
class FEMExceptionObjectNotFound : public FEMException
{
public:
  FEMExceptionObjectNotFound(const char *file, unsigned int lineNumber, std::string location, std::string baseClassName, int GN);

  /** Virtual destructor needed for subclasses. Has to have empty throw(). */
  virtual ~FEMExceptionObjectNotFound() throw() {}

  /** Type related information. */
  itkTypeMacro(FEMExceptionObjectNotFound,FEMException);

  /**
   * Base class of the searched object.
   */
  std::string m_baseClassName;
  int m_GN;

};




/**
 * \class FEMExceptionSolution
 * \brief Base class for all exceptions that can occur when solving FEM problem.
 *
 * This class is normally used when an error occurs while the problem is
 * already in memory and something went wrong while trying to solve it.
 */
class FEMExceptionSolution : public FEMException
{
public:
  /**
   * Constructor. In order to construct this exception object, four parameters
   * must be provided: file, lineNumber, location and a detailed description
   * of the exception.
   */
  FEMExceptionSolution(const char *file, unsigned int lineNumber, std::string location, std::string moreDescription);
 
  /** Virtual destructor needed for subclasses. Has to have empty throw(). */
  virtual ~FEMExceptionSolution() throw() {}
  
  /** Type related information. */
  itkTypeMacro(FEMExceptionSolution,FEMException);
  
};




}} // end namespace itk::fem

#endif // #ifndef __itkFEMException_h
