//+------------------------------------------------------------------+
//|                                                    Spaceline.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

  
enum ENUM_PRICE
  {
   ManualInput,    // Input Price Manually
   D0Open,         // Today Open Price
   D1Open,         // Yesterday Open Price
  };

extern string UniqueID = "Space1";
extern ENUM_PRICE WhichPrice = ManualInput;
extern double  StartPrice = 0;
extern int     NumLines   = 9;
extern int     Spacing    = 25;
extern string  AboveBelow = "AB";
extern color   LineColor  = Gray;
extern color   BaseLineColor = clrLime;
extern int     LineWidth  = 1;
extern int     LineStyle  = 0;
extern string  TimeFrames = "M1, M5, M15, M30, H1, H4, D1, W1, MN";
input int                 Button_Window              = 0;  
input ENUM_BASE_CORNER    Button_Corner              = 3;  
input int                 Button_X                   = 522;
input int                 Button_Y                   = 99;
input int                 Button_Width               = 99;
input int                 Button_Height              = 36;
input int                 Button_FontSize            = 11;
input color               Button_BrdrColor           = clrChocolate;
input color               Button_OffBckColor         = C'40,40,40';
input color               Button_OnBckColor          = clrGreen;
input color               Button_OffTxtColor         = clrRed;
input color               Button_OnTxtColor          = clrChocolate;

string ButTxtOff = "Lines Off";
string ButTxtOn = "Lines On";
string ButtonName = "Button " + UniqueID + "SpacedLinesOnOffButton";

double timeX = 0;

//+------------------------------------------------------------------+
int init()  {
//+------------------------------------------------------------------+
  del_obj();
  plot_obj();
  CreateButton(ButtonName);
  
    if(Period()==1   )timeX=60;if(Period()==5    )timeX=300;if(Period()==15   )timeX=900;
  if(Period()==30  )timeX=1800;if(Period()==60   )timeX=3600;if(Period()==240  )timeX=14400;
  if(Period()==1440)timeX=86400;if(Period()==10080)timeX=604800;if(Period()==43200)timeX=2592000;


  return(0);
}

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  del_obj();
  ObjectDelete(0,ButtonName); 
  return(0);
}

//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+
  return(0);
}

//+------------------------------------------------------------------+
int MathSign(double n)
//+------------------------------------------------------------------+
// Returns the sign of a number (i.e. -1, 0, +1)
// Usage:   int x=MathSign(-25)   returns x=-1
{
  if (n > 0) return(1);
  else if (n < 0) return (-1);
  else return(0);
}  

//+------------------------------------------------------------------+
double MathFix(double n, int d)
//+------------------------------------------------------------------+
// Returns N rounded to D decimals - works around a precision bug in MQL4
{
  return(MathRound(n*MathPow(10,d)+0.000000000001*MathSign(n))/MathPow(10,d));
}  


//+------------------------------------------------------------------+
void plot_obj()  {
//+------------------------------------------------------------------+

  int x,y;
  
  TimeFrames = StringUpper(TimeFrames) + ",";
  int tf = 0;
  if (StringFind(TimeFrames,"M1,")  >= 0)    tf += 1;
  if (StringFind(TimeFrames,"M5,")  >= 0)    tf += 2;
  if (StringFind(TimeFrames,"M15,") >= 0)    tf += 4;
  if (StringFind(TimeFrames,"M30,") >= 0)    tf += 8;
  if (StringFind(TimeFrames,"H1,")  >= 0)    tf += 16;
  if (StringFind(TimeFrames,"H4,")  >= 0)    tf += 32;
  if (StringFind(TimeFrames,"D1,")  >= 0)    tf += 64;
  if (StringFind(TimeFrames,"W1,")  >= 0)    tf += 128;
  if (StringFind(TimeFrames,"MN,")  >= 0)    tf += 256;

  if (Digits >= 4)   {                            // non-JPY pair
     double mult = 0.0001;
     double prc  = MathFix(Close[0],2);
  }
  else  {                                         // JPY pair
     mult = 0.01;
     prc  = MathFix(Close[0],0);
  }   
  if (WhichPrice==ManualInput&&StartPrice > 0)
    prc = StartPrice;
  if (WhichPrice==D0Open)
    prc = iOpen(_Symbol,PERIOD_D1,0);
  if (WhichPrice==D1Open)
    prc = iOpen(_Symbol,PERIOD_D1,1);

  AboveBelow = StringUpper(AboveBelow);
  int X0 = 0, X1 = 0;
  if (AboveBelow == "A")    {  X0 = 0;            X1 = NumLines-1;  }     else
  if (AboveBelow == "B")    {  X0 = -NumLines+1;  X1 = 0;           }     else
  if (AboveBelow == "AB")   {  X0 = -NumLines+1;  X1 = NumLines-1;  }  
    
  for (int i=X0; i<=X1; i++)   
  {
    color HLineColor = LineColor;
    if ( i == 0) HLineColor = BaseLineColor;
    
    string objname = UniqueID + "Lspc-"+i;
    ObjectCreate(objname,OBJ_HLINE,0,0,prc+Spacing*mult*i);
    ObjectSet(objname,OBJPROP_COLOR,HLineColor);
    ObjectSet(objname,OBJPROP_WIDTH,LineWidth);
    ObjectSet(objname,OBJPROP_STYLE,LineStyle);
    ObjectSet(objname,OBJPROP_TIMEFRAMES,tf);
    
    ChartTimePriceToXY(0, 0, iTime(Symbol(),PERIOD_CURRENT,0) + timeX*3,prc+Spacing*mult*i, x, y);
    string Position = "";
    if ( i < 0 ) Position = "Dn";
    if ( i > 0 ) Position = "Up";
    
   
    DrawLabel( UniqueID + "Linelabel" + IntegerToString(i),x,y, Position +" " + IntegerToString(i) + " (" + DoubleToString(prc+Spacing*mult*i,Digits) + ")" ,8,"Arial Rounded MT Bold",HLineColor);
   
   
  }
  return;
}

  
void del_obj()
{
   string lookFor       = UniqueID;
   int    lookForLength = StringLen(lookFor);
   for (int i=ObjectsTotal()-1; i>=0; i--)
   {
      string objectName = ObjectName(i);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
   }
}



//+------------------------------------------------------------------+
string StringUpper(string str)
//+------------------------------------------------------------------+
// Converts any lowercase characters in a string to uppercase
// Usage:    string x=StringUpper("The Quick Brown Fox")  returns x = "THE QUICK BROWN FOX"
{
  string outstr = "";
  string lower  = "abcdefghijklmnopqrstuvwxyz";
  string upper  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  for(int i=0; i<StringLen(str); i++)  {
    int t1 = StringFind(lower,StringSubstr(str,i,1),0);
    if (t1 >=0)  
      outstr = outstr + StringSubstr(upper,t1,1);
    else
      outstr = outstr + StringSubstr(str,i,1);
  }
  return(outstr);
} 
//+------------------------------------------------------------------+
void CreateButton(string btn_name)
{
   
        
                   if(ObjectFind(0,btn_name)<0)
                    {
                   ObjectCreate(0,btn_name,OBJ_BUTTON,Button_Window,0,0);
                   ObjectSetInteger(0,btn_name,OBJPROP_XDISTANCE,Button_X);
                   ObjectSetInteger(0,btn_name,OBJPROP_YDISTANCE,Button_Y);
                   ObjectSetInteger(0,btn_name,OBJPROP_XSIZE,Button_Width);
                   ObjectSetInteger(0,btn_name,OBJPROP_YSIZE,Button_Height);
                   ObjectSetInteger(0,btn_name,OBJPROP_CORNER,Button_Corner);
                   ObjectSetString(0,btn_name,OBJPROP_TEXT,ButTxtOn);
                   ObjectSetString(0,btn_name,OBJPROP_FONT,"Tahoma");
                   ObjectSetInteger(0,btn_name,OBJPROP_FONTSIZE,Button_FontSize);
                   ObjectSetInteger(0,btn_name,OBJPROP_COLOR,Button_OnTxtColor);
                   ObjectSetInteger(0,btn_name,OBJPROP_BGCOLOR,Button_OnBckColor);
                   ObjectSetInteger(0,btn_name,OBJPROP_BORDER_COLOR,Button_BrdrColor);
                   ObjectSetInteger(0,btn_name,OBJPROP_BACK,false);
                   ObjectSetInteger(0,btn_name,OBJPROP_STATE,true);
                   ObjectSetInteger(0,btn_name,OBJPROP_SELECTABLE,false);
                   ObjectSetInteger(0,btn_name,OBJPROP_SELECTED,false);
                   ObjectSetInteger(0,btn_name,OBJPROP_HIDDEN,true);
                   ObjectSetInteger(0,btn_name,OBJPROP_ZORDER,9);
                    }
   }
   
   
void DrawLabel(string name,int x,int y,string label,int size=9,string font="Arial",color clr=DimGray,string tooltip="")
  {
 
   if (ObjectFind(name)) ObjectDelete(name);
   ObjectCreate(name,OBJ_LABEL,0,0,0);
   ObjectSetText(name,label,size,font,clr);
   ObjectSet(name,OBJPROP_CORNER,0);
   ObjectSet(name,OBJPROP_XDISTANCE,x);
   ObjectSet(name,OBJPROP_YDISTANCE,y);
   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);
//--- justify text
//ObjectSet(name, OBJPROP_ANCHOR, 0);
//ObjectSetString(0, name, OBJPROP_TOOLTIP, tooltip);
//ObjectSet(name, OBJPROP_SELECTABLE, 0);
//---
  }
  
  
//+------------------------------------------------------------------+ 
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
 {
//---
   if(id==CHARTEVENT_OBJECT_CLICK)
     { 
     if(sparam==ButtonName&&
        ObjectGetString(0,sparam,OBJPROP_TEXT)==ButTxtOff)
      {
      ObjectSetString(0,sparam,OBJPROP_TEXT,ButTxtOn);
      ObjectSetInteger(0,sparam,OBJPROP_COLOR,Button_OnTxtColor);
      ObjectSetInteger(0,sparam,OBJPROP_BGCOLOR,Button_OnBckColor);
      ObjectSetInteger(0,sparam,OBJPROP_STATE,true);
      plot_obj();
      }
     else
     if(sparam==ButtonName&&
        ObjectGetString(0,sparam,OBJPROP_TEXT)==ButTxtOn)
      {      
      ObjectSetString(0,sparam,OBJPROP_TEXT,ButTxtOff);
      ObjectSetInteger(0,sparam,OBJPROP_COLOR,Button_OffTxtColor);
      ObjectSetInteger(0,sparam,OBJPROP_BGCOLOR,Button_OffBckColor);
      ObjectSetInteger(0,sparam,OBJPROP_STATE,true);
      del_obj();
      }
     }

 }
//+------------------------------------------------------------------+
