//+------------------------------------------------------------------+
//|                                         DrawdownTablePrinter.mqh |
//+------------------------------------------------------------------+
#ifndef DRAWDOWNTABLEPRINTER_MQH
#define DRAWDOWNTABLEPRINTER_MQH

#include "DrawdownTypes.mqh"

//+------------------------------------------------------------------+
//| CDrawdownTablePrinter                                            |
//| Prints a table of drawdown episodes to the terminal log, sorted  |
//| by duration in descending order.                                 |
//+------------------------------------------------------------------+
class CDrawdownTablePrinter
  {
private:
   string                PadRight(string value, int width) const;
   void                  SortByDuration(CDrawdownEpisode &episodes[], int count) const;

public:
                     CDrawdownTablePrinter(void);
                    ~CDrawdownTablePrinter(void);

   void                  Print(const CDrawdownEpisode &episodes_in[], int count) const;
  };

//+------------------------------------------------------------------+
//| Constructor: no member state to initialize.                      |
//+------------------------------------------------------------------+
CDrawdownTablePrinter::CDrawdownTablePrinter(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor: no dynamic resources to release.                     |
//+------------------------------------------------------------------+
CDrawdownTablePrinter::~CDrawdownTablePrinter(void)
  {
  }

//+------------------------------------------------------------------+
//| Print                                                            |
//| Copies the incoming episodes, sorts the copy by duration in      |
//| descending order, and prints a fixed-width table with columns for|
//| start date, depth percentage, duration in days, and status.      |
//+------------------------------------------------------------------+
void CDrawdownTablePrinter::Print(const CDrawdownEpisode &episodes_in[], int count) const
  {
//--- copy the episodes so sorting never mutates the caller's own array
   CDrawdownEpisode sorted[];
   ::ArrayResize(sorted, count);
   for(int i = 0; i < count; i++)
      sorted[i] = episodes_in[i];
   SortByDuration(sorted, count);
//--- print the header row with fixed-width column labels
   string header = PadRight("Start", 12) + PadRight("Depth %", 10) +
                   PadRight("Duration(d)", 14) + PadRight("Status", 10);
   ::Print(header);
//--- print one row per episode, longest duration first
   for(int i = 0; i < count; i++)
     {
      string row = PadRight(::TimeToString(sorted[i].start_time, TIME_DATE), 12) +
                   PadRight(::DoubleToString(sorted[i].depth_percent, 1), 10) +
                   PadRight(::DoubleToString(sorted[i].duration_days, 1), 14) +
                   PadRight(sorted[i].is_open ? "Open" : "Recovered", 10);
      ::Print(row);
     }
  }

//+------------------------------------------------------------------+
//| SortByDuration                                                   |
//| Sorts episodes into descending order by duration_days using a    |
//| simple bubble sort.                                              |
//+------------------------------------------------------------------+
void CDrawdownTablePrinter::SortByDuration(CDrawdownEpisode &episodes[], int count) const
  {
   CDrawdownEpisode temp;
   for(int i = 0; i < count - 1; i++)
     {
      for(int j = 0; j < count - 1 - i; j++)
        {
         if(episodes[j].duration_days < episodes[j + 1].duration_days)
           {
            temp             = episodes[j];
            episodes[j]      = episodes[j + 1];
            episodes[j + 1]  = temp;
           }
        }
     }
  }

//+------------------------------------------------------------------+
//| PadRight                                                         |
//| Pads a string with trailing spaces up to the given width, or     |
//| returns the original string unchanged if it already meets or     |
//| exceeds that width.                                              |
//+------------------------------------------------------------------+
string CDrawdownTablePrinter::PadRight(string value, int width) const
  {
   int need = width - ::StringLen(value);
   if(need <= 0)
      return(value);
   string result = value;
   for(int i = 0; i < need; i++)
      result += " ";
   return(result);
  }

#endif // DRAWDOWNTABLEPRINTER_MQH
//+------------------------------------------------------------------+