// $Id: runreport.h,v 1.21 2018/01/03 21:33:02 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


#ifndef RUNREPORT_H
#define RUNREPORT_H

#include <cmath>
#include <ctime>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "vectorx.h"
#include "stringx.h"
#include "timex.h"
#include "constants.h"

class ChainOut;
class ChainPack;
class Force;
class ForceSummary;

enum OnceKey{oncekey_OverflowOfSafeExpDiff,
             oncekey_UnderflowOfSafeExpDiff,
             oncekey_OverflowOfProductWithExp,
             oncekey_UnderflowOfProductWithExp};

typedef std::map<OnceKey, long> KeyToLongMap;
typedef std::map<OnceKey, long>::iterator KeyToLongMapiter;
typedef std::map<long, OnceKey> LongToKeyMap;
typedef std::map<long, OnceKey>::iterator LongToKeyMapiter;

/******************************************************************
This class manages runtime reports and provides runtime-report
information to the output manager.  It takes input from the
chain manager.  Key routines are PrintBar, meant to be called
repeatedly by the chain itself (for the scrolling bar);
MakeReport, which constructs a chain summary report, and
FormatReport, which prints it.  (The two are separate
so that the output reporter can take the results of MakeReport and
reformat them to its liking.)

Mary Kuhner       October 2000

Added prognosis of profiles October 2001 -- Mary Kuhner

******************************************************************/

class RunReport
{
  public:

    RunReport(const ForceSummary& fs, verbosity_type progress=NORMAL);
    ~RunReport() {};
    void SetBarParameters(long totsteps, long burn, long chno, long chtype);
    void PrintBar(long steps);
    void PrognoseRegion(const ChainPack& chpack, long region,
                        long steps, long total);
    void RecordProfileStart();
    void PrognoseProfiles(long thisprof, long totprofs);
    void PrognoseAll(const ChainPack& chpack, long thisreg, long totregs);
    void MakeReport(const ChainOut& chout) const;
    vector<string> FormatReport(const ChainOut& chout, bool current,
                                long linelength) const;
    void DisplayReport(const ChainOut& chout);

    //These functions are used by the rest of the program to communicate with
    // the user, according to the verbosity level set by the user, and sometimes
    // whether or not the NDEBUG flag is on.
    void ReportUrgent(const string& msg, bool printtime = true, long linelength=DEFLINELENGTH);
    void ReportNormal(const string& msg, bool printtime = true, long linelength=DEFLINELENGTH);
    void ReportNormal(const StringVec1d& msgs, bool printtime = true, long linelength=DEFLINELENGTH);
    void ReportChat(const string& msg, bool printtime = true, long linelength=DEFLINELENGTH);
    void ReportDebug(const string& msg, bool printtime = true, long linelength=DEFLINELENGTH);

    void ReportOnce(const string& msg, OnceKey key, bool doNormal);
    void SaveOutput(const string& msg, bool printtime = true);

    StringVec1d GetMessages() const {return m_messages;};
    KeyToLongMap GetKeyFrequencies() const {return m_keyfrequencies;};
    LongToKeyMap GetKeyIndices() const {return m_keyindices;};

  private:

    verbosity_type m_level;
    verbosity_type m_filelevel;
    // the following three are mutable so that a report can be prepared
    // and stored internally even in a const RunReport object
    mutable string       m_scalars;            // these three store run reports
    mutable StringVec1d  m_tables;
    const ForceSummary& m_forcesum;
    time_t       m_profilestart;       // time at which profiling began
    time_t       m_profiletotal;

    // these are used to control the scrolling bar
    long         m_totalsteps;
    long         m_chainno;
    long         m_counter_display_increment;
    string       m_chaintype;
    long         m_chaintype_num;
    long         m_burnin;
    double       m_burnpercent;

    //These are for saving the messages we get.
    StringVec1d  m_messages;
    KeyToLongMap m_keyfrequencies;
    LongToKeyMap m_keyindices;

    void AddForceToTable(const Force* force, StringVec1d& table,
                         const ChainOut& chout) const;
    void PrettyPrint(const string& msg, bool printtime, long linelength);

}; // RunReport

//------------------------------------------------------------------------------------
// These are tools for marking output (both header printed on screen at LAMARC startup
// and beginning of output file "outfile.txt") to indicate unambiguously whether any
// "unusual" debugging options are activated.  If all the relevant pre-processor flags
// are all in their usual states, no extra strings are printed.

bool DebuggingOptionsRunning();
string DebuggingOptionsString(unsigned long int & current_linecount);

//------------------------------------------------------------------------------------

#endif // RUNREPORT_H

//____________________________________________________________________________________
