#ifndef INCLUDED_ERR_
#define INCLUDED_ERR_

#include <iosfwd>

#include <bobcat/mstream>

#include "../typedefs/typedefs.h"

    // err messages to cerr, messages may end in '\n'

class Err
{
    static char const *s_plain[];
    static char const *s_context[];
    static char const *s_src[];

    static LineInfo const *s_lineInfo;             // last set LineInfo
    static bool s_handle;                          // handle a context message

    public:
        enum Plain                          // plain errors,
        {                                   // no line context
            CUMPROB,
            INCIDENCE_SUM_PROB,
            MISSING_SPEC,
            MULTIPLY_SPECIFIED,
            CT_NO_SENS,
            UNDEFINED_SPEC,
            CUM_DEATH,
        };

        enum Context
        {
            AT_LEAST,
            CT_SENS,
            CT_SENS_RANGE,
            GROUP_NO_COLON,
            INVALID_TYPE,
            INVALID_VALUE,
            MODALITY_REPEATED,
            NEGATIVE,
            NOT_CONSECUTIVE,
            PROB_SUM,
            RANGE_0_1,
            ROUND_AGES_DONT_INC,
            ROUND_NONE,
            SPEC_ERROR,
            UNDEFINED_DIST,
            UNDEFINED_MODALITY,
            VSD_MISSING,
            LC_INVALID_MODALITY,
            BC_CT_INVALID,
            TABLEPARAMS
        };

        static char const *src(ParamsSrc type);

                    // merely the error message:
        static std::ostream &msg(Plain err);                            // 1.

                    // error msg + src and line nr, ending in ": "
        static std::ostream &msg(Context err);                          // 2.
        static void msgTxt(Context err);            // also inserts line txt

                    // msg(RANGE_0_1 using line)
        static void range();

                    // msg(NEGATIVE using line)
        static void negative();

                    // msg(AT_LEAST using line)
        static void atLeast(double minimum);

                    // msg(SPEC_ERROR using line
        static void specification();

                    // msg(MULTIPLY_SPECIFIED)
        static void multiplySpecified(LineInfoVect::const_iterator begin,
                                      LineInfoVect::const_iterator end,
                                      std::string const &sectionList);

        static LineInfo const *reset(LineInfo const &lineInfo);

        static std::string const &txt();

                                    // status of all operations since the
        static bool valid();        // last reset
};

inline bool Err::valid()
{
    return s_handle;
}

inline char const *Err::src(ParamsSrc type)
{
    return s_src[type];
}

inline void Err::msgTxt(Context err)
{
    msg(err) << '`' << s_lineInfo->txt << '\'' << std::endl;
}

inline std::string const &Err::txt()
{
    return s_lineInfo->txt;
}

#endif
