//+------------------------------------------------------------------+
//|                                           ! ! !SemaphorTrue2.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, zznbrm"
                          
//---- indicator settings
#property indicator_chart_window
#property  indicator_buffers 6 
#property  indicator_color1 Gray
#property  indicator_color2 Magenta
#property  indicator_color3 Yellow
#property  indicator_color4 Gray
#property  indicator_color5 Magenta
#property  indicator_color6 Yellow
#property  indicator_width1 2
#property  indicator_width2 2
#property  indicator_width3 2
#property  indicator_width4 2
#property  indicator_width5 2
#property  indicator_width6 2

//---- input parameters
extern int eintDepth1 = 5;
extern int eintDepth2 = 13;
extern int eintDepth3 = 34;
extern double edblOffsetPoints = 50.0;
extern int MaxBars = 1000;

extern string _alerts = "--- Alerts ---";
extern bool Ball1_Alerts = false;
extern bool Ball2_Alerts = true;
extern bool Ball3_Alerts = true;
extern bool Send_Emails = true;
extern bool Show_Popup = true;


//---- indicator buffers
double gadblUp1[];
double gadblUp2[];
double gadblUp3[];
double gadblDn1[];
double gadblDn2[];
double gadblDn3[];

int MaxBars2;
datetime lastTime = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   SetIndexBuffer( 0, gadblUp1 );
   SetIndexEmptyValue( 0, 0.0 );
   SetIndexStyle( 0, DRAW_ARROW );
   SetIndexArrow( 0, 159 ); 
   SetIndexLabel( 0, "Up1" );

   SetIndexBuffer( 1, gadblUp2 );
   SetIndexEmptyValue( 1, 0.0 );
   SetIndexStyle( 1, DRAW_ARROW );
   SetIndexArrow( 1, 159 ); 
   SetIndexLabel( 1, "Up2" );
   
   SetIndexBuffer( 2, gadblUp3 );
   SetIndexEmptyValue( 2, 0.0 );
   SetIndexStyle( 2, DRAW_ARROW );
   SetIndexArrow( 2, 159 ); 
   SetIndexLabel( 2, "Up3" );
   
   SetIndexBuffer( 3, gadblDn1 );
   SetIndexEmptyValue( 3, 0.0 );
   SetIndexStyle( 3, DRAW_ARROW );
   SetIndexArrow( 3, 159 ); 
   SetIndexLabel( 3, "Dn1" );
   
   SetIndexBuffer( 4, gadblDn2 );
   SetIndexEmptyValue( 4, 0.0 );
   SetIndexStyle( 4, DRAW_ARROW );
   SetIndexArrow( 4, 159 ); 
   SetIndexLabel( 4, "Dn2" );
   
   SetIndexBuffer( 5, gadblDn3 );
   SetIndexEmptyValue( 5, 0.0 );
   SetIndexStyle( 5, DRAW_ARROW );
   SetIndexArrow( 5, 159 ); 
   SetIndexLabel( 5, "Dn3" ); 
    
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
     
   //---- name for DataWindow and indicator subwindow label
   IndicatorShortName( "SemaphorTrue2(" + eintDepth1 + "," + eintDepth2 + "," + eintDepth3 + ")" );   
   
   lastTime = Time[0];
   
   return( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   return( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   if(MaxBars > 0 && MaxBars < Bars)
      MaxBars2 = MaxBars;
   else
      MaxBars2 = Bars;
      
   int counted_bars = IndicatorCounted();
   
   if (counted_bars < 0) return (-1);
   if (counted_bars > 0) counted_bars--;
   int intLimit = Bars - counted_bars;
   int intLow1, intLow2, intLow3, intHigh1, intHigh2, intHigh3;

   if(intLimit > MaxBars2) intLimit = MaxBars2;

   for( int inx = intLimit; inx >= 0; inx-- )
   {          
      gadblUp1[inx] = 0.0;  gadblUp2[inx] = 0.0;    gadblUp3[inx] = 0.0;
      gadblDn1[inx] = 0.0;  gadblDn2[inx] = 0.0;    gadblDn3[inx] = 0.0;
      
      intLow1 = iLowest( Symbol(), Period(), MODE_LOW, eintDepth1, inx );
      intLow2 = iLowest( Symbol(), Period(), MODE_LOW, eintDepth2, inx );
      intLow3 = iLowest( Symbol(), Period(), MODE_LOW, eintDepth3, inx );
      
      if ( intLow3 == inx )
      {
         gadblUp3[inx] = Low[inx] - (edblOffsetPoints*Point);
      }
      else if ( intLow2 == inx )
      {
         gadblUp2[inx] = Low[inx] - (edblOffsetPoints*Point);
      }
      else if ( intLow1 == inx )
      {
         gadblUp1[inx] = Low[inx] - (edblOffsetPoints*Point);
      }
      
      intHigh1 = iHighest( Symbol(), Period(), MODE_HIGH, eintDepth1, inx );
      intHigh2 = iHighest( Symbol(), Period(), MODE_HIGH, eintDepth2, inx );
      intHigh3 = iHighest( Symbol(), Period(), MODE_HIGH, eintDepth3, inx );
      
      if ( intHigh3 == inx )
      {
         gadblDn3[inx] = High[inx] + (edblOffsetPoints*Point);
      }
      else if ( intHigh2 == inx )
      {
         gadblDn2[inx] = High[inx] + (edblOffsetPoints*Point);
      }
      else if ( intHigh1 == inx )
      {
         gadblDn1[inx] = High[inx] + (edblOffsetPoints*Point);
      }
   }
   
   if(Time[0] > lastTime){
      lastTime = Time[0];
      string txt = "";
      string ending = Symbol() +  " " + PeriodToStr(Period());
      
      if(Ball1_Alerts && gadblUp1[1] > 0)
         txt = "BALL 1  UP  - " + ending;
         
      if(Ball1_Alerts && gadblDn1[1] > 0)
         txt = "BALL 1  DOWN  - " + ending;
         
      if(Ball2_Alerts && gadblUp2[1] > 0)
         txt = "BALL 2  UP  - " + ending;
         
      if(Ball2_Alerts && gadblDn2[1] > 0)
         txt = "BALL 2  DOWN  - " + ending;
         
      if(Ball3_Alerts && gadblUp3[1] > 0)
         txt = "BALL 3  UP  - " + ending;
         
      if(Ball3_Alerts && gadblDn3[1] > 0)
         txt = "BALL 3  DOWN  - " + ending;
         
      if(Send_Emails && txt != "")
         SendMail(txt, txt);
         
      if(Show_Popup && txt != "")
         Alert(txt);
   }
   
   return( 0 );
}

string PeriodToStr(int p){
   switch(p){
      case PERIOD_M1: return("M1");
      case PERIOD_M5: return("M5");
      case PERIOD_M15: return("M15");
      case PERIOD_M30: return("M30");
      case PERIOD_H1: return("H1");
      case PERIOD_H4: return("H4");
      case PERIOD_D1: return("D1");
      case PERIOD_W1: return("W1");
      case PERIOD_MN1: return("MN1");
      default: return("" + Period());
   }
}
