//------------------------------------------------------------------
#property copyright "mladen"
#property link      "mladenfx@gmail.com"
//------------------------------------------------------------------

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1  clrBlue
#property indicator_color2  clrRed
#property indicator_color3  clrLimeGreen
#property indicator_color4  clrRed
#property indicator_color5  clrLimeGreen
#property strict

//
//
//
//
//
enum enTimeFrames
{
   tf_cu  = PERIOD_CURRENT, // Current time frame
   tf_m1  = PERIOD_M1,      // 1 minute
   tf_m5  = PERIOD_M5,      // 5 minutes
   tf_m15 = PERIOD_M15,     // 15 minutes
   tf_m30 = PERIOD_M30,     // 30 minutes
   tf_h1  = PERIOD_H1,      // 1 hour
   tf_h4  = PERIOD_H4,      // 4 hours
   tf_d1  = PERIOD_D1,      // Daily
   tf_w1  = PERIOD_W1,      // Weekly
   tf_mn1 = PERIOD_MN1,     // Monthly
   tf_n1  = -1,             // First higher time frame
   tf_n2  = -2,             // Second higher time frame
   tf_n3  = -3              // Third higher time frame
};

extern enTimeFrames    TimeFrame          = tf_n1;   // Time frame
extern int                JawsPeriod  = 13;              // Jaws period
extern int                JawsShift   = 8;               // Jaws shift
extern int                TeethPeriod = 8;               // Teeth period
extern int                TeethShift  = 5;               // Teeth shift
extern int                LipsPeriod  = 5;               // Lips period
extern int                LipsShift   = 3;               // Lips shift
extern ENUM_MA_METHOD     MaMode      = MODE_SMMA;       // Average method
extern ENUM_APPLIED_PRICE MaPrice     = PRICE_MEDIAN;    // Price
extern bool               Interpolate = true;            // Interpolate in mtf mode?

//
//
//
//
//

double BlueBuffer[],RedBuffer[],LimeBuffer[],arrowUp[],arrowDn[],count[],state[];
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,tf_cu,JawsPeriod,0,TeethPeriod,0,LipsPeriod,0,MaMode,MaPrice,_buff,_ind)

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//

int init()
{
   for (int i=0; i<indicator_buffers; i++) SetIndexStyle(i,DRAW_LINE);
   IndicatorBuffers(7);
   SetIndexBuffer(0,BlueBuffer); SetIndexLabel(0,"Gator Jaws");
   SetIndexBuffer(1,RedBuffer);  SetIndexLabel(1,"Gator Teeth");
   SetIndexBuffer(2,LimeBuffer); SetIndexLabel(2,"Gator Lips");
   SetIndexBuffer(3,arrowUp);    SetIndexStyle(3,DRAW_ARROW); SetIndexArrow(3,SYMBOL_ARROWUP);
   SetIndexBuffer(4,arrowUp);    SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,SYMBOL_ARROWUP);
   SetIndexBuffer(5,count);
   SetIndexBuffer(6,state);
   
      //
      //
      //
      //
      //
     
         indicatorFileName = WindowExpertName();
         TimeFrame         = (enTimeFrames)timeFrameValue(TimeFrame);
         SetIndexShift(0,JawsShift  * TimeFrame/_Period);  
         SetIndexShift(1,TeethShift * TimeFrame/_Period);  
         SetIndexShift(2,LipsShift  * TimeFrame/_Period);  
   IndicatorShortName(timeFrameToString(TimeFrame)+"   Alligator");
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); count[0]=limit;
         if (TimeFrame!=_Period)
         {
            limit = (int)fmax(limit,fmin(Bars-1,_mtfCall(5,0)*TimeFrame/_Period));
            for (int i=limit; i>=0; i--)
            {   
               int y = iBarShift(NULL,TimeFrame,Time[i]);
                  BlueBuffer[i] = _mtfCall(0,y);
                  RedBuffer[i]  = _mtfCall(1,y);
                  LimeBuffer[i] = _mtfCall(2,y);
                  
                  //
                  //
                  //
                  //
                  //
                  
                  if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                     #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                     int n,k; datetime time = iTime(NULL,TimeFrame,y);
                        for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;	
                        for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++) 
                        {
                           _interpolate(BlueBuffer);
                           _interpolate(RedBuffer);
                           _interpolate(LimeBuffer);
                        }                        
            }
            return(0);
         }       

   //
   //
   //
   //
   //
   
   for (int i = limit; i >= 0 ; i--)
   {
      BlueBuffer[i] = iMA(NULL,0,JawsPeriod, 0,MaMode,MaPrice,i);
      RedBuffer[i]  = iMA(NULL,0,TeethPeriod,0,MaMode,MaPrice,i);
      LimeBuffer[i] = iMA(NULL,0,LipsPeriod, 0,MaMode,MaPrice,i);
      
       
   }
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
int timeFrameValue(int _tf)
{
   int add  = (_tf>=0) ? 0 : MathAbs(_tf);
   if (add != 0) _tf = _Period;
   int size = ArraySize(iTfTable); 
      int i =0; for (;i<size; i++) if (iTfTable[i]==_tf) break;
                                   if (i==size) return(_Period);
                                                return(iTfTable[(int)MathMin(i+add,size-1)]);
}