//+------------------------------------------------------------------+
//|                                      DoubleBottomRecorderEA.mq5  |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                          https://www.mql5.com/en/users/lynnchris |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com/en/users/lynnchris"
#property version   "1.0"
#property strict

#include <PatternRecorder/PatternLibrary.mqh>
#include <PatternRecorder/PatternRecorderPanel.mqh>

CPatternLibrary *g_library = NULL;
CRecorderPanel  *g_panel = NULL;

//--- Inputs control whether and where the chart panel is created
input bool Input_ShowPanel = true;
input int  Input_PanelX = 20;
input int  Input_PanelY = 20;

//+------------------------------------------------------------------+
//| Initializes the recorder expert                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Create the in-memory library and load previously saved samples
   g_library = new CPatternLibrary(PATTERN_DOUBLE_BOTTOM_CANDIDATE);
   if(g_library == NULL)
      return(INIT_FAILED);
   if(!g_library.IsReady())
     {
      Print("Library unavailable: another recorder may hold the storage lock.");
      delete g_library;
      g_library = NULL;
      return(INIT_FAILED);
     }
   Print("Pattern Library loaded. Samples found: ", g_library.GetSampleCount());

//--- Create the optional chart interface
   if(Input_ShowPanel)
     {
      //--- Stop initialization if either allocation or UI creation fails
      g_panel = new CRecorderPanel();
      if(g_panel == NULL || !g_panel.Create(g_library, 0, 0, Input_PanelX, Input_PanelY))
        {
         if(g_panel != NULL)
           {
            delete g_panel;
            g_panel = NULL;
           }
         delete g_library;
         g_library = NULL;
         return(INIT_FAILED);
        }
     }
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Releases resources owned by the recorder expert                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Release owned objects when the EA leaves the chart
   if(g_panel != NULL)
     {
      delete g_panel;
      g_panel = NULL;
     }
   if(g_library != NULL)
     {
      delete g_library;
      g_library = NULL;
     }
  }

//+------------------------------------------------------------------+
//| Forwards chart events to the recorder panel                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam,
                  const double &dparam, const string &sparam)
  {
//--- Forward mouse and object events to the panel controller
   if(g_panel != NULL)
      g_panel.OnChartEvent(id, lparam, dparam, sparam);
  }

//+------------------------------------------------------------------+