//+------------------------------------------------------------------+
//|                                         SuperJolt MoneyLanes.mq4 |
//|                                        Copyright 2015, SuperJolt |
//|                                             http://SuperJolt.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2015, SuperJolt"
#property link      "http://SuperJolt.com"
#property version   "1.20"
#property strict
#property indicator_chart_window

//+-----------------------------------------------------------------+
#import "SuperJolt.MT4.MoneyLanes.dll"

   int _CreateIndicatorInstance(int hostFrameHandle, string symbolName, int digits, double pips2dbl,string dataFilesPath,int lane1Period, int lane2Period, int lane3Period, int lane4Period,
            int roadblockDistance,
            int shadeDistancesLen, double &shadeDistances[],
            int movingAveragesPeriodsLen, int &movingAveragesPeriods[],
            int leftOffsetInPixels,
            bool showRoadblocks,
            bool squaresMode,
            int chartPeriod,
            bool showPriceLevels,
            string screenshotsFilesPath,
            bool showBidAskZone,
            bool showPriceLevelsOnLeft);
   
   void _SendRates(int hostFrameHandle, 
            int len,
            double &lane1MAs[],
            double &lane2MAs[],
            double &lane3MAs[],
            double &lane4MAs[],
            double bid, double ask,
            bool tf1IsBull,
            bool tf2IsBull,
            bool tf3IsBull,
            bool tf4IsBull            
            );
   
   void _RemoveIndicatorInstance(int hostFrameHandle);
   
#import
//+------------------------------------------------------------------+

int hostFrameHandle;

string OLabel = "MoneyLanes";

extern int tf1 = 1; //Lane 1 timeframe in minutes
extern int tf2 = 5; //Lane 2 timeframe in minutes
extern int tf3 = 15; //Lane 3 timeframe in minutes
extern int tf4 = 60; //Lane 4 timeframe in minutes
extern bool showRoadblocks = true; //Show roadblocks
extern int roadblockDistance = 1; //Max pips between prices to form a roadblock
extern int leftOffsetInPixels = 0; //Indent from left side of chart in pixels
extern bool squaresMode = true; //Show squares instead of background rectangles
extern bool showPriceLevels = true; //Show price levels for chart
extern bool showPriceLevelsOnLeft = false; //Show price levels on Left side
extern string screenshotsFilePath = ""; //Path to save screenshots, blank to show dialog instead
extern bool isIndex = false; //Chart is an Index? e.g. GER30, SPA35
extern bool showBidAskZone = true; //Show the Ask Line

//+------------------------------------------------------------------+

//Do not change the number of elements in each array
double ShadeDistances[10] = {10, 16, 26, 42, 68, 111, 179, 290, 470, 760};
int MovingAveragesPeriods[7] = {21,34,55,75,100,144,233};   
//+------------------------------------------------------------------+

bool isIndicatorInitialised = false;

//+------------------------------------------------------------------+

int OnInit()
{
   if(!IsDllsAllowed()) {
      Alert("Error: DLL calls must be allowed for MoneyLanes to open. Please check your settings");
      return(INIT_FAILED);
   }
   
   hostFrameHandle = WindowHandle(Symbol(), Period());
   double pips2dbl, pips2points;
   
   if (Digits == 5 || Digits == 3 || isIndex)
   {   // Adjust for five (5) digit brokers.
       pips2dbl    = Point*10; 
       pips2points = 10;
   }
   else
   {    
      pips2dbl = Point;
      pips2points =  1;
   } 
   
   string dataPath=TerminalInfoString(TERMINAL_DATA_PATH);
   int result = _CreateIndicatorInstance(hostFrameHandle, Symbol(), Digits, pips2dbl, dataPath, tf1,tf2,tf3,tf4, 
                                          roadblockDistance, 
                                          ArraySize(ShadeDistances), ShadeDistances, 
                                          ArraySize(MovingAveragesPeriods), MovingAveragesPeriods,
                                          leftOffsetInPixels,
                                          showRoadblocks,
                                          squaresMode,
                                          Period(),
                                          showPriceLevels,
                                          screenshotsFilePath,
                                          showBidAskZone,
                                          showPriceLevelsOnLeft);
   
   if (result<0)
   {
      Print("Error - CreateInstance failed");
      return(INIT_FAILED);
   }
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+

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[])
{

   double lane1MAs[7];
   lane1MAs[0] = GetMovingAverage(tf1, MovingAveragesPeriods[0]);
   lane1MAs[1] = GetMovingAverage(tf1, MovingAveragesPeriods[1]);
   lane1MAs[2] = GetMovingAverage(tf1, MovingAveragesPeriods[2]);
   lane1MAs[3] = GetMovingAverage(tf1, MovingAveragesPeriods[3]);
   lane1MAs[4] = GetMovingAverage(tf1, MovingAveragesPeriods[4]);
   lane1MAs[5] = GetMovingAverage(tf1, MovingAveragesPeriods[5]);
   lane1MAs[6] = GetMovingAverage(tf1, MovingAveragesPeriods[6]);
   
   double lane2MAs[7];
   lane2MAs[0] = GetMovingAverage(tf2, MovingAveragesPeriods[0]);
   lane2MAs[1] = GetMovingAverage(tf2, MovingAveragesPeriods[1]);
   lane2MAs[2] = GetMovingAverage(tf2, MovingAveragesPeriods[2]);
   lane2MAs[3] = GetMovingAverage(tf2, MovingAveragesPeriods[3]);
   lane2MAs[4] = GetMovingAverage(tf2, MovingAveragesPeriods[4]);
   lane2MAs[5] = GetMovingAverage(tf2, MovingAveragesPeriods[5]);
   lane2MAs[6] = GetMovingAverage(tf2, MovingAveragesPeriods[6]);
                 
   double lane3MAs[7];
   lane3MAs[0] = GetMovingAverage(tf3, MovingAveragesPeriods[0]);
   lane3MAs[1] = GetMovingAverage(tf3, MovingAveragesPeriods[1]);
   lane3MAs[2] = GetMovingAverage(tf3, MovingAveragesPeriods[2]);
   lane3MAs[3] = GetMovingAverage(tf3, MovingAveragesPeriods[3]);
   lane3MAs[4] = GetMovingAverage(tf3, MovingAveragesPeriods[4]);
   lane3MAs[5] = GetMovingAverage(tf3, MovingAveragesPeriods[5]);
   lane3MAs[6] = GetMovingAverage(tf3, MovingAveragesPeriods[6]);
   
   double lane4MAs[7];
   lane4MAs[0] = GetMovingAverage(tf4, MovingAveragesPeriods[0]);
   lane4MAs[1] = GetMovingAverage(tf4, MovingAveragesPeriods[1]);
   lane4MAs[2] = GetMovingAverage(tf4, MovingAveragesPeriods[2]);
   lane4MAs[3] = GetMovingAverage(tf4, MovingAveragesPeriods[3]);
   lane4MAs[4] = GetMovingAverage(tf4, MovingAveragesPeriods[4]);
   lane4MAs[5] = GetMovingAverage(tf4, MovingAveragesPeriods[5]);
   lane4MAs[6] = GetMovingAverage(tf4, MovingAveragesPeriods[6]);       
                                                              
   _SendRates(hostFrameHandle, 7, lane1MAs, lane2MAs, lane3MAs, lane4MAs, Close[0], Ask, 
         iClose(Symbol(),tf1,0) > iClose(Symbol(),tf1,1),
         iClose(Symbol(),tf2,0) > iClose(Symbol(),tf2,1),
         iClose(Symbol(),tf3,0) > iClose(Symbol(),tf3,1),
         iClose(Symbol(),tf4,0) > iClose(Symbol(),tf4,1)        
         );

   return(rates_total);
}
//+------------------------------------------------------------------+

double GetMovingAverage(int timeframe, int period)
{
   return iMA(Symbol(),timeframe,period,0, MODE_SMA, PRICE_CLOSE,0);
}

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   int obj_total=ObjectsTotal();
   for(int i = obj_total - 1; i >= 0; i--)
   {
      string label = ObjectName(i);
      if(StringFind(label, OLabel)==-1) continue;
      ObjectDelete(label); 
   }     
   
   if(IsDllsAllowed())
      _RemoveIndicatorInstance(hostFrameHandle);
   
   return;
}

//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // Event identifier  
                  const long& lparam,   // Event parameter of long type
                  const double& dparam, // Event parameter of double type
                  const string& sparam) // Event parameter of string type
{
   /*if(id==CHARTEVENT_KEYDOWN)
   {
      Print("KEY=" + int(lparam));
   }*/
}
//+------------------------------------------------------------------+