//+------------------------------------------------------------------------+
//|                                                        iClock Mod1.mq4 !
//|                              Copyright 2015, MetaQuotes Software Corp. |
//|                                                   https://www.mql5.com |
//| Author: mladen - https://www.forex-tsd.com                             |
//| Modifier: File45 - https://www.mql5.com/en/users/file45/publications   |
//| * 2015/4/09: Convert from mql5 to mql4                                 |
//| * 2015/4/09: Add alerts and label colored alert states.                |
//+------------------------------------------------------------------------+
#property copyright "mladen"
#property link      "www.forex-tsd.com"
#property version   "1.00"
#property description "Continuous-no-log candle timer with new candle alert options."
#property description "Not dependent on incoming ticks."
#property description "Pop up and Sound only alert options."
#property description "Timer label colored according to Alert Mode: Off, On, Sound only."
#property description "Automatic Broker GMT and Daylight Saving Time adjustment."

#property indicator_chart_window
//#property indicator_buffers 1
//#property indicator_plots   1
//#define clockName "CandleTimer"
//#property strict

enum AlertMode_menu
  {
   NoAlert    = 0, // Off
   PopUpAlert = 1, // On
   SoundAlert = 2  // Sound only 
  };

input AlertMode_menu AlertMode  = 0; // Select Alert Mode
//input color ValuesPositiveColor = MediumSeaGreen; // Color for positive timer values
input color AlertOff            = Yellow;
input color AlertOn             = LimeGreen;
input color SoundOnly           = DodgerBlue;
input color NoBarColor          = Red;        // Color for negative timer values
input int   FontSize            = 12;         // Font Size
input bool  FontBold            = false;       // Font Bold
input int   FontShift           = 4;          // Font Shift

//int  atrHandle;
datetime LastAlertTime;
string TMz;
string theFont;
string clockName="Candle Timer";

int OnInit()
  {
   switch(FontBold)
     {
      case 0: theFont="Arial"; break;
      case 1: theFont="Arial Black"; break;
     }

   switch(Period())
     {
      case 1:     TMz = "M1";  break;
      case 5:     TMz = "M5";  break;
      case 15:    TMz = "M15"; break;
      case 30:    TMz = "M30"; break;
      case 60:    TMz = "H1";  break;
      case 240:   TMz = "H4";  break;
      case 1440:  TMz = "D1";  break;
      case 10080: TMz = "W1";  break;
      case 43200: TMz = "MN";  break;
     }

   LastAlertTime=TimeCurrent();
   //atrHandle=(iATR(NULL,0,30,0)); 
   EventSetTimer(1);

   return(0);
  }

void OnDeinit(const int reason) { EventKillTimer(); ObjectDelete(clockName); }
void OnTimer() { refreshClock(); }

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[])
  {
   if((AlertMode==1) && (LastAlertTime<Time[0]))
     {
      Alert("New Bar - ",Symbol()," - "+TMz+" - "+AccountCompany());
      LastAlertTime=Time[0];
     }
   else if((AlertMode==2) && (LastAlertTime<Time[0]))
     {
      PlaySound("Alert.wav");
      LastAlertTime=Time[0];
     }

   refreshClock();
   return(rates_total);
  }

void refreshClock()
  {
   static bool inRefresh=false;
   if(inRefresh) return;
   inRefresh=true;
   ShowClock(); ChartRedraw();
   inRefresh=false;
  }

void ShowClock()
  {
   int periodMinutes=periodToMinutes(Period());
   int shift=periodMinutes*FontShift*60;
   int currentTime=(int)TimeCurrent();
   int localTime=(int)TimeLocal();
   int barTime=(int)iTime();
   int diff=(int)MathMax(round((currentTime-localTime)/3600.0)*3600,-24*3600);

   color  theColor;
   string time=getTime(barTime+periodMinutes*60-localTime-diff,theColor);
   time=(TerminalInfoInteger(TERMINAL_CONNECTED)) ? time : time+" x";

   if(ObjectFind(0,clockName)<0)
      ObjectCreate(0,clockName,OBJ_TEXT,0,barTime+shift,0);
   ObjectSetString(0,clockName,OBJPROP_TEXT,time);
   ObjectSetString(0,clockName,OBJPROP_FONT,theFont);
   ObjectSetInteger(0,clockName,OBJPROP_FONTSIZE,FontSize);
   ObjectSetInteger(0,clockName,OBJPROP_COLOR,theColor);
   if(ChartGetInteger(0,CHART_SHIFT,0)==0 && (shift>=0))
      ObjectSetInteger(0,clockName,OBJPROP_TIME,barTime-shift*3);
   else ObjectSetInteger(0,clockName,OBJPROP_TIME,barTime+shift);

   double price[]; if(CopyClose(Symbol(),0,0,1,price)<=0) return;
   double atr[];
   //if(CopyBuffer(atrHandle,0,0,1,atr)<=0) return;
   price[0]+=3.0*atr[0]/4.0;

   bool visible=((ChartGetInteger(0,CHART_VISIBLE_BARS,0)-ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0))>0);
   if(visible && price[0]>=ChartGetDouble(0,CHART_PRICE_MAX,0))
      ObjectSetDouble(0,clockName,OBJPROP_PRICE,price[0]-1.5*atr[0]);
   else ObjectSetDouble(0,clockName,OBJPROP_PRICE,price[0]);
  }

string getTime(int times,color &theColor)
  {
   string stime="";
   int seconds;
   int minutes;
   int hours;

   //if(times<0) {theColor=ValuesNegativeColor; times=(int)fabs(times);}
   //else theColor=ValuesPositiveColor;

   if(times<0)
     {
      theColor=NoBarColor; times=(int)fabs(times);
     }
   else if(times>0)
     {
      switch(AlertMode)
        {
         case 0: theColor=AlertOff; break;
         case 1: theColor=AlertOn; break;
         case 2: theColor=SoundOnly;
        }
     }

   seconds=(times%60);
   hours=(times-times%3600)/3600;
   minutes=(times-seconds)/60-hours*60;

   if(hours>0)
      if(minutes<10)
         stime=stime+(string)hours+":0";
   else  stime=stime+(string)hours+":";
   stime=stime+(string)minutes;
   if(seconds<10)
      stime=stime+":0"+(string)seconds;
   else  stime=stime+":"+(string)seconds;
   return(stime);
  }

datetime iTime(ENUM_TIMEFRAMES forPeriod=PERIOD_CURRENT)
  {
   datetime times[]; if(CopyTime(Symbol(),forPeriod,0,1,times)<=0) return(TimeLocal());
   return(times[0]);
  }

int periodToMinutes(int period)
  {
   int i;
   static int _per[]={1,5,15,30,60,240,1440,10080,43200};
   static int _min[]={1,5,15,30,60,240,1440,10080,43200};

   if(period==PERIOD_CURRENT)
      period=Period();
   for(i=0;i<20;i++) if(period==_per[i]) break;
   return(_min[i]);
  }
//+------------------------------------------------------------------+
