//+------------------------------------------------------------------+
//| WK MN DY LINES.mq4                                               |
//| Simpler than it looked :)   codobro                              |
//| Alert stuff/opportunity to change colors etc., by fxdaytrader    |
//+------------------------------------------------------------------+
#property copyright "WK NM DY LINES"
#property indicator_chart_window

extern bool DisplayDaily=true;
extern bool DisplayWeekly=true;
extern bool DisplayMonthly=true;

extern color DailyColor=Yellow;
extern int   DailyStyle=STYLE_DASH;
extern color WeeklyColor=DodgerBlue;
extern int   WeeklyStyle=STYLE_DASH;
extern color MonthlyColor=MediumOrchid;
extern int   MonthlyStyle=STYLE_DASH;

//alerts/misc
extern bool HighLineAlerts=true;
extern bool LowLineAlerts=true;
extern bool DailyAlerts=true;
extern bool WeeklyAlerts=true;
extern bool MonthlyAlerts=true;
extern bool spaceIfSame=false;

extern int    AlertCandle            = 0;
extern bool   PopupAlerts            = false;
extern bool   PushNotificationAlerts = true;
extern bool   SoundAlerts            = false;
extern string SoundFileHigh          = "alert.wav";
extern string SoundFileLow           = "alert2.wav";

double objprice;

//object prefixes:
string D1HighPrefix  = "PREV DAILY HIGH BROKEN";
string D1LowPrefix   = "PREV DAILY LOW BROKEN";
string W1HighPrefix  = "PREV WEEKLY HIGH BROKEN";
string W1LowPrefix   = "PREV WEEKLY LOW BROKEN";
string MN1HighPrefix = "PREV MONTHLY HIGH BROKEN";
string MN1LowPrefix  = "PREV MONTHLY LOW BROKEN";

double Weekly[][6];
double Monthly[][6];
double Daily[][6];

double W1H, W1L, MNH, MNL, D1H, D1L;

//+------------------------------------------------------------------+
//| LABEL CREATION FUNCTION                                          |
//+------------------------------------------------------------------+
void AddLineLabel(string labelName, string text, double price, color clr)
{
   if(ObjectFind(labelName) != -1)
      ObjectDelete(labelName);

   ObjectCreate(labelName, OBJ_TEXT, 0, Time[0]+_Period*60, price);
   ObjectSetText(labelName, text + "  " + DoubleToString(price, Digits), 10, "Arial", clr);
   ObjectSet(labelName, OBJPROP_ANCHOR, ANCHOR_LEFT);
}
//+------------------------------------------------------------------+

int init() { return(0); }

//+------------------------------------------------------------------+
int deinit()
{
   int total = ObjectsTotal();
   for(int i = total - 1; i >= 0; i--)
   {
      string name = ObjectName(i);

      if( StringFind(name, D1HighPrefix)  == 0 ||
          StringFind(name, D1LowPrefix)   == 0 ||
          StringFind(name, W1HighPrefix)  == 0 ||
          StringFind(name, W1LowPrefix)   == 0 ||
          StringFind(name, MN1HighPrefix) == 0 ||
          StringFind(name, MN1LowPrefix)  == 0 )
      {
         ObjectDelete(name);
      }
   }

   return(0);
}

//+------------------------------------------------------------------+

int start()
{
   ArrayCopyRates(Daily, Symbol(), 1440);
   D1H = Daily[1][3];
   D1L = Daily[1][2];

   if (DisplayDaily)
   {
      ObjCreateMove(D1HighPrefix,DailyStyle,DailyColor,D1H);
      AddLineLabel(D1HighPrefix + "_LBL", "PD1 High", D1H, DailyColor);

      ObjCreateMove(D1LowPrefix,DailyStyle,DailyColor,D1L);
      AddLineLabel(D1LowPrefix + "_LBL", "PD1 Low", D1L, DailyColor);
   }

   ArrayCopyRates(Weekly, Symbol(), 10080);
   W1H = Weekly[1][3];
   W1L = Weekly[1][2];

   if (spaceIfSame)
   {
      if (W1H==D1H) W1H += 2*Point;
      if (W1L==D1L) W1L -= 2*Point;
   }

   if (DisplayWeekly)
   {
      ObjCreateMove(W1HighPrefix,WeeklyStyle,WeeklyColor,W1H);
      AddLineLabel(W1HighPrefix + "_LBL", "PW1 High", W1H, WeeklyColor);

      ObjCreateMove(W1LowPrefix,WeeklyStyle,WeeklyColor,W1L);
      AddLineLabel(W1LowPrefix + "_LBL", "PW1 Low", W1L, WeeklyColor);
   }

   ArrayCopyRates(Monthly, Symbol(), 43200);
   MNH = Monthly[1][3];
   MNL = Monthly[1][2];

   if (spaceIfSame)
   {
      if (MNH==D1H) MNH += 4*Point;
      if (MNL==D1L) MNL -= 4*Point;
   }

   if (DisplayMonthly)
   {
      ObjCreateMove(MN1HighPrefix,MonthlyStyle,MonthlyColor,MNH);
      AddLineLabel(MN1HighPrefix + "_LBL", "PMN1 High", MNH, MonthlyColor);

      ObjCreateMove(MN1LowPrefix,MonthlyStyle,MonthlyColor,MNL);
      AddLineLabel(MN1LowPrefix + "_LBL", "PMN1 Low", MNL, MonthlyColor);
   }

   CheckForLineTouches();
   return(0);
}
//+------------------------------------------------------------------+
void ObjCreateMove(string objname, int objstyle, color objcolor, double price)
{
   datetime t1 = iTime(NULL, 0, Bars - 1); // far left of chart
   datetime t2 = Time[0];                  // current bar

   if(ObjectFind(objname) == -1)
   {
      ObjectCreate(objname, OBJ_TREND, 0, t1, price, t2, price);
      ObjectSet(objname, OBJPROP_COLOR, objcolor);
      ObjectSet(objname, OBJPROP_STYLE, objstyle);
      ObjectSet(objname, OBJPROP_RAY, false); // stops at current bar
   }
   else
   {
      ObjectMove(objname, 0, t1, price);
      ObjectMove(objname, 1, t2, price);
   }
}


//////////////////////////////////////////////////////////////////////
//stuff by fxdaytrader:
double GetObjectPrice(string objname,int objshift) {
 return(ObjectGet(objname,objshift));
}

bool ObjTouched(string objname,int shift) {
  objprice=GetObjectPrice(objname,1);
  if (iHigh(NULL,0,shift)>=objprice && iClose(NULL,0,shift+1)<=objprice) return(true);
  if (iLow(NULL,0,shift)<=objprice && iClose(NULL,0,shift+1)>=objprice) return(true);
 return(false);
}

void CheckForLineTouches() {
 int lastAlertType=3;
 string msg=Symbol() + " " +TFtoStr(Period())+" "; 

 if (DailyAlerts && DisplayDaily) {
   if (lastAlertType!=2 && HighLineAlerts && ObjTouched(D1HighPrefix,AlertCandle)) {
    msg=msg+"PREV DAILY HIGH BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileHigh);
    lastAlertType=2;
   }
   if (lastAlertType!=1 && LowLineAlerts && ObjTouched(D1LowPrefix,AlertCandle)) {
    msg=msg+"PREV DAILY LOW BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileLow);
    lastAlertType=1;
   }
 }

 if (WeeklyAlerts && DisplayWeekly) {
   if (lastAlertType!=2 && HighLineAlerts && ObjTouched(W1HighPrefix,AlertCandle)) {
    msg=msg+"PREV WEEKLY HIGH BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileHigh);
    lastAlertType=2;
   }
   if (lastAlertType!=1 && LowLineAlerts && ObjTouched(W1LowPrefix,AlertCandle)) {
    msg=msg+"PREV WEEKLY LOW BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileLow);
    lastAlertType=1;
   }
 }

 if (MonthlyAlerts && DisplayMonthly) {
   if (lastAlertType!=2 && HighLineAlerts && ObjTouched(MN1HighPrefix,AlertCandle)) {
    msg=msg+"PREV MONTHLY HIGH BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileHigh);
    lastAlertType=2;
   }
   if (lastAlertType!=1 && LowLineAlerts && ObjTouched(MN1LowPrefix,AlertCandle)) {
    msg=msg+"PREV MONTHLY LOW BROKEN "+DoubleToStr(objprice,Digits);
    doAlerts(msg,SoundFileLow);
    lastAlertType=1;
   }
 }
}

void doAlerts(string msg,string SoundFile) {
 static datetime lastAlertTime=0;
 if (lastAlertTime!=iTime(NULL,0,0)) {
  lastAlertTime=iTime(NULL,0,0);

  if (PopupAlerts) Alert(msg);
  if (PushNotificationAlerts) SendNotification(msg);
  if (SoundAlerts) PlaySound(SoundFile);
 }
}

string TFtoStr(int period) {
 switch(period) {
  case 1     : return("M1");
  case 5     : return("M5");
  case 15    : return("M15");
  case 30    : return("M30");
  case 60    : return("H1");
  case 240   : return("H4");
  case 1440  : return("D1");
  case 10080 : return("W1");
  case 43200 : return("MN1");
  default    : return(DoubleToStr(period,0));
 }
}
//////////////////////////////////////////////////////////////////////
