/*
   Generated by EX4-TO-MQ4 decompiler V4.0.224.1 []
   Website: http://purebeam.biz
   E-mail : purebeam@gmail.com
*/
#property copyright "Copyright © 2010, NiX"
#property link      "http://www.the-forex-strategy.com"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Black

#include <WinUser32.mqh>

extern int Range = 13;
extern int OutputTimeFrame = 2;
extern bool FiveDigitBroker = TRUE;
extern bool DisableComment = FALSE;
extern bool RefreshWindowOnAskPriceChange = FALSE;
extern int RenderUsing1MhistoryBars = 7200;
extern string SoundSignalOnNewBar = "clock_tick.wav";
int g_file_108 = -1;
int gi_112;
int gi_120 = 0;
double gd_124 = 0.0;
double gd_132 = 0.0;
double gd_140 = 0.0;
double gd_148 = 0.0;
double gd_156 = 0.0;
int gi_164 = 0;
bool gi_unused_168 = FALSE;
int gi_172 = 0;
bool gi_176 = FALSE;
int gi_180;
int gi_184 = 0;
int gi_188 = 0;
int gi_192 = 400;
string gs_196;
string gs_204;
int gi_212;
int g_digits_216;
int gia_220[13];
double gd_224;
double g_bid_232;
bool gi_240 = FALSE;
int gi_244 = 0;
string g_name_248 = "RB_title";
string g_name_256 = "RB_underline";
int gi_264 = 20;
string gsa_268[20] = {"RB_aux1", "RB_aux2", "RB_aux3", "RB_aux4", "RB_aux5", "RB_aux6", "RB_aux7", "RB_aux8", "RB_aux9", "RB_aux10", "RB_aux11", "RB_aux12", "RB_aux13", "RB_aux14", "RB_aux15", "RB_aux16", "RB_aux17", "RB_aux18", "RB_aux19", "RB_aux20"};

void DebugMsg(string as_0) {
   if (gi_176) Alert(as_0);
}

void DebugPrint(string as_0) {
   if (gi_176) Print(as_0);
}

bool isMTready() {
   RefreshRates();
   double l_bid_0 = MarketInfo(Symbol(), MODE_BID);
   double l_ask_8 = MarketInfo(Symbol(), MODE_ASK);
   if (l_bid_0 > 0.0 && l_ask_8 > 0.0) return (TRUE);
   return (FALSE);
}

int init() {
   while (!isMTready()) Sleep(100);
   gs_204 = Symbol();
   gi_212 = Period() * OutputTimeFrame;
   g_digits_216 = Digits;
   if (Period() != PERIOD_M1) {
      Alert("Please attach the script to 1M chart only! Exiting...");
      Range = 0;
      return (0);
   }
   switch (OutputTimeFrame) {
   case 0:
   case 1:
   case 5:
   case 15:
   case 30:
   case 60:
   case 240:
   case 1440:
   case 10080:
   case 43200:
      Alert(OutputTimeFrame + " is a Metatrader4 reserver time frame. Please choose a different value. Exiting...");
   }
   if (!IsDllsAllowed()) {
      Alert("The live range bar feed will not work if DLL calls are disabled! Exiting...");
      return (0);
   }
   if (!DisableComment) {
      if (ObjectFind(g_name_248) == -1) ObjectCreate(g_name_248, OBJ_LABEL, 0, 0, 0);
      if (ObjectFind(g_name_256) == -1) ObjectCreate(g_name_256, OBJ_LABEL, 0, 0, 0);
      while (ObjectFind(gsa_268[gi_244]) == 0) gi_244++;
      if (gi_244 >= gi_264) {
         Alert("Indicator limit reached. Exiting...");
         return (0);
      }
      ObjectCreate(gsa_268[gi_244], OBJ_LABEL, 0, 0, 0);
      ObjectSetText(gsa_268[gi_244], Range + " pip range bars @ offline " + Symbol() + ",M" + OutputTimeFrame, 11, "Terminal", Gray);
      ObjectSet(gsa_268[gi_244], OBJPROP_CORNER, 1);
      ObjectSet(gsa_268[gi_244], OBJPROP_XDISTANCE, 5);
      ObjectSet(gsa_268[gi_244], OBJPROP_YDISTANCE, 13 * gi_244 + 40);
      ObjectSetText(g_name_248, "RangeBar Plugin v" + "1.03a" + " for MT4 (c)2010 NiX", 11, "Terminal", RoyalBlue);
      ObjectSet(g_name_248, OBJPROP_CORNER, 1);
      ObjectSet(g_name_248, OBJPROP_XDISTANCE, 5);
      ObjectSet(g_name_248, OBJPROP_YDISTANCE, 20);
      ObjectSetText(g_name_256, "__________________________________________", 11, "Terminal", Blue);
      ObjectSet(g_name_256, OBJPROP_CORNER, 1);
      ObjectSet(g_name_256, OBJPROP_XDISTANCE, 5);
      ObjectSet(g_name_256, OBJPROP_YDISTANCE, 25);
   }
   gi_172 = Range;
   if (FiveDigitBroker) Range = 10 * Range;
   int li_4 = (MarketInfo(Symbol(), MODE_ASK) - MarketInfo(Symbol(), MODE_BID)) / Point;
   if (Range < li_4) {
      Alert("You have chosen a range setting that is less than your spread for " + Symbol() + ". The setting has been updated to " + li_4);
      Range = li_4;
   }
   DebugPrint("range = " + Range);
   if (Range <= 0) return (0);
   g_file_108 = FileOpenHistory(gs_204 + gi_212 + ".hst", FILE_BIN|FILE_WRITE);
   if (g_file_108 < 0) return (-1);
   gs_196 = "(C)opyright 2010, NiX";
   FileWriteInteger(g_file_108, gi_192, LONG_VALUE);
   FileWriteString(g_file_108, gs_196, 64);
   FileWriteString(g_file_108, gs_204, 12);
   FileWriteInteger(g_file_108, gi_212, LONG_VALUE);
   FileWriteInteger(g_file_108, g_digits_216, LONG_VALUE);
   FileWriteInteger(g_file_108, 0, LONG_VALUE);
   FileWriteInteger(g_file_108, 0, LONG_VALUE);
   FileWriteArray(g_file_108, gia_220, 0, 13);
   gi_112 = FileTell(g_file_108);
   int li_8 = 0;
   if (Bars > RenderUsing1MhistoryBars) {
      if (RenderUsing1MhistoryBars == 0) li_8 = Bars;
      else li_8 = RenderUsing1MhistoryBars;
   } else li_8 = Bars;
   for (gi_180 = li_8 - 1; gi_180 >= 0; gi_180--) processHistoryBar(Time[gi_180], Open[gi_180], Low[gi_180], High[gi_180], Close[gi_180], Volume[gi_180], 1);
   gi_120 = Time[gi_180 + 1];
   gi_188 = gi_120;
   while (gi_120 <= gi_188) gi_120++;
   DebugPrint("History written! lastpos: " + gi_112);
   gd_224 = NormalizeDouble(Range * Point, Digits);
   FileSeek(g_file_108, 0, SEEK_END);
   FileWriteInteger(g_file_108, gi_120, LONG_VALUE);
   FileWriteDouble(g_file_108, gd_124, DOUBLE_VALUE);
   FileWriteDouble(g_file_108, gd_132, DOUBLE_VALUE);
   FileWriteDouble(g_file_108, gd_140, DOUBLE_VALUE);
   FileWriteDouble(g_file_108, gd_148, DOUBLE_VALUE);
   FileWriteDouble(g_file_108, gd_156, DOUBLE_VALUE);
   FileFlush(g_file_108);
   gi_112 = FileTell(g_file_108);
   if (gi_184 == 0) {
      gi_184 = WindowHandle(gs_204, OutputTimeFrame);
      if (gi_184 != 0) DebugMsg("Chart window detected correctly");
   }
   if (gi_184 != 0)
      if (PostMessageA(gi_184, WM_COMMAND, 33324, 0) == 0) gi_184 = 0;
   RefreshRates();
   gi_240 = TRUE;
   return (0);
}

int deinit() {
   if (g_file_108 >= 0) {
      FileClose(g_file_108);
      g_file_108 = -1;
   }
   int l_count_0 = 0;
   for (int l_index_4 = 0; l_index_4 < gi_264; l_index_4++)
      if (ObjectFind(gsa_268[l_index_4]) == 0) l_count_0++;
   ObjectDelete(gsa_268[gi_244]);
   if (l_count_0 == 1) {
      ObjectDelete(g_name_248);
      ObjectDelete(g_name_256);
   }
   return (0);
}

int start() {
   if (g_bid_232 != Bid) {
      g_bid_232 = Bid;
      if (gi_184 == 0) {
         gi_184 = WindowHandle(gs_204, OutputTimeFrame);
         if (gi_184 != 0) DebugMsg("Chart window detected correctly");
      }
      if (gd_124 != 0.0) {
         if (gd_140 < Bid) gd_140 = Bid;
         if (gd_132 > Bid) gd_132 = Bid;
         gd_148 = Bid;
         gd_156 += 1.0;
      } else {
         gd_140 = Close[0];
         gd_132 = Close[0];
         gd_124 = Close[0];
         gd_148 = Close[0];
         gd_156 = 1;
         gi_120 = Time[0];
      }
      if (NormalizeDouble(gd_140 - gd_132, Digits) > gd_224) {
         DebugPrint("processing...");
         processHistoryBar(gi_120, gd_124, gd_132, gd_140, gd_148, gd_156, 1, 1);
         gi_188 = gi_120;
         for (gi_120 = Time[0] + 1; gi_120 <= gi_188; gi_120++) {
         }
         if (gi_184 != 0)
            if (PostMessageA(gi_184, WM_COMMAND, 33324, 0) == 0) gi_184 = 0;
         DebugPrint("done...");
      } else {
         FileSeek(g_file_108, gi_112 - 44, SEEK_SET);
         FileWriteInteger(g_file_108, gi_120, LONG_VALUE);
         FileWriteDouble(g_file_108, gd_124, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, gd_132, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, gd_140, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, gd_148, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, gd_156, DOUBLE_VALUE);
         FileFlush(g_file_108);
         if (gi_184 != 0)
            if (PostMessageA(gi_184, WM_COMMAND, 33324, 0) == 0) gi_184 = 0;
      }
   } else {
      if (RefreshWindowOnAskPriceChange) {
         if (gi_184 != 0)
            if (PostMessageA(gi_184, WM_COMMAND, 33324, 0) == 0) gi_184 = 0;
      }
   }
   return (0);
}

void updateHistory(int ai_0, double ad_4, double ad_12, double ad_20, double ad_28, double ad_36, bool ai_44 = FALSE) {
   int li_48;
   if (g_file_108 >= 0) {
      if (ai_44) {
         FileSeek(g_file_108, gi_112 - 44, SEEK_SET);
         DebugPrint("2H_rewrite--> " + TimeToStr(ai_0, TIME_SECONDS) + " " + ad_4 + " " + ad_12 + " " + ad_20 + " " + ad_28 + " " + ad_36);
      } else {
         FileSeek(g_file_108, gi_112, SEEK_SET);
         DebugPrint("2H_-seek----> " + TimeToStr(ai_0, TIME_SECONDS) + " " + ad_4 + " " + ad_12 + " " + ad_20 + " " + ad_28 + " " + ad_36);
      }
      FileWriteInteger(g_file_108, ai_0, LONG_VALUE);
      FileWriteDouble(g_file_108, ad_4, DOUBLE_VALUE);
      FileWriteDouble(g_file_108, ad_12, DOUBLE_VALUE);
      FileWriteDouble(g_file_108, ad_20, DOUBLE_VALUE);
      FileWriteDouble(g_file_108, ad_28, DOUBLE_VALUE);
      FileWriteDouble(g_file_108, ad_36, DOUBLE_VALUE);
      FileFlush(g_file_108);
      gi_112 = FileTell(g_file_108);
      if (ad_28 > ad_4) gi_unused_168 = TRUE;
      else {
         if (ad_4 == ad_28) {
            if (ad_20 - ad_4 > ad_4 - ad_12) gi_unused_168 = FALSE;
            else gi_unused_168 = TRUE;
         } else gi_unused_168 = FALSE;
      }
      if (ai_44) {
         li_48 = ai_0;
         for (gi_120 = Time[0]; gi_120 <= li_48; gi_120++) {
         }
         FileSeek(g_file_108, 0, SEEK_END);
         FileWriteInteger(g_file_108, gi_120, LONG_VALUE);
         FileWriteDouble(g_file_108, ad_28, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, ad_28, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, ad_28, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, ad_28, DOUBLE_VALUE);
         FileWriteDouble(g_file_108, 1, DOUBLE_VALUE);
         FileFlush(g_file_108);
         gi_112 = FileTell(g_file_108);
         DebugPrint("2H_following--> " + TimeToStr(gi_120, TIME_SECONDS) + " " + ad_28 + " " + ad_28 + " " + ad_28 + " " + ad_28 + " " + 1);
         if (gi_240 && SoundSignalOnNewBar != "") {
            if (SoundSignalOnNewBar == "alert_box") Alert("New bar on " + gi_172 + "pip chart for " + Symbol());
            else PlaySound(SoundSignalOnNewBar);
         }
      }
   }
}

void memoryBar(int ai_0, double ad_4, double ad_12, double ad_20, double ad_28, double ad_36) {
   if (gi_120 != 0) {
      gi_120 = ai_0;
      gd_156 = ad_36;
   } else gd_156 += ad_36;
   gd_124 = ad_4;
   gd_132 = ad_12;
   gd_140 = ad_20;
   gd_148 = ad_28;
   DebugPrint("## memoryBar--> " + TimeToStr(ai_0, TIME_SECONDS) + " " + ad_4 + " " + ad_12 + " " + ad_20 + " " + ad_28 + " " + ad_36);
}

void memoryBarClear() {
   gi_120 = 0;
   gd_124 = 0;
   gd_132 = 0;
   gd_140 = 0;
   gd_148 = 0;
   gd_156 = 0;
}

int processHistoryBar(int ai_0, double ad_4, double ad_12, double ad_20, double ad_28, double ad_36, int ai_44, bool ai_48 = FALSE) {
   double ld_76;
   double ld_84;
   double ld_92;
   double ld_100;
   if (ai_44 == 1 && gd_124 != 0.0) {
      DebugPrint("NB ------------> " + ad_4 + " " + ad_12 + " " + ad_20 + " " + ad_28);
      DebugPrint("MEM-----------> " + gd_124 + " " + gd_132 + " " + gd_140 + " " + gd_148);
      if (ad_20 < gd_140) ad_20 = gd_140;
      if (ad_12 > gd_132) ad_12 = gd_132;
      ad_4 = gd_124;
      DebugPrint("NB -updated----> " + ad_4 + " " + ad_12 + " " + ad_20 + " " + ad_28);
      gi_164 = ai_0;
   } else {
      DebugPrint("Recursive entry...");
      ai_0 = gi_164 + 1;
      gi_164 = ai_0;
   }
   double ld_52 = NormalizeDouble(Range * Point, Digits);
   double ld_60 = NormalizeDouble(MathAbs(ad_20 - ad_12), Digits);
   double ld_68 = NormalizeDouble(ad_28 - ad_4, Digits);
   if (ld_68 < 0.0 || (ld_68 == 0.0 && ad_28 > ad_12)) {
      if (ld_60 > ld_52) {
         ld_76 = NormalizeDouble(MathAbs(ad_20 - ad_4), Digits);
         if (ld_76 > ld_52) {
            if (ad_20 - ad_4 >= ld_52) {
               ld_84 = ad_4 + ld_52;
               updateHistory(ai_0, ad_4, ad_4, ld_84, ld_84, ad_36, ai_48);
               memoryBar(ai_0, ld_84, ad_12, ad_20, ad_28, ad_36);
               processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
               return (1);
            }
            ld_92 = ad_20 - ld_52;
            updateHistory(ai_0, ad_4, ld_92, ad_20, ld_92, ad_36, ai_48);
            memoryBar(ai_0, ld_92, ad_12, ad_20, ad_28, ad_36);
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
         if (ld_76 == ld_52) {
            updateHistory(ai_0, ad_4, ad_4, ad_20, ad_4, ad_36, ai_48);
            memoryBar(ai_0, ad_4, ad_12, ad_4, ad_28, ad_36);
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
         if (ld_76 < ld_52) {
            updateHistory(ai_0, ad_4, ad_20 - ld_52, ad_20, ad_20 - ld_52, ad_36, ai_48);
            if (ad_28 < ad_20 - ld_52 && ad_28 != ad_4) {
               memoryBar(ai_0, ad_20 - ld_52, ad_12, ad_20 - ld_52, ad_28, ad_36);
               DebugPrint("H2O1_exit");
            } else {
               if (ad_28 >= ad_20 - ld_52 && ad_28 != ad_4) {
                  memoryBar(ai_0, ad_20 - ld_52, ad_12, ad_20 - ld_52, ad_20 - ld_52, ad_36);
                  DebugPrint("H@O2_exit");
               } else {
                  if (ad_28 < ad_20 - ld_52 && ad_28 == ad_4) {
                     DebugMsg("Untested_178");
                     memoryBarClear();
                     return (0);
                  }
                  if (ad_28 >= ad_20 - ld_52 && ad_28 == ad_4) {
                     memoryBar(ai_0, ad_20 - ld_52, ad_12, ad_20, ad_20, ad_36);
                     DebugPrint("H@O3exit");
                  }
               }
            }
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
      }
      if (ld_60 < ld_52) {
         memoryBar(ai_0, ad_4, ad_12, ad_20, ad_28, ad_36);
         DebugPrint("Unfinished bar... 9");
         return (1);
      }
   } else {
      if (ld_60 > ld_52) {
         ld_100 = NormalizeDouble(MathAbs(ad_4 - ad_12), Digits);
         if (ld_100 > ld_52) {
            if (ad_4 - ad_12 >= ld_52) {
               ld_92 = ad_4 - ld_52;
               updateHistory(ai_0, ad_4, ld_92, ad_4, ld_92, ad_36, ai_48);
               memoryBar(ai_0, ld_92, ad_12, ad_20, ad_28, ad_36);
               processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
               return (1);
            }
            ld_84 = ad_12 + ld_52;
            updateHistory(ai_0, ad_4, ad_12, ld_84, ld_84, ad_36, ai_48);
            memoryBar(ai_0, ld_84, ld_84, ad_20, ld_84, ad_36);
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
         if (ld_100 == ld_52) {
            updateHistory(ai_0, ad_4, ad_12, ad_4, ad_4, ad_36, ai_48);
            memoryBar(ai_0, ad_4, ad_4, ad_20, ad_28, ad_36);
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
         if (ld_100 < ld_52) {
            updateHistory(ai_0, ad_4, ad_12, ad_12 + ld_52, ad_12 + ld_52, ad_36, ai_48);
            if (ad_28 < ad_12 + ld_52 && ad_28 != ad_4) {
               memoryBar(ai_0, ad_12 + ld_52, ad_28, ad_20, ad_28, ad_36);
               DebugPrint("O2L1_exit");
            } else {
               if (ad_28 >= ad_12 + ld_52 && ad_28 != ad_4) {
                  memoryBar(ai_0, ad_12 + ld_52, ad_12 + ld_52, ad_20, ad_28, ad_36);
                  DebugPrint("O2L2_exit");
               } else {
                  if (ad_28 < ad_12 + ld_52 && ad_28 == ad_4) {
                     memoryBar(ai_0, ad_12 + ld_52, ad_12, ad_20, ad_12, ad_36);
                     DebugPrint("O2L3_exit");
                  } else {
                     if (ad_28 >= ad_12 + ld_52 && ad_28 == ad_4) {
                        DebugMsg("Untested275");
                        memoryBarClear();
                        return (0);
                     }
                  }
               }
            }
            processHistoryBar(ai_0, gd_124, gd_132, gd_140, gd_148, 1, 0);
            return (1);
         }
      }
      if (ld_60 < ld_52) {
         DebugPrint("Unfinished bar... 10");
         memoryBar(ai_0, ad_4, ad_12, ad_20, ad_28, ad_36);
         return (1);
      }
   }
   DebugPrint("END...");
   return (0);
}
