//+------------------------------------------------------------------+
//|                                             ChartLevelDrawer.mqh |
//+------------------------------------------------------------------+
#ifndef CHARTLEVELDRAWER_MQH
#define CHARTLEVELDRAWER_MQH

//+------------------------------------------------------------------+
//| CChartLevelDrawer                                                |
//| Draws and removes the horizontal ladder lines that mark each     |
//| profit target on the chart. Object names are derived from the    |
//| position ticket and the R-multiple so that every line belonging  |
//| to a position can be found and removed again with a single       |
//| prefix, without the engine needing to track a separate registry. |
//+------------------------------------------------------------------+
class CChartLevelDrawer
  {
public:
                     CChartLevelDrawer(void);
                    ~CChartLevelDrawer(void);

   string            DrawLevel(const long chart_id,
                               const ulong position_ticket,
                               const double r_multiple,
                               const double close_pct,
                               const double price,
                               const color line_color);
   void              RemoveLevel(const long chart_id, const string object_name);
   void              RemoveAll(const long chart_id, const ulong position_ticket);
   void              MarkHit(const long chart_id, const string object_name, const color hit_color);
   string            BuildPrefix(const ulong position_ticket) const;
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CChartLevelDrawer::CChartLevelDrawer(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CChartLevelDrawer::~CChartLevelDrawer(void)
  {
  }

//+------------------------------------------------------------------+
//| BuildPrefix                                                      |
//| Builds the common naming prefix shared by every object that      |
//| belongs to one position, used both for creation and cleanup.     |
//+------------------------------------------------------------------+
string CChartLevelDrawer::BuildPrefix(const ulong position_ticket) const
  {
   return(::StringFormat("PCE_%I64u_", position_ticket));
  }

//+------------------------------------------------------------------+
//| DrawLevel                                                        |
//| Creates a horizontal dashed line at the given price, labelled    |
//| with the R-multiple and close percentage of this ladder level.   |
//| Returns the object name so the caller can store it for cleanup.  |
//+------------------------------------------------------------------+
string CChartLevelDrawer::DrawLevel(const long chart_id,
                                    const ulong position_ticket,
                                    const double r_multiple,
                                    const double close_pct,
                                    const double price,
                                    const color line_color)
  {
   string name = BuildPrefix(position_ticket) + ::StringFormat("%.1fR", r_multiple);

   ::ObjectDelete(chart_id, name);
   if(!::ObjectCreate(chart_id, name, OBJ_HLINE, 0, 0, price))
     {
      ::PrintFormat("CChartLevelDrawer: failed to create object %s, error=%d",
                    name, ::GetLastError());
      return("");
     }

   string label = ::StringFormat("%.1fR (%.0f%%)", r_multiple, close_pct);

   ::ObjectSetInteger(chart_id, name, OBJPROP_COLOR, line_color);
   ::ObjectSetInteger(chart_id, name, OBJPROP_STYLE, STYLE_DASH);
   ::ObjectSetInteger(chart_id, name, OBJPROP_WIDTH, 1);
   ::ObjectSetInteger(chart_id, name, OBJPROP_BACK, false);
   ::ObjectSetInteger(chart_id, name, OBJPROP_SELECTABLE, false);
   ::ObjectSetString(chart_id, name, OBJPROP_TEXT, label);

   return(name);
  }

//+------------------------------------------------------------------+
//| RemoveLevel                                                      |
//| Deletes a single named chart object.                             |
//+------------------------------------------------------------------+
void CChartLevelDrawer::RemoveLevel(const long chart_id, const string object_name)
  {
   if(object_name == "")
      return;
   ::ObjectDelete(chart_id, object_name);
  }

//+------------------------------------------------------------------+
//| RemoveAll                                                        |
//| Deletes every chart object created for the given position ticket |
//| by matching against the shared naming prefix.                    |
//+------------------------------------------------------------------+
void CChartLevelDrawer::RemoveAll(const long chart_id, const ulong position_ticket)
  {
   string prefix = BuildPrefix(position_ticket);
   ::ObjectsDeleteAll(chart_id, prefix);
  }

//+------------------------------------------------------------------+
//| MarkHit                                                          |
//| Changes a line's color to mark that its ladder level has been    |
//| hit, giving the chart a visual record of progress through the    |
//| ladder without needing to remove and redraw the line.            |
//+------------------------------------------------------------------+
void CChartLevelDrawer::MarkHit(const long chart_id, const string object_name, const color hit_color)
  {
   if(object_name == "")
      return;
   if(::ObjectFind(chart_id, object_name) < 0)
      return;
   ::ObjectSetInteger(chart_id, object_name, OBJPROP_COLOR, hit_color);
   ::ObjectSetInteger(chart_id, object_name, OBJPROP_STYLE, STYLE_SOLID);
  }

#endif // CHARTLEVELDRAWER_MQH
//+------------------------------------------------------------------+