#property copyright "Saver0"
#property link      "http://www.forexfactory.com/saver0"


#property indicator_chart_window

extern int maxBars = 1000;
extern string forTimeFrame = 240;
extern int drawEvery_X_Bars = 10;

string _obj = "Boxes_";

int theTimeFrame = 0;

int deinit() {

   for (int index = 0; index < ObjectsTotal(); index++)
	{
		if (StringFind(ObjectName(index), _obj) == 0)
		{
			ObjectDelete(ObjectName(index));
			index--;
		}
	}
	
	
   return(0);
}

int init()
{
   theTimeFrame = stringToTimeFrame(forTimeFrame);
   return(0);
}



int lastRanBar = 0;
int start()
{
   int counted_bars=IndicatorCounted();

   int limit=Bars-counted_bars+2;

   if(limit > maxBars)
      limit = maxBars;
      
   for(int a=limit; a>=0; a--)
   {
      int time = iTime(NULL, theTimeFrame, a);
      
      if(drawEvery_X_Bars > 0)
      {
         int pos = a;
         a = a-drawEvery_X_Bars+1;
      }
      else
      {
         pos = iBarShift(NULL, 0, time);
      }
         
      int barsInBar = theTimeFrame/Period();
      
      double highVal = -1000;
      double lowVal = 1000;
      int highPos = -1;
      int lowPos = -1;
      
      
      
      if(pos-barsInBar > 0)
      {
         for(int b=0; b<barsInBar; b++)
         {
            if(High[pos-b] > highVal)
            {
               highVal = High[pos-b];
               highPos = pos-b;
            }
            
            if(Low[pos-b] < lowVal)
            {
               lowVal = Low[pos-b];
               lowPos = pos-b;
            }
         } 
         
         if(highPos != -1 && lowPos != -1)
         {
            //Left Line
            int x1 = Time[pos];
            int x2 = Time[highPos];
            double y1 = Open[pos];
            double y2 = High[highPos];         
            Trend_Line(x1, x2, y1, y2, Yellow, 0);
            
            //Bottom Line
            x1 = Time[pos];
            x2 = Time[lowPos];
            y1 = Open[pos];
            y2 = Low[lowPos];         
            Trend_Line(x1, x2, y1, y2, Yellow, 0);
            
            //Top Line
            //if(pos-lowPos != 0)
            {
               x1 = Time[highPos];
               if(highPos - (pos-lowPos) >= 0)
                  x2 = Time[highPos - (pos-lowPos)];
               else
                  x2 = Time[highPos] + ((pos-lowPos)*Period()*60);
               y1 = High[highPos];
               y2 = High[highPos] - (Open[pos] - Low[lowPos]);
               Trend_Line(x1, x2, y1, y2, Yellow, 0);
            }
            
            //Bottom Line
            //if(pos-highPos != 0)
            {
               x1 = Time[lowPos];
               y1 = Low[lowPos];
               y2 = High[highPos] - (Open[pos] - Low[lowPos]);
               Trend_Line(x1, x2, y1, y2, Yellow, 0);
            }
            int startPos = iBarShift(NULL, 0, x2);
            bool found = false;
            for(int c=startPos; c >= 0; c--)
            {
               if(y2 > Low[c] && y2 < High[c])
               {
                  Trend_Line(x2, Time[c], y2, y2, Red, 0);
                  found = true;
                  break;
               }
            }
            if(!found)
            {
               Trend_Line(x2, Time[0], y2, y2, Red, 0);
            }
         }
   
      }
   }
      

   return(0);
}  

int lineCount = 0;
void Trend_Line(
    datetime x1, datetime x2, double y1, 
    double y2, color lineColor, double style){
    //~~~~~~~~~~
    string label = _obj+"_"+lineCount;
    ObjectDelete(label);
    ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
    ObjectSet(label, OBJPROP_RAY, 0);
    ObjectSet(label, OBJPROP_COLOR, lineColor);
    ObjectSet(label, OBJPROP_STYLE, style);
    
    lineCount++;
    //~~~~~~~~~~
}

int debugLine = 0;
void printDebug(string msg)
{
   //if(showDebug)
   {
      int y = 15*debugLine;
      int x = 20+MathFloor(y/800)*410;
      
      y = 20+MathMod(y,800);
     
      DrawLabel(_obj+"-Deubug-"+debugLine, msg, x, y, DodgerBlue, "Arial", 9);
      debugLine++;
   }
}


void DrawLabel(string label, string text, int x, int y, color clr, string fontName, int fontSize)
{
   int typeCorner = 0;
 
   string labelIndicator = label;   
   if (ObjectFind(labelIndicator) == -1)
   {
      ObjectCreate(labelIndicator, OBJ_LABEL, 0, 0, 0);
   }
   
   ObjectSet(labelIndicator, OBJPROP_CORNER, typeCorner);
   ObjectSet(labelIndicator, OBJPROP_XDISTANCE, x);
   ObjectSet(labelIndicator, OBJPROP_YDISTANCE, y);
   ObjectSetText(labelIndicator, text, fontSize, fontName, clr);
}

string getPeriod()
{
   switch(Period())
   {
      case 1:
      {
         return ("m1");
         break;
      }
      case 5:
      {
         return ("m5");
         break;
      }
      case 15:
      {
         return ("m15");
         break;
      }
      case 30:
      {
         return ("m30");
         break;
      }
      case 60:
      {
         return ("h1");
         break;
      }
      case 240:
      {
         return ("h4");
         break;
      }
      case 1440:
      {
         return ("d1");
         break;
      }
   }
}
  
int GetBrokerGMTOffset(int AccuracyThresholdInMinutes = 60)
{
   int lGMT = TimeGMT();

   // Get the current broker time and round the difference to the nearest n minutes
   int lBrokerTimestamp = TimeCurrent();
   double lDiff = lBrokerTimestamp - lGMT;
   lDiff = MathRound(lDiff / (AccuracyThresholdInMinutes * 60));
   lDiff *= (AccuracyThresholdInMinutes * 60);
   return (lDiff);

}


string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

int stringToTimeFrame(string tfs)
{
   tfs = stringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
   {
         if(tfs==sTfTable[i] || tfs==iTfTable[i])
         {
            return(iTfTable[i]);
         }
   }
   return(Period());
}

string TimeFrameToString(int tfs)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==iTfTable[i]) return(sTfTable[i]);
   
   return(Period());
}

string stringUpperCase(string str)
{
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int chars = StringGetChar(s, length);
         if((chars > 96 && chars < 123) || (chars > 223 && chars < 256))
                     s = StringSetChar(s, length, chars - 32);
         else if(chars > -33 && chars < 0)
                     s = StringSetChar(s, length, chars + 224);
   }
   return(s);
}

