#property copyright "FX Omoshiro Lab"
#property version   "1.00"
#property description "A deterministic lab for inspecting values while debugging MQL5"

input int    InpLeft=7;
input int    InpRight=5;
input int    InpFactor=4;
input int    InpAdjustment=3;
input string InpImageName="106-metaeditor-debug-watch-lab.png";

bool g_finished=false;

int AddValues(const int left,const int right)
  {
   return left+right;
  }

int MultiplyValue(const int value,const int factor)
  {
   return value*factor;
  }

void DrawLabel(const string name,const int y,const string text,const color clr)
  {
   if(ObjectFind(0,name)<0 && !ObjectCreate(0,name,OBJ_LABEL,0,0,0))
     {
      PrintFormat("MQL106_FAIL ObjectCreate name=%s error=%d",name,GetLastError());
      return;
     }
   ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,20);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,12);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   ObjectSetString(0,name,OBJPROP_FONT,"Consolas");
   ObjectSetString(0,name,OBJPROP_TEXT,text);
  }

void OnTimer()
  {
   if(g_finished) return;

   // Set a debugger breakpoint on this line to inspect the input values.
   const int subtotal=AddValues(InpLeft,InpRight);
   // Step into MultiplyValue() here, or step over it and inspect scaled.
   const int scaled=MultiplyValue(subtotal,InpFactor);
   const int result=scaled-InpAdjustment;
   const int expected=InpLeft*InpFactor+InpRight*InpFactor-InpAdjustment;
   const bool verified=(result==expected);

   DrawLabel("MQL106_TITLE",20,"MetaEditor debugger lab | synthetic integer inputs",clrWhite);
   DrawLabel("MQL106_BREAK",52,"Breakpoint: inspect left="+IntegerToString(InpLeft)+
             " right="+IntegerToString(InpRight)+" before AddValues()",clrAqua);
   DrawLabel("MQL106_STEP",82,"subtotal = "+IntegerToString(InpLeft)+" + "+
             IntegerToString(InpRight)+" = "+IntegerToString(subtotal),clrLime);
   DrawLabel("MQL106_CALL",112,"MultiplyValue("+IntegerToString(subtotal)+", "+
             IntegerToString(InpFactor)+") = "+IntegerToString(scaled),clrGold);
   DrawLabel("MQL106_RESULT",142,"result = "+IntegerToString(scaled)+" - "+
             IntegerToString(InpAdjustment)+" = "+IntegerToString(result),clrWhite);
   DrawLabel("MQL106_CHECK",172,verified ? "Independent formula check: PASS" : "Independent formula check: FAIL",
             verified ? clrLime : clrTomato);
   DrawLabel("MQL106_KEYS",212,"F9 breakpoint | F5 debug | F10 step over | F11 step into",clrSilver);
   ChartRedraw(0);

   if(!verified)
     {
      PrintFormat("MQL106_FAIL left=%d right=%d factor=%d adjustment=%d result=%d expected=%d",
                  InpLeft,InpRight,InpFactor,InpAdjustment,result,expected);
      return;
     }

   PrintFormat("MQL106_SUMMARY left=%d right=%d subtotal=%d factor=%d scaled=%d adjustment=%d result=%d expected=%d verified=true",
               InpLeft,InpRight,subtotal,InpFactor,scaled,InpAdjustment,result,expected);
   ResetLastError();
   if(ChartScreenShot(0,InpImageName,1200,630,ALIGN_LEFT))
     {
      Print("captured=true error=0");
      g_finished=true;
      EventKillTimer();
      return;
     }
   PrintFormat("MQL106_WAIT ChartScreenShot error=%d",GetLastError());
  }

int OnInit()
  {
   ChartSetInteger(0,CHART_COLOR_BACKGROUND,clrBlack);
   ChartSetInteger(0,CHART_COLOR_FOREGROUND,clrLime);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrBlack);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrBlack);
   ChartSetInteger(0,CHART_COLOR_CHART_UP,clrBlack);
   ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrBlack);
   ChartSetInteger(0,CHART_SHOW_GRID,false);
   ChartSetInteger(0,CHART_SHOW_OHLC,false);
   ChartSetInteger(0,CHART_SHIFT,false);
   EventSetTimer(2);
   return INIT_SUCCEEDED;
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
   ObjectDelete(0,"MQL106_TITLE");
   ObjectDelete(0,"MQL106_BREAK");
   ObjectDelete(0,"MQL106_STEP");
   ObjectDelete(0,"MQL106_CALL");
   ObjectDelete(0,"MQL106_RESULT");
   ObjectDelete(0,"MQL106_CHECK");
   ObjectDelete(0,"MQL106_KEYS");
  }

void OnTick() {}
