//+------------------------------------------------------------------+
//|                                                      b-clock.mq4 |
//|                                     Core time code by Nick Bilak |
//|        http://metatrader.50webs.com/         beluck[at]gmail.com |
//|                                  modified by adoleh2000 and dwt5 | 
//|                                                                  | 
//| 2012.07.11 - diogo@forexfactory                                  | 
//| - close time calculation compensate weekends for WEEK/MONTH chart|
//| - presented time-left is dynamic shown in descesding magnitude   |
//|   and not only in "minutes and seconds"                          |
//+------------------------------------------------------------------+

#property copyright "Copyright © 2005, Nick Bilak"
#property link      "http://metatrader.50webs.com/"

#property indicator_chart_window

//---- buffers
double s1[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int init() {
   return(0);
}
  
int deinit() {
   ObjectDelete("time");
   return(0);
}
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
   // Fix barClose to apply more correct calculations for forex-market
   // Don't include weekends pex.
   // 
   // Period() - amount of minutes determining the used period (chart timeframe). 
   // datetime [datatype] - Seconds since January 1, 1970
   datetime barOpen = iTime(Symbol(), Period(), 0); // Time[0];
   datetime barClose;
   switch (Period()) {
      case PERIOD_MN1:
         // Advance one month worth of seconds
         // Use 31 days because PERIOD_MN1 represents 30 days
         barClose = barOpen + 31 * PERIOD_D1 * 60; 
         // Rewind until first day of following month
         barClose = barClose - (TimeDay(barClose) - 1) * PERIOD_D1 * 60;
         // Let's correct barClose now with week information to cope
         // with non-trading weekends that may occur at end of month
         datetime weekBarOpen = iTime(Symbol(), PERIOD_W1, iBarShift(Symbol(),PERIOD_W1, barOpen));
         if (weekBarOpen > 0) {
            datetime lastWeekBarOpen = weekBarOpen;
            int stepSize = PERIOD_W1 * 60;
            while (lastWeekBarOpen + stepSize < barClose) {
               lastWeekBarOpen = lastWeekBarOpen + stepSize;
            }
            // Same logic as when Period() == PERIOD_W1 (below)
            datetime lastWeekBarClose = lastWeekBarOpen + (PERIOD_D1 * 5) * 60; 
            if (lastWeekBarClose < barClose) {
               barClose = lastWeekBarClose;
            }
         }
         break;
      case PERIOD_W1: // 10080 <=> 7 days minutes
         // Correct barClose to cope with non-trading weekends
         // Advance only 5 days from the start of the week
         barClose = barOpen + (PERIOD_D1 * 5) * 60; 
         break;
      default:
         barClose = barOpen + Period() * 60; 
         break;
   }
   // remainingDuration - This value is in seconds
   int remainingDuration = barClose - TimeCurrent();
   if (remainingDuration < 0) {
      // MT when changing TF may not have updated 'Time'
      // yet Period() is already updated it seems
      return (0);
   }
   string durationStr = createDurationString(remainingDuration," month(s) "," week(s) "," day(s) "," hour(s) "," minute(s) "," second(s) ");
   string smallDurationStr = createDurationString(remainingDuration,"M","w","d","h","m","s");

   /*
	double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   Comment( m + " minutes " + s + " seconds left to bar end");
   */
   Comment( durationStr + "left to bar end" );
   
   if((ObjectFind("time") != 0) || (ObjectType("time") != OBJ_TEXT)) {
      ObjectDelete("time");
      ObjectCreate("time", OBJ_TEXT, 0, 0, 0);
   }
   ObjectSetText("time", "                           " + smallDurationStr + " to close", 10, "Tahoma", MediumTurquoise);
   // ObjectMove("time", 0, Time[0], Close[0]);
   // ObjectMove("time", 0, Time[0], (High[0]+Close[0]) / 2);
   ObjectMove("time", 0, Time[0], High[0]);
   
	
   /*
   ObjectDelete("time");
   
   if(ObjectFind("time") != 0)
   {
   ObjectCreate("time", OBJ_TEXT, 0, Time[0], Close[0]+ 0.0005);
   ObjectSetText("time", "                                 <--"+m+":"+s, 13, "Verdana", MediumTurquoise);
   }
   else
   {
   ObjectMove("time", 0, Time[0], Close[0]+0.0005);
   }
   */

   return(0);
}

// remainingDuration - This value is in seconds
string createDurationString(int remainingDuration, string monthsSuffix, string weeksSuffix, string daysSuffix, string hoursSuffix, string minutesSuffix, string secondsSuffix) {
   int months = remainingDuration / (PERIOD_MN1 * 60);
   remainingDuration = remainingDuration % (PERIOD_MN1 * 60);
   int weeks = remainingDuration / (PERIOD_W1 * 60);
   remainingDuration = remainingDuration % (PERIOD_W1 * 60);
   int days = remainingDuration / (PERIOD_D1 * 60);
   remainingDuration = remainingDuration % (PERIOD_D1 * 60);
   int hours = remainingDuration / (PERIOD_H1 * 60);
   remainingDuration = remainingDuration % (PERIOD_H1 * 60);
   int minutes = remainingDuration / (PERIOD_M1 * 60);
   remainingDuration = remainingDuration % (PERIOD_M1 * 60);
   int seconds = remainingDuration;
   
   string durationStr = "";
   int maxEntries = 2;
   if (months > 0 && (maxEntries > 0)) {
      durationStr = durationStr + months + monthsSuffix; // Support offline charts (?) with larger TF than Month
      maxEntries--;
   }
   if ((weeks > 0) && (maxEntries > 0)) {
      durationStr = durationStr + weeks + weeksSuffix;
      maxEntries--;
   }
   if ((days > 0) && (maxEntries > 0)) {
      durationStr = durationStr + days + daysSuffix;
      maxEntries--;
   }
   if ((hours > 0) && (maxEntries > 0)) {
      durationStr = durationStr + hours + hoursSuffix;
      maxEntries--;
   }
   if ((minutes > 0) && (maxEntries > 0)) {
      if (minutes < 10) {
         durationStr = durationStr + "0" + minutes + minutesSuffix;
      } else {
         durationStr = durationStr + minutes + minutesSuffix;
      }
      maxEntries--;
   }
   if (maxEntries > 0) {
      if (seconds < 10) {
         durationStr = durationStr + "0" + seconds + secondsSuffix;
      } else {
         durationStr = durationStr + seconds + secondsSuffix;
      }
      maxEntries--;
   }
   
   return (durationStr);
}
//+------------------------------------------------------------------+


