//+------------------------------------------------------------------+
//|                                             ConfigLoaderDemo.mq5 |
//+------------------------------------------------------------------+

#property strict

#include <ConfigLoader\StrategyConfig.mqh>
#include <ConfigLoader\JsonConfigLoader.mqh>
#include <Canvas\Canvas.mqh>

//--- input parameters
input string InpConfigFile = "ConfigLoader\\StrategyConfig.json"; // JSON file in MQL5\Files
input ushort InpReloadKey  = 82;                     // Key code for hot-reload ('R')
input int    InpDashWidth  = 320;                    // Dashboard width in pixels
input int    InpDashHeight = 170;                    // Dashboard height in pixels

//--- module-scope state
SStrategyConfig   g_config;
CJsonConfigLoader g_loader;
CCanvas           g_canvas;

//+------------------------------------------------------------------+
//| Draws the current configuration values onto the canvas           |
//+------------------------------------------------------------------+
void DrawDashboard(void)
  {
   g_canvas.Erase(ColorToARGB(clrWhiteSmoke, 230));
   g_canvas.FontSet("Consolas", 14);
   g_canvas.TextOut(10, 8, "Strategy Config Dashboard", ColorToARGB(clrBlack, 255));

   string lines[7];
   lines[0] = "Lot size:     " + DoubleToString(g_config.m_lot_size, 2);
   lines[1] = "Stop loss:    " + DoubleToString(g_config.m_stop_loss_pts, 1) + " pts";
   lines[2] = "Take profit:  " + DoubleToString(g_config.m_take_profit_pts, 1) + " pts";
   lines[3] = "Max spread:   " + DoubleToString(g_config.m_max_spread_pts, 1) + " pts";
   lines[4] = "Magic number: " + IntegerToString(g_config.m_magic_number);
   lines[5] = "Comment:      " + g_config.m_comment;
   lines[6] = "Last loaded:  " + TimeToString(g_loader.GetLastLoadTime(), TIME_DATE | TIME_SECONDS);

   int y = 36;
   for(int i = 0; i < 7; i++)
     {
      g_canvas.TextOut(10, y, lines[i], ColorToARGB(clrBlack, 255));
      y += 18;
     }

   g_canvas.Update();
  }

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   g_config = SStrategyConfig::Default();
   g_loader.SetFilePath(InpConfigFile);

   if(g_loader.Load(g_config))
      Print("OnInit - configuration loaded successfully from ", InpConfigFile);
   else
      Print("OnInit - configuration load failed, using default values");

   g_config.Print();

   if(!g_canvas.CreateBitmapLabel("ConfigDashboard", 10, 10, InpDashWidth, InpDashHeight,
                                  COLOR_FORMAT_ARGB_NORMALIZE))
     {
      Print("OnInit - failed to create dashboard canvas, error code ", GetLastError());
      return(INIT_FAILED);
     }

   DrawDashboard();
   EventSetTimer(5);

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
   g_canvas.Destroy();
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  }

//+------------------------------------------------------------------+
//| Timer function - keeps the dashboard values current              |
//+------------------------------------------------------------------+
void OnTimer()
  {
   DrawDashboard();
  }

//+------------------------------------------------------------------+
//| ChartEvent function - listens for the hot-reload hotkey          |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   if(id == CHARTEVENT_KEYDOWN && lparam == InpReloadKey)
     {
      SStrategyConfig previous = g_config;

      if(g_loader.Load(g_config))
        {
         Print("OnChartEvent - hot-reload succeeded at ",
               TimeToString(g_loader.GetLastLoadTime(), TIME_DATE | TIME_SECONDS));
         Print("OnChartEvent - lot size old=", DoubleToString(previous.m_lot_size, 2),
               " new=", DoubleToString(g_config.m_lot_size, 2));
         Print("OnChartEvent - stop loss old=", DoubleToString(previous.m_stop_loss_pts, 1),
               " new=", DoubleToString(g_config.m_stop_loss_pts, 1));
         Print("OnChartEvent - take profit old=", DoubleToString(previous.m_take_profit_pts, 1),
               " new=", DoubleToString(g_config.m_take_profit_pts, 1));
         DrawDashboard();
        }
      else
        {
         Print("OnChartEvent - hot-reload failed, retaining previous configuration");
         g_config = previous;
        }
     }
  }
//+------------------------------------------------------------------+