//+------------------------------------------------------------------+
//|                               Pivots_Core_Structure_Advanced.mq5 |
//+------------------------------------------------------------------+
#property copyright "Custom MT5 Core Dashboard"
#property version   "4.0"
#property indicator_chart_window
#property indicator_plots 0

//--- Input Parameters ---
input group "--- General Settings ---";
input bool     DrawHistory             = true;
input int      HistoryDays             = 60; 
input int      HistoryQuarters         = 8;  
input bool     DisplayLables           = true; 
input int      Length_Daily_Bars       = 5;   
input int      Length_Weekly_Bars      = 10;  
input int      Length_Monthly_Bars     = 15;  
input int      Length_Quarterly_Bars   = 20;

input group "--- Line Colors ---";
input color    Color_Open              = clrGold;
input color    Color_Close             = clrOrange;
input color    Color_Pivot             = clrMagenta;
input color    Color_High              = clrAqua;
input color    Color_Low               = clrRed;
input color    Color_Midpoint          = clrSilver;

input group "--- Line Textures (Styles) ---";
input ENUM_LINE_STYLE Style_Open       = STYLE_SOLID;
input ENUM_LINE_STYLE Style_Close      = STYLE_DASH;
input ENUM_LINE_STYLE Style_Pivot      = STYLE_SOLID;
input ENUM_LINE_STYLE Style_High       = STYLE_DOT;
input ENUM_LINE_STYLE Style_Low        = STYLE_DOT;
input ENUM_LINE_STYLE Style_Midpoint   = STYLE_DASHDOT;

input group "--- Line Thickness ---";
input int      Thick_Open              = 1;
input int      Thick_Close             = 1;
input int      Thick_Pivot             = 2;
input int      Thick_High              = 1;
input int      Thick_Low               = 1;
input int      Thick_Midpoint          = 1;

//--- Global GUI & Logic Variables ---
string ObjPrefix = "CoreAdv_"; 
string GUIPrefix = "CGUIAdv_";

// 4x2 Matrix Toggles
bool ShowDOCP = true, ShowWOCP = true, ShowMOCP = true, ShowQOCP = true;
bool ShowDHLM = true, ShowWHLM = true, ShowMHLM = true, ShowQHLM = true;

int  GUI_X = 20;
int  GUI_Y = 20;
bool GUI_Min = false;

bool isDragging = false;
int  dragOffsetX = 0;
int  dragOffsetY = 0;

string gv_DOCP, gv_WOCP, gv_MOCP, gv_QOCP;
string gv_DHLM, gv_WHLM, gv_MHLM, gv_QHLM;
string gv_X, gv_Y, gv_Min;

//+------------------------------------------------------------------+
int OnInit() 
  { 
   ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
   string cid = IntegerToString(ChartID());
   
   gv_DOCP="C_DOCP_"+cid; gv_WOCP="C_WOCP_"+cid; gv_MOCP="C_MOCP_"+cid; gv_QOCP="C_QOCP_"+cid;
   gv_DHLM="C_DHLM_"+cid; gv_WHLM="C_WHLM_"+cid; gv_MHLM="C_MHLM_"+cid; gv_QHLM="C_QHLM_"+cid;
   gv_X="CXA_"+cid; gv_Y="CYA_"+cid; gv_Min="CMinA_"+cid;

   if(GlobalVariableCheck(gv_DOCP)) ShowDOCP = (bool)GlobalVariableGet(gv_DOCP);
   if(GlobalVariableCheck(gv_WOCP)) ShowWOCP = (bool)GlobalVariableGet(gv_WOCP);
   if(GlobalVariableCheck(gv_MOCP)) ShowMOCP = (bool)GlobalVariableGet(gv_MOCP);
   if(GlobalVariableCheck(gv_QOCP)) ShowQOCP = (bool)GlobalVariableGet(gv_QOCP);
   
   if(GlobalVariableCheck(gv_DHLM)) ShowDHLM = (bool)GlobalVariableGet(gv_DHLM);
   if(GlobalVariableCheck(gv_WHLM)) ShowWHLM = (bool)GlobalVariableGet(gv_WHLM);
   if(GlobalVariableCheck(gv_MHLM)) ShowMHLM = (bool)GlobalVariableGet(gv_MHLM);
   if(GlobalVariableCheck(gv_QHLM)) ShowQHLM = (bool)GlobalVariableGet(gv_QHLM);
   
   if(GlobalVariableCheck(gv_X)) GUI_X = (int)GlobalVariableGet(gv_X);
   if(GlobalVariableCheck(gv_Y)) GUI_Y = (int)GlobalVariableGet(gv_Y);
   if(GlobalVariableCheck(gv_Min)) GUI_Min = (bool)GlobalVariableGet(gv_Min);

   CreateGUI();
   return(INIT_SUCCEEDED); 
  }

void OnDeinit(const int reason) 
  { 
   ObjectsDeleteAll(0, ObjPrefix); 
   ObjectsDeleteAll(0, GUIPrefix);
   if(reason == REASON_REMOVE)
     {
      GlobalVariableDel(gv_DOCP); GlobalVariableDel(gv_WOCP); GlobalVariableDel(gv_MOCP); GlobalVariableDel(gv_QOCP);
      GlobalVariableDel(gv_DHLM); GlobalVariableDel(gv_WHLM); GlobalVariableDel(gv_MHLM); GlobalVariableDel(gv_QHLM);
      GlobalVariableDel(gv_X); GlobalVariableDel(gv_Y); GlobalVariableDel(gv_Min);
     }
  }

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   if(id == CHARTEVENT_MOUSE_MOVE)
     {
      int x = (int)lparam, y = (int)dparam;
      int mouse_state = (int)StringToInteger(sparam);
      bool left_click = (mouse_state & 1) == 1;

      if(left_click)
        {
         if(!isDragging) { if(x >= GUI_X && x <= GUI_X + 500 && y >= GUI_Y && y <= GUI_Y + 25) { isDragging = true; dragOffsetX = x - GUI_X; dragOffsetY = y - GUI_Y; } }
         else { GUI_X = x - dragOffsetX; GUI_Y = y - dragOffsetY; UpdateGUI_Positions(); ChartRedraw(); }
        }
      else { if(isDragging) { isDragging = false; GlobalVariableSet(gv_X, GUI_X); GlobalVariableSet(gv_Y, GUI_Y); } }
     }

   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      bool needsRedraw = false;
      bool needsPosUpdate = false;
      
      if(sparam == GUIPrefix + "btnMin") { GUI_Min = !GUI_Min; needsPosUpdate = true; GlobalVariableSet(gv_Min, GUI_Min); }
      else if(sparam == GUIPrefix + "btnDOCP") { ShowDOCP = !ShowDOCP; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnWOCP") { ShowWOCP = !ShowWOCP; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnMOCP") { ShowMOCP = !ShowMOCP; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnQOCP") { ShowQOCP = !ShowQOCP; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnDHLM") { ShowDHLM = !ShowDHLM; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnWHLM") { ShowWHLM = !ShowWHLM; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnMHLM") { ShowMHLM = !ShowMHLM; needsRedraw = true; }
      else if(sparam == GUIPrefix + "btnQHLM") { ShowQHLM = !ShowQHLM; needsRedraw = true; }

      if(needsPosUpdate) { UpdateGUI_Positions(); ObjectSetInteger(0, sparam, OBJPROP_STATE, false); ChartRedraw(); }

      if(needsRedraw)
        {
         GlobalVariableSet(gv_DOCP, (double)ShowDOCP); GlobalVariableSet(gv_WOCP, (double)ShowWOCP); 
         GlobalVariableSet(gv_MOCP, (double)ShowMOCP); GlobalVariableSet(gv_QOCP, (double)ShowQOCP);
         GlobalVariableSet(gv_DHLM, (double)ShowDHLM); GlobalVariableSet(gv_WHLM, (double)ShowWHLM); 
         GlobalVariableSet(gv_MHLM, (double)ShowMHLM); GlobalVariableSet(gv_QHLM, (double)ShowQHLM);
         
         UpdateGUI_State();
         RedrawIndicator(false); 
         ObjectSetInteger(0, sparam, OBJPROP_STATE, false);
         ChartRedraw();
        }
     }
  }

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[])
  {
   static datetime last_bar_time = 0;
   datetime curr_bar_time = iTime(NULL, 0, 0);
   if(prev_calculated > 0 && curr_bar_time == last_bar_time) return(rates_total); 
   last_bar_time = curr_bar_time;
   if(prev_calculated == 0) RedrawIndicator(false); 
   else RedrawIndicator(true);  
   return(rates_total);
  }

void RedrawIndicator(bool onlyCurrentBar)
  {
   if(!onlyCurrentBar) ObjectsDeleteAll(0, ObjPrefix); 
   datetime baseTime = iTime(NULL, 0, 0);
   int sec = PeriodSeconds(_Period);
   
   CalculateLevels(PERIOD_D1, "D", onlyCurrentBar, baseTime + sec * Length_Daily_Bars, ShowDOCP, ShowDHLM);
   CalculateLevels(PERIOD_W1, "W", onlyCurrentBar, baseTime + sec * Length_Weekly_Bars, ShowWOCP, ShowWHLM);
   CalculateLevels(PERIOD_MN1, "M", onlyCurrentBar, baseTime + sec * Length_Monthly_Bars, ShowMOCP, ShowMHLM);
   CalculateQuarterly(onlyCurrentBar, baseTime + sec * Length_Quarterly_Bars, ShowQOCP, ShowQHLM);
  }

// ---> Fixed Enum Parameter applied here <---
void CalculateLevels(ENUM_TIMEFRAMES timeframe, string timeframePrefix, bool onlyCurrentBar, datetime currentLineEnd, bool showOCP, bool showHLM)
  {
   datetime cutoffTime = TimeCurrent() - (HistoryDays * 86400);
   int limit = DrawHistory ? iBarShift(NULL, timeframe, cutoffTime) : 1; 
   if(limit < 1) limit = 1; 
   if(onlyCurrentBar) limit = 1; 

   string strO, strC, strP, strH, strL, strM;
   if(timeframePrefix == "D") { strO="Daily Open"; strC="Yest Close"; strP="Daily Pivot"; strH="Yest High"; strL="Yest Low"; strM="Yest Midpoint"; }
   else if(timeframePrefix == "W") { strO="Weekly Open"; strC="Last Wk Close"; strP="Weekly Pivot"; strH="Last Wk High"; strL="Last Wk Low"; strM="Last Wk Midpoint"; }
   else if(timeframePrefix == "M") { strO="Monthly Open"; strC="Last Mo Close"; strP="Monthly Pivot"; strH="Last Mo High"; strL="Last Mo Low"; strM="Last Mo Midpoint"; }

   double last_O=0, last_C=0, last_P=0, last_H=0, last_L=0, last_M=0;

   for(int i = limit; i >= 0; i--)
     {
      datetime t1 = iTime(NULL, timeframe, i);
      datetime t2 = (i == 0) ? currentLineEnd : iTime(NULL, timeframe, i - 1);
      datetime labelTime = (i == 0) ? currentLineEnd : ((timeframePrefix == "D") ? t1 : t2);
      
      double prevH = iHigh(NULL, timeframe, i + 1); double prevL = iLow(NULL, timeframe, i + 1); double prevC = iClose(NULL, timeframe, i + 1); double currO = iOpen(NULL, timeframe, i);
      if(prevH == 0 || prevL == 0) continue; 

      double Pivot = (prevH + prevL + prevC) / 3.0; double Mid = (prevH + prevL) / 2.0;
      string objBaseName = ObjPrefix + timeframePrefix + "_" + TimeToString(t1) + "_"; string connName = objBaseName + "conn_"; 

      if(showOCP)
        {
         DrawLevel(objBaseName+"O", strO, t1, t2, currO, Color_Open, Style_Open, Thick_Open, labelTime);
         DrawLevel(objBaseName+"C", strC, t1, t2, prevC, Color_Close, Style_Close, Thick_Close, labelTime);
         DrawLevel(objBaseName+"P", strP, t1, t2, Pivot, Color_Pivot, Style_Pivot, Thick_Pivot, labelTime);
         if(i < limit && last_O != 0) {
            DrawVerticalConnect(connName+"O", t1, last_O, currO, Color_Open, Style_Open, Thick_Open);
            DrawVerticalConnect(connName+"C", t1, last_C, prevC, Color_Close, Style_Close, Thick_Close);
            DrawVerticalConnect(connName+"P", t1, last_P, Pivot, Color_Pivot, Style_Pivot, Thick_Pivot);
         }
        }

      if(showHLM)
        {
         DrawLevel(objBaseName+"H", strH, t1, t2, prevH, Color_High, Style_High, Thick_High, labelTime);
         DrawLevel(objBaseName+"L", strL, t1, t2, prevL, Color_Low, Style_Low, Thick_Low, labelTime);
         DrawLevel(objBaseName+"M", strM, t1, t2, Mid, Color_Midpoint, Style_Midpoint, Thick_Midpoint, labelTime);
         if(i < limit && last_H != 0) {
            DrawVerticalConnect(connName+"H", t1, last_H, prevH, Color_High, Style_High, Thick_High);
            DrawVerticalConnect(connName+"L", t1, last_L, prevL, Color_Low, Style_Low, Thick_Low);
            DrawVerticalConnect(connName+"M", t1, last_M, Mid, Color_Midpoint, Style_Midpoint, Thick_Midpoint);
         }
        }
      last_O = currO; last_C = prevC; last_P = Pivot; last_H = prevH; last_L = prevL; last_M = Mid;
     }
  }

void CalculateQuarterly(bool onlyCurrentBar, datetime currentLineEnd, bool showOCP, bool showHLM)
  {
   int numQuarters = DrawHistory ? HistoryQuarters : 1; 
   if(onlyCurrentBar) numQuarters = 1; 
   
   // ---> TimeToStruct implemented for MT5 here <---
   datetime currentTime = TimeCurrent(); 
   MqlDateTime mdt;
   TimeToStruct(currentTime, mdt);
   int currentYear = mdt.year; 
   int currentMonth = mdt.mon; 
   int currentQ = (currentMonth - 1) / 3; 
   
   double last_O=0, last_C=0, last_P=0, last_H=0, last_L=0, last_M=0;

   for(int i = numQuarters - 1; i >= 0; i--)
     {
      int targetYear = currentYear; int targetQ = currentQ - i;
      while(targetQ < 0) { targetQ += 4; targetYear--; }
      int targetStartMonth = targetQ * 3 + 1;
      string strMonth = IntegerToString(targetStartMonth); if(targetStartMonth < 10) strMonth = "0" + strMonth;
      datetime t1 = StringToTime(IntegerToString(targetYear) + "." + strMonth + ".01 00:00");
      datetime t2; datetime labelTime;
      
      if(i == 0) { t2 = currentLineEnd; labelTime = t2; }
      else {
         int nextQ = targetQ + 1; int nextYear = targetYear; if(nextQ > 3) { nextQ = 0; nextYear++; }
         int nextStartMonth = nextQ * 3 + 1; string strNextMonth = IntegerToString(nextStartMonth); if(nextStartMonth < 10) strNextMonth = "0" + strNextMonth;
         t2 = StringToTime(IntegerToString(nextYear) + "." + strNextMonth + ".01 00:00"); labelTime = t2; 
      }
      
      int prevYear = targetYear; int prevQ = targetQ - 1; if(prevQ < 0) { prevQ += 4; prevYear--; }
      int prevStartMonth = prevQ * 3 + 1; string strPrevMonth = IntegerToString(prevStartMonth); if(prevStartMonth < 10) strPrevMonth = "0" + strPrevMonth;
      datetime prevStartTime = StringToTime(IntegerToString(prevYear) + "." + strPrevMonth + ".01 00:00");

      int shiftStart = iBarShift(NULL, PERIOD_MN1, prevStartTime);
      if(shiftStart < 2 || shiftStart == -1) continue; 

      double prevH = MathMax(iHigh(NULL, PERIOD_MN1, shiftStart), MathMax(iHigh(NULL, PERIOD_MN1, shiftStart-1), iHigh(NULL, PERIOD_MN1, shiftStart-2)));
      double prevL = MathMin(iLow(NULL, PERIOD_MN1, shiftStart), MathMin(iLow(NULL, PERIOD_MN1, shiftStart-1), iLow(NULL, PERIOD_MN1, shiftStart-2)));
      double prevC = iClose(NULL, PERIOD_MN1, shiftStart-2); 
      
      int currShiftStart = iBarShift(NULL, PERIOD_MN1, t1);
      double currO = iOpen(NULL, PERIOD_MN1, currShiftStart); 
      if(prevH == 0 || prevL == 0) continue; 

      double Pivot = (prevH + prevL + prevC) / 3.0; double Mid = (prevH + prevL) / 2.0;
      string objBaseName = ObjPrefix + "Q_" + TimeToString(t1) + "_"; string connName = objBaseName + "conn_"; 

      if(showOCP)
        {
         DrawLevel(objBaseName+"O", "Quarterly Open", t1, t2, currO, Color_Open, Style_Open, Thick_Open, labelTime);
         DrawLevel(objBaseName+"C", "Last Qtr Close", t1, t2, prevC, Color_Close, Style_Close, Thick_Close, labelTime);
         DrawLevel(objBaseName+"P", "Quarterly Pivot", t1, t2, Pivot, Color_Pivot, Style_Pivot, Thick_Pivot, labelTime);

         if(i < numQuarters - 1 && last_O != 0) {
            DrawVerticalConnect(connName+"O", t1, last_O, currO, Color_Open, Style_Open, Thick_Open);
            DrawVerticalConnect(connName+"C", t1, last_C, prevC, Color_Close, Style_Close, Thick_Close);
            DrawVerticalConnect(connName+"P", t1, last_P, Pivot, Color_Pivot, Style_Pivot, Thick_Pivot);
         }
        }

      if(showHLM)
        {
         DrawLevel(objBaseName+"H", "Last Qtr High", t1, t2, prevH, Color_High, Style_High, Thick_High, labelTime);
         DrawLevel(objBaseName+"L", "Last Qtr Low", t1, t2, prevL, Color_Low, Style_Low, Thick_Low, labelTime);
         DrawLevel(objBaseName+"M", "Last Qtr Midpoint", t1, t2, Mid, Color_Midpoint, Style_Midpoint, Thick_Midpoint, labelTime);

         if(i < numQuarters - 1 && last_H != 0) {
            DrawVerticalConnect(connName+"H", t1, last_H, prevH, Color_High, Style_High, Thick_High);
            DrawVerticalConnect(connName+"L", t1, last_L, prevL, Color_Low, Style_Low, Thick_Low);
            DrawVerticalConnect(connName+"M", t1, last_M, Mid, Color_Midpoint, Style_Midpoint, Thick_Midpoint);
         }
        }
      last_O = currO; last_C = prevC; last_P = Pivot; last_H = prevH; last_L = prevL; last_M = Mid;
     }
  }

void CreateGUI()
  {
   ObjectCreate(0, GUIPrefix+"Head", OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_FONTSIZE, 9); ObjectSetString(0, GUIPrefix+"Head", OBJPROP_FONT, "Arial Bold");
   ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_BGCOLOR, clrBlack); ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_COLOR, clrWhite);
   ObjectSetString(0, GUIPrefix+"Head", OBJPROP_TEXT, "   CORE STRUCTURE MATRIX");

   ObjectCreate(0, GUIPrefix+"btnMin", OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_FONTSIZE, 10); ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_BGCOLOR, clrDimGray);
   ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_COLOR, clrWhite);

   ObjectCreate(0, GUIPrefix+"BG", OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_BGCOLOR, clrBlack); ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_BORDER_COLOR, clrDimGray);
   
   CreateToggle("btnDOCP"); CreateToggle("btnWOCP"); CreateToggle("btnMOCP"); CreateToggle("btnQOCP"); 
   CreateToggle("btnDHLM"); CreateToggle("btnWHLM"); CreateToggle("btnMHLM"); CreateToggle("btnQHLM"); 
   
   UpdateGUI_Positions(); 
   UpdateGUI_State();
  }

void CreateToggle(string nameSuffix)
  {
   string name = GUIPrefix + nameSuffix;
   ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 8); ObjectSetString(0, name, OBJPROP_FONT, "Arial");
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite);
  }

void UpdateGUI_Positions()
  {
   int w_total = 515; int w_btn = 120; // 4 column layout
   
   ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_XDISTANCE, GUI_X); ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_YDISTANCE, GUI_Y);
   ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_XSIZE, w_total - 25); ObjectSetInteger(0, GUIPrefix+"Head", OBJPROP_YSIZE, 25);

   ObjectSetString(0, GUIPrefix+"btnMin", OBJPROP_TEXT, GUI_Min ? "+" : "-");
   ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_XDISTANCE, GUI_X + w_total - 25); ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_YDISTANCE, GUI_Y);
   ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_XSIZE, 25); ObjectSetInteger(0, GUIPrefix+"btnMin", OBJPROP_YSIZE, 25);

   long vis = GUI_Min ? OBJ_NO_PERIODS : OBJ_ALL_PERIODS;
   ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_TIMEFRAMES, vis); 
   ObjectSetInteger(0, GUIPrefix+"btnDOCP", OBJPROP_TIMEFRAMES, vis); ObjectSetInteger(0, GUIPrefix+"btnWOCP", OBJPROP_TIMEFRAMES, vis); 
   ObjectSetInteger(0, GUIPrefix+"btnMOCP", OBJPROP_TIMEFRAMES, vis); ObjectSetInteger(0, GUIPrefix+"btnQOCP", OBJPROP_TIMEFRAMES, vis);
   ObjectSetInteger(0, GUIPrefix+"btnDHLM", OBJPROP_TIMEFRAMES, vis); ObjectSetInteger(0, GUIPrefix+"btnWHLM", OBJPROP_TIMEFRAMES, vis); 
   ObjectSetInteger(0, GUIPrefix+"btnMHLM", OBJPROP_TIMEFRAMES, vis); ObjectSetInteger(0, GUIPrefix+"btnQHLM", OBJPROP_TIMEFRAMES, vis);

   if(!GUI_Min)
     {
      ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_XDISTANCE, GUI_X); ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_YDISTANCE, GUI_Y + 25);
      ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_XSIZE, w_total); ObjectSetInteger(0, GUIPrefix+"BG", OBJPROP_YSIZE, 75);

      // Row 1 (Opens, Closes, Pivots)
      SetBtnPos("btnDOCP", GUI_X + 5,                 GUI_Y + 35, w_btn, 25);
      SetBtnPos("btnWOCP", GUI_X + 10 + w_btn,        GUI_Y + 35, w_btn, 25);
      SetBtnPos("btnMOCP", GUI_X + 15 + (w_btn*2),    GUI_Y + 35, w_btn, 25);
      SetBtnPos("btnQOCP", GUI_X + 20 + (w_btn*3),    GUI_Y + 35, w_btn, 25);
      
      // Row 2 (Highs, Lows, Mids)
      SetBtnPos("btnDHLM", GUI_X + 5,                 GUI_Y + 65, w_btn, 25);
      SetBtnPos("btnWHLM", GUI_X + 10 + w_btn,        GUI_Y + 65, w_btn, 25);
      SetBtnPos("btnMHLM", GUI_X + 15 + (w_btn*2),    GUI_Y + 65, w_btn, 25);
      SetBtnPos("btnQHLM", GUI_X + 20 + (w_btn*3),    GUI_Y + 65, w_btn, 25);
     }
  }

void SetBtnPos(string name, int x, int y, int w, int h)
  {
   ObjectSetInteger(0, GUIPrefix+name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, GUIPrefix+name, OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, GUIPrefix+name, OBJPROP_XSIZE, w); ObjectSetInteger(0, GUIPrefix+name, OBJPROP_YSIZE, h);
  }

void UpdateGUI_State()
  {
   ObjectSetString(0, GUIPrefix+"btnDOCP", OBJPROP_TEXT, ShowDOCP ? "D. O/C/PIVOT: ON" : "D. O/C/PIVOT: OFF"); ObjectSetInteger(0, GUIPrefix+"btnDOCP", OBJPROP_BGCOLOR, ShowDOCP ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnWOCP", OBJPROP_TEXT, ShowWOCP ? "W. O/C/PIVOT: ON" : "W. O/C/PIVOT: OFF"); ObjectSetInteger(0, GUIPrefix+"btnWOCP", OBJPROP_BGCOLOR, ShowWOCP ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnMOCP", OBJPROP_TEXT, ShowMOCP ? "M. O/C/PIVOT: ON" : "M. O/C/PIVOT: OFF"); ObjectSetInteger(0, GUIPrefix+"btnMOCP", OBJPROP_BGCOLOR, ShowMOCP ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnQOCP", OBJPROP_TEXT, ShowQOCP ? "Q. O/C/PIVOT: ON" : "Q. O/C/PIVOT: OFF"); ObjectSetInteger(0, GUIPrefix+"btnQOCP", OBJPROP_BGCOLOR, ShowQOCP ? clrTeal : clrMaroon);
   
   ObjectSetString(0, GUIPrefix+"btnDHLM", OBJPROP_TEXT, ShowDHLM ? "D. H/L/MID: ON" : "D. H/L/MID: OFF"); ObjectSetInteger(0, GUIPrefix+"btnDHLM", OBJPROP_BGCOLOR, ShowDHLM ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnWHLM", OBJPROP_TEXT, ShowWHLM ? "W. H/L/MID: ON" : "W. H/L/MID: OFF"); ObjectSetInteger(0, GUIPrefix+"btnWHLM", OBJPROP_BGCOLOR, ShowWHLM ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnMHLM", OBJPROP_TEXT, ShowMHLM ? "M. H/L/MID: ON" : "M. H/L/MID: OFF"); ObjectSetInteger(0, GUIPrefix+"btnMHLM", OBJPROP_BGCOLOR, ShowMHLM ? clrTeal : clrMaroon);
   ObjectSetString(0, GUIPrefix+"btnQHLM", OBJPROP_TEXT, ShowQHLM ? "Q. H/L/MID: ON" : "Q. H/L/MID: OFF"); ObjectSetInteger(0, GUIPrefix+"btnQHLM", OBJPROP_BGCOLOR, ShowQHLM ? clrTeal : clrMaroon);
  }

void DrawLevel(string name, string labelText, datetime time1, datetime time2, double price, color clr, int style, int width, datetime labelTime)
  {
   if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_TREND, 0, time1, price, time2, price);
   else { ObjectSetInteger(0, name, OBJPROP_TIME, 0, time1); ObjectSetDouble(0, name, OBJPROP_PRICE, 0, price); ObjectSetInteger(0, name, OBJPROP_TIME, 1, time2); ObjectSetDouble(0, name, OBJPROP_PRICE, 1, price); }
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_STYLE, style); ObjectSetInteger(0, name, OBJPROP_WIDTH, width); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false); ObjectSetInteger(0, name, OBJPROP_BACK, true);       
   if(DisplayLables)
     {
      string lblName = name + "_lbl";
      if(ObjectFind(0, lblName) < 0) ObjectCreate(0, lblName, OBJ_TEXT, 0, labelTime, price);
      else { ObjectSetInteger(0, lblName, OBJPROP_TIME, 0, labelTime); ObjectSetDouble(0, lblName, OBJPROP_PRICE, 0, price); }
      // ---> Built-in Digits and conversion updated here <---
      string formattedPrice = DoubleToString(price, _Digits); ObjectSetString(0, lblName, OBJPROP_TEXT, "  " + labelText + " " + formattedPrice);
      ObjectSetInteger(0, lblName, OBJPROP_COLOR, clr); ObjectSetInteger(0, lblName, OBJPROP_FONTSIZE, 8); ObjectSetInteger(0, lblName, OBJPROP_ANCHOR, ANCHOR_LEFT); 
     }
  }

void DrawVerticalConnect(string name, datetime time, double price1, double price2, color clr, int style, int width)
  {
   if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_TREND, 0, time, price1, time, price2);
   else { ObjectSetInteger(0, name, OBJPROP_TIME, 0, time); ObjectSetDouble(0, name, OBJPROP_PRICE, 0, price1); ObjectSetInteger(0, name, OBJPROP_TIME, 1, time); ObjectSetDouble(0, name, OBJPROP_PRICE, 1, price2); }
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_STYLE, style); ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false); ObjectSetInteger(0, name, OBJPROP_BACK, true);   
  }
//+------------------------------------------------------------------+