////////////////////////////////////////////////////////////////////////////////
// 
// ScreenReport.hh 
//
//    produced: 2024-04-15 jr
//
////////////////////////////////////////////////////////////////////////////////
#ifndef SCREENREPORT_HH
#define SCREENREPORT_HH

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>

#include "Signal.hh"
#include "Global.hh"
#include "CommandlineOptions.hh"
#include "ContainerIO.hh"
#include "Message.hh"

typedef std::vector<int> progress_vector_type;

namespace topcom {

  // the following class can be used to organize the reporting
  // of intermediate results to the screen:
  class ScreenReport {
  public:
    static const char*     field_separator;
  private:
    long                   _countdown;
    long                   _old_count;
  public:
    inline ScreenReport();
    inline ScreenReport(const ScreenReport&);
    inline ScreenReport& operator=(const ScreenReport&);

    // report only according to frequency settings:
    bool decide_report(const size_type);
    Message& execute_ext_worker_report(Message&,
				       const int,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const progress_vector_type&) const;
    Message& execute_ext_master_report(Message&,
				       const int,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type,
				       const size_type) const;
    Message& execute_flip_distclass_report(Message&,
					   const int,
					   const size_type,
					   const size_type,
					   const size_type,
					   const size_type,
					   const size_type,
					   const size_type) const;

    Message& execute_flip_node_report(Message&,
				      const int,
				      const size_type,
				      const size_type,
				      const size_type,
				      const size_type,
				      const size_type,
				      const size_type) const;
    
    // report the various possible numbers inside a data line:
    Message& report_master(Message&) const;
    Message& report_workerID(Message&, int) const;    
    Message& report_nextdistclass(Message&) const;
    Message& report_indistclass(Message&) const;
    Message& report_nodecount(Message&, const size_type) const;
    Message& report_symcount(Message&, const size_type) const;
    Message& report_totalcount(Message&, const size_type) const;
    Message& report_deadendcount(Message&, const size_type) const;
    Message& report_earlydeadendcount(Message&, const size_type) const;
    Message& report_storedcount(Message&, const size_type) const;
    Message& report_flipcount(Message&, const size_type) const;
    Message& report_flipdist(Message&, const size_type) const;
    Message& report_workbuffersize(Message&, const size_type) const;
    Message& report_minworkbuffersize(Message&, const size_type) const;
    Message& report_nodebudget(Message&, const size_type) const;
    Message& report_idlethreads(Message&, const int idlethreads) const;
    Message& report_progressvector(Message&, const progress_vector_type& progressvector) const;
  };

  inline ScreenReport::ScreenReport() :
    _countdown(CommandlineOptions::report_frequency()),
    _old_count(0) {}
  inline ScreenReport::ScreenReport(const ScreenReport& sr) :
    _countdown(sr._countdown),
    _old_count(sr._old_count) {}
  inline ScreenReport& ScreenReport::operator=(const ScreenReport& sr) {
    if (this == &sr) {
      return *this;
    }
    _countdown = sr._countdown;
    _old_count = sr._old_count; 
    return *this;
  }
  
}; // namespace topcom



#endif

// eof ScreenReport.hh
