
#ifndef __WFX_LANG_WFXEXCEPTION_H__
#define __WFX_LANG_WFXEXCEPTION_H__

#include <WFX/WFXIncludes.h>

namespace WFX {

    namespace lang {
    
        /**
         * basic exception
         *
         * TODO: Copy constructor, destructor
         */
        class WFXException  {
            public:
                /**
                 * CTor
                 *
                 * @param: text - Error text
                 * @param: file - File the exception occured in
                 * @param: line - Line the exception occured in
                 * @param: func - function the exception occured in
                 * @param: ex - exception to be used as a base
                 */
                WFXException(const Char* text, const Char* file, const Int line, const Char* func);
                WFXException(const WFXException& ex, const Char* text, const Char* file, const Int line, const Char* func);

                /**
                 * Ctor
                 *
                 * @param: ex - Exception to be copied
                 */
                WFXException(const WFXException& ex);

                /**
                 * adds a callentry to the stack
                 */
                void addCallEntry(const std::string& text, const std::string& file, Int line, const std::string func);

                /**
                 * prints the stack trace
                 */
                void printStackTrace();
            protected:

            private:
                /** defines a call stack element */
                struct CallEntry {
                    std::string Text;
                    std::string File;
                    Int Line;
                    std::string Function;
                };

                /** Call stack */
                std::list<CallEntry>* CallStack;

                /** inits the exception */
                void init(const Char* text, const Char* file, const Int line, const Char* func);
                
        };
   
    }
}

//convienience
//TODO: __FUNCTION__ is gcc specific
#define THROW(message) { std::stringstream ss; ss << message; throw WFX::lang::WFXException(ss.str().data(), __FILE__, __LINE__, __FUNCTION__); }
#define RETHROW(ex,message) { std::stringstream ss; ss << message; throw WFX::lang::WFXException(ex, ss.str().data(), __FILE__, __LINE__, __FUNCTION__); }

#endif //include guard

