#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 clrRed
#property indicator_color2 clrDarkGoldenrod
#property indicator_color3 clrBlueViolet

extern string OpenSourceby = "idealfx";
extern int High_period = 70;
extern int Low_period = 21;
extern int Trigger_Sens = 2;
extern bool ForecastHighTrendLine = TRUE;
extern bool StayLinesAfterDelete = FALSE;
extern string Note0 = "***** Semafor Drawing Adjustment";
extern bool DrawHighPivotSemafor = TRUE;
extern bool DrawLowPivotSemafor = TRUE;
extern bool DrawLowestPivotSemafor = TRUE;
extern string Note1 = "***** High Trend Lines Adjustment";
extern bool HTL_Draw = TRUE;
extern color HTL_ResColor = clrRed;
extern color HTL_SupColor = clrMaroon;
extern int HTL_Style = 1;
extern int HTL_Width = 2;
extern double HTL_Ext = 1.5;
extern int HTL_InMemory = 10;
extern int                HTL_MinPivotDifferentIgnore = 5;
extern string             Note2 = "***** Low Trend Lines Adjustment";
extern bool               LTL_Draw = TRUE;
extern color              LTL_ResColor = clrGold;
extern color              LTL_SupColor = clrGoldenrod;
extern int                LTL_Style = 0;
extern int                LTL_Width = 0;
extern double             LTL_Ext = 1.5;
extern int                LTL_InMemory = 30;
extern int                LTL_MinPivotDifferentIgnore = 4;
extern string             Note3 = "***** High Semafor Adjustment";
extern bool               HighPivotTextAlarm = TRUE;
extern string             HighPivotSoundAlarm = "alert.wav";
extern int                HighPivotSemaforDrawOffset = 28;
extern int                HighSemaforSymbol = 142;
extern string             Note4 = "***** High Semafor Adjustment";
extern bool               LowPivotTextAlarm = FALSE;
extern string             LowPivotSoundAlarm = "";
extern int                LowPivotSemaforDrawOffset = 18;
extern int                LowSemaforSymbol = 141;
extern string             Note5 = "***** Lowest Semafor Adjustment";
extern int                LowestSemaforSymbol = 115;
extern string             Note6 = "***** Forecast Trend Line Adjustment";
extern color              FTL_Color = clrDeepPink;
extern int                FTL_Style = 1;
extern int                FTL_Width = 2;
extern double             FTL_Ext = 1.05;

extern string             button_note1          = "------------------------------";
extern ENUM_BASE_CORNER   btn_corner            = CORNER_LEFT_UPPER; // chart btn_corner for anchoring
extern string             btn_text              = "WALT";                //don't forget to change here
extern string             btn_Font              = "Arial";
extern int                btn_FontSize          = 10;                                 //btn__font size
extern color              btn_text_color        = clrWhite;
extern color              btn_background_color  = clrDimGray;
extern color              btn_border_color      = clrBlack;
extern int                button_x              = 20;                                         //btn__x
extern int                button_y              = 13;                                         //btn__y
extern int                btn_Width             = 60;                                     //btn__width
extern int                btn_Height            = 20;                                    //btn__height
extern string             button_note2          = "------------------------------";

double Semafor02[];
double LowSemafor03[];
double DrawLow01[];
string aLabel01 = "L1";
string level02 = "L2";
int Semafor01;
int buffer02;
int LowSemafor02;
int LowSemafor01;
int aCounter01 = 0;
int overkill = 0;
double BufferArray01[][6];
int Semafor03 = 0;
int Semafor04 = 0;
int Semafor05 = -1;
int Semafor06;
double BufferArray02[][6];
int LowSemafor04 = 0;
int LowSemafor05 = 0;
int LowSemafor06 = -1;
int LowSemafor07;
double BufferArray03[][6];
int DrawLow02 = 0;
int DrawLow03 = 0;
int DrawLow04 = -1;
int DrawLow05;
int tempNumber01 = 0;
int THX1138 = 0;
int ManyWave01 = -1;
string ExtBuffer01[];
string watl01[];
color maincolor01;
color maincolor02;
int mainstyle01;
int minorWidth01;
double WolfWave01;
int WolfWave150 = 0;
string tempString02 = "";
int TempCounter01 = 0;
int TempCounter02 = 0;
string Forecast01 = "ForecastHighTrendLine";
bool tempBool01 = FALSE;
int DateTime101 = 0;
double Price01 = 0.0;
int Micro01 = 0;
int counted_bars;
//+------------------------------------------------------------------+
class VisibilityCotroller
{
   string buttonId;
   string visibilityId;
   bool show_data;
   bool recalc;
public:
   void Init(string id, string indicatorName)
   {
      recalc = false;
      visibilityId = indicatorName + "_visibility";
      double val;
      if (GlobalVariableGet(visibilityId, val))
         show_data = val != 0;
         
      buttonId = id;
      ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, 1);
      createButton(buttonId, btn_text, btn_Width, btn_Height, btn_Font, btn_FontSize, btn_background_color, btn_border_color, btn_text_color);
      ObjectSetInteger(0, buttonId, OBJPROP_YDISTANCE, button_y);
      ObjectSetInteger(0, buttonId, OBJPROP_XDISTANCE, button_x);
   }

   bool HandleButtonClicks()
   {
      if (ObjectGetInteger(0, buttonId, OBJPROP_STATE))
      {
         ObjectSetInteger(0, buttonId, OBJPROP_STATE, false);
         show_data = !show_data;
         GlobalVariableSet(visibilityId, show_data ? 1.0 : 0.0);
         recalc = true;
         return true;
      }
      return false;
   }

   bool IsRecalcNeeded()
   {
      return recalc;
   }

   void ResetRecalc()
   {
      recalc = false;
   }

   bool IsVisible()
   {
      return show_data;
   }
//+------------------------------------------------------------------+
private:
   void createButton(string buttonID,string buttonText,int width,int height,string font,int fontSize,color bgColor,color borderColor,color txtColor)
   {
      ObjectDelete(0,buttonID);
      ObjectCreate(0,buttonID,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,buttonID,OBJPROP_COLOR,txtColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BGCOLOR,bgColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BORDER_COLOR,borderColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BORDER_TYPE,BORDER_RAISED);
      ObjectSetInteger(0,buttonID,OBJPROP_XDISTANCE,9999);
      ObjectSetInteger(0,buttonID,OBJPROP_YDISTANCE,9999);
      ObjectSetInteger(0,buttonID,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,buttonID,OBJPROP_YSIZE,height);
      ObjectSetString(0,buttonID,OBJPROP_FONT,font);
      ObjectSetString(0,buttonID,OBJPROP_TEXT,buttonText);
      ObjectSetInteger(0,buttonID,OBJPROP_FONTSIZE,fontSize);
      ObjectSetInteger(0,buttonID,OBJPROP_SELECTABLE,0);
      ObjectSetInteger(0,buttonID,OBJPROP_CORNER,btn_corner);
      ObjectSetInteger(0,buttonID,OBJPROP_HIDDEN,1);
   }
};
//+------------------------------------------------------------------+
VisibilityCotroller _visibility;

string IndicatorName;
string IndicatorObjPrefix;

string GenerateIndicatorName(const string target)
{
   string name = target;
   int try = 2;
   while (WindowFind(name) != -1)
   {
      name = target + " #" + IntegerToString(try++);
   }
   return name;
}
//+------------------------------------------------------------------+
int start() {
   _visibility.HandleButtonClicks();
   if (!_visibility.IsVisible())
   {
      aCounter01 = 0;
      Clean();
      return 0;
   }
      
   if (overkill == FALSE) {
      if (counted_bars != Bars) {
         deinit();
         Sleep(1000);
         counted_bars = Bars;
         aCounter01 = 0;
         return (0);
      }
   }
   if (overkill == FALSE) {
      overkill = TRUE;
   }
   if (aCounter01 == Time[0]) return (0);
   aCounter01 = Time[0];
   
   int counted_bars02 = IndicatorCounted();
   int Limit01 = Bars - 2;
   if (counted_bars02 > 2 && !_visibility.IsRecalcNeeded()) 
      Limit01 = Bars - counted_bars02 - 1;
   _visibility.ResetRecalc();
   for (int Factory = Limit01; Factory >= 1; Factory--) 
   {
      NewWave_Manager(Factory, buffer02, Semafor01, BufferArray01, Semafor02, Semafor03, Semafor04, Semafor05, Semafor06, DrawHighPivotSemafor, HighPivotSemaforDrawOffset, HighPivotTextAlarm, HighPivotSoundAlarm, 1);
      NewWave_Manager(Factory, LowSemafor01, LowSemafor02, BufferArray02, LowSemafor03, LowSemafor04, LowSemafor05, LowSemafor06, LowSemafor07, DrawLowPivotSemafor, LowPivotSemaforDrawOffset, LowPivotTextAlarm, LowPivotSoundAlarm, 0);
      NewWave_Manager(Factory, 2, 5, BufferArray03, DrawLow01, DrawLow02, DrawLow03, DrawLow04, DrawLow05, DrawLowestPivotSemafor, 3, 0, "", 0);
      if (Semafor06 && HTL_Draw) 
      {
         TLMng_Init(HTL_ResColor, HTL_SupColor, HTL_Style, HTL_Width, HTL_Ext, HTL_InMemory, "HTL", HTL_MinPivotDifferentIgnore);
         TLMng_Main(BufferArray01, ExtBuffer01, Semafor06);
      }
      if (LowSemafor07 && LTL_Draw) 
      {
         TLMng_Init(LTL_ResColor, LTL_SupColor, LTL_Style, LTL_Width, LTL_Ext, LTL_InMemory, "LTL", LTL_MinPivotDifferentIgnore);
         TLMng_Main(BufferArray02, watl01, LowSemafor07);
      }
   }
   return (0);
}
//+------------------------------------------------------------------+
void FTLMng_Main(int aColor01, int aColor02, double tempNumber1000, int Where01) {
   datetime DateTime100;
   if (ObjectFind(Forecast01) > -1) {
      ObjectDelete(Forecast01);
      tempBool01 = FALSE;
      DateTime101 = FALSE;
      Price01 = 0;
   }
   double SecondPt01 = FTLMng_FindSecondpoint(aColor01, aColor02, Where01);
   if (SecondPt01 != 0.0) {
      DateTime100 = Time[aColor01];
      if (FTLMng_DrawFirst(aColor02, tempNumber1000, DateTime100, SecondPt01) != 0) {
         Micro01 = Where01;
         FTLMng_ReDraw(aColor01);
         tempBool01 = TRUE;
         return;
      }
   }
}
//+------------------------------------------------------------------+
int FTLMng_DrawFirst(int tempDateTime99, double tempPrice04, int tempDateTime98, double tempPrice16) {
   if (ObjectCreate(Forecast01, OBJ_TREND, 0, tempDateTime99, tempPrice04, tempDateTime98, tempPrice16)) {
      ObjectSet(Forecast01, OBJPROP_RAY, FALSE);
      ObjectSet(Forecast01, OBJPROP_COLOR, FTL_Color);
      ObjectSet(Forecast01, OBJPROP_STYLE, FTL_Style);
      ObjectSet(Forecast01, OBJPROP_WIDTH, FTL_Width);
      DateTime101 = tempDateTime99;
      Price01 = tempPrice04;
      ObjectsRedraw();
      return (1);
   }
   GetLastError();
   return (0);
}
//+------------------------------------------------------------------+
int FTLMng_ReDraw(int aColor01) {
   if (ObjectFind(Forecast01) == -1) return (0);
   double aDoubleNumb02 = FTLMng_FindSecondpoint(aColor01, DateTime101, Micro01);
   if (aDoubleNumb02 == 0.0) return (0);
   int anInteger05 = Time[aColor01];
   int tempDateTime5000 = 0;
   double SecondPt01 = 0;
   ObjectMove(Forecast01, 1, anInteger05, aDoubleNumb02);
   if (FTL_Ext > 0.0) {
      TLMng_CountExt(FTL_Ext, DateTime101, Price01, anInteger05, aDoubleNumb02, tempDateTime5000, SecondPt01);
      if (tempDateTime5000 == 0 || SecondPt01 == 0.0) return (0);
      ObjectMove(Forecast01, 1, tempDateTime5000, SecondPt01);
   }
   ObjectsRedraw();
   return (0);
}
//+------------------------------------------------------------------+
double FTLMng_FindSecondpoint(int aColor01, int aColor02, int tempNumb200) {
   if (aColor01 == 0 || aColor02 == 0) return (0);
   int shift01 = iBarShift(NULL, 0, aColor02, FALSE);
   double SecondPt01 = 0;
   if (tempNumb200 == 1) SecondPt01 = iMA(NULL, 0, 1.1 * shift01, 0, MODE_LWMA, PRICE_HIGH, aColor01);
   if (tempNumb200 == 2) SecondPt01 = iMA(NULL, 0, 1.1 * shift01, 0, MODE_LWMA, PRICE_LOW, aColor01);
   return (SecondPt01);
}
//+------------------------------------------------------------------+
int TLMng_Main(double &Array100[][6], string &Array101[], int &tempNumb200) {
   int mario;
   int tempNumber55;
   double tempNumber100;
   double tempNumber101;
   int Limit010;
   int Limit014;
   int tempNumber102;
   int tempNumber103;
   int WaveCount01 = WAMng_WaveCount(Array100);
   if (WaveCount01 > 0) mario = WAMng_WaveType(Array100, WaveCount01);
   if (mario > 0) {
      tempNumber55 = WAMng_LookPrivWaveSameType(Array100, mario, WaveCount01);
      if (tempNumber55 > 0) {
         tempNumber100 = WAMng_GetWavePiv(Array100, WaveCount01);
         tempNumber101 = WAMng_GetWavePiv(Array100, tempNumber55);
         if (tempNumber100 == 0.0 || tempNumber101 == 0.0) return (0);
         Limit010 = WAMng_GetWavePivBar(Array100, WaveCount01);
         Limit014 = WAMng_GetWavePivBar(Array100, tempNumber55);
         if (Limit010 == 0 || Limit014 == 0) return (0);
         if (TempCounter02 > 0) {
            tempNumber102 = iBarShift(NULL, 0, Limit010, FALSE);
            tempNumber103 = iBarShift(NULL, 0, Limit014, FALSE);
            if (tempNumber103 - tempNumber102 <= TempCounter02) return (0);
         }
         if (mario == 1) {
            if (tempNumber100 < tempNumber101) TLMng_BuidLine(Array101, mario, tempNumber101, Limit014, tempNumber100, Limit010);
            else tempNumb200 = 0;
         } else {
            if (mario == 2) {
               if (tempNumber100 > tempNumber101) TLMng_BuidLine(Array101, mario, tempNumber101, Limit014, tempNumber100, Limit010);
               else tempNumb200 = 0;
            }
         }
      }
   }
   return (0);
}
//+------------------------------------------------------------------+
void TLMng_Init(int aColor01, int aColor02, int tempNumb200, int WolfWave02, double Elliott01, int Elliott02, string Elliott03, int Elliott04) {
   maincolor01 = aColor01;
   maincolor02 = aColor02;
   if (minorWidth01 <= 1) {
      mainstyle01 = tempNumb200;
      minorWidth01 = 1;
   } else {
      mainstyle01 = 0;
      minorWidth01 = WolfWave02;
   }
   if (Elliott01 < 1.0) WolfWave01 = 1;
   else WolfWave01 = Elliott01;
   WolfWave150 = Elliott02;
   tempString02 = Elliott03;
   TempCounter02 = Elliott04;
}
//+------------------------------------------------------------------+
void TLMng_BuidLine(string &CheckNumb01[], int aColor02, double tempNumber1000, int aDateTime16, double tempNumberr01, int aDateTime001) {
   string SupRes01;
   int datetime01;
   double main01;
   int counter100;
   double Mando01;
   string tempString01 = "";
   if (tempString02 == "") tempString01 = "Def";
   else tempString01 = tempString02;
   string buildLine01 = tempString01 + "_Asys_AutoTL_" + Period() + "_";
   TempCounter01++;
   if (aColor02 == 2) SupRes01 = "Sup";
   else SupRes01 = "Res";
   buildLine01 = buildLine01 + SupRes01 + " - " + TempCounter01;
   if (ObjectCreate(buildLine01, OBJ_TREND, 0, aDateTime16, NormalizeDouble(tempNumber1000, Digits), aDateTime001, NormalizeDouble(tempNumberr01, Digits))) {
      ObjectSet(buildLine01, OBJPROP_RAY, FALSE);
      if (SupRes01 == "Sup") ObjectSet(buildLine01, OBJPROP_COLOR, maincolor02);
      else {
         if (SupRes01 == "Res") ObjectSet(buildLine01, OBJPROP_COLOR, maincolor01);
         else ObjectSet(buildLine01, OBJPROP_COLOR, Red);
      }
      ObjectSet(buildLine01, OBJPROP_STYLE, mainstyle01);
      ObjectSet(buildLine01, OBJPROP_WIDTH, minorWidth01);
      if (WolfWave01 > 1.0) {
         datetime01 = 0;
         main01 = 0;
         TLMng_CountExt(WolfWave01, aDateTime16, NormalizeDouble(tempNumber1000, Digits), aDateTime001, NormalizeDouble(tempNumberr01, Digits), datetime01, main01);
         ObjectMove(buildLine01, 1, datetime01, main01);
         counter100 = 0;
         Mando01 = TLMng_CorrectLine(buildLine01, aDateTime001, NormalizeDouble(tempNumberr01, Digits));
         while (Mando01 != 0.0) {
            main01 += Mando01;
            ObjectMove(buildLine01, 1, datetime01, main01);
            Mando01 = TLMng_CorrectLine(buildLine01, aDateTime001, NormalizeDouble(tempNumberr01, Digits));
            counter100++;
            if (counter100 > 20) break;
         }
      }
      TLMng_CheckNumTL(CheckNumb01, buildLine01, WolfWave150);
      ObjectsRedraw();
   }
}
//+------------------------------------------------------------------+
double TLMng_CorrectLine(string aStringName01, int tempNumb200, double station02) {
   if (aStringName01 == "" || tempNumb200 == 0) return (0);
   GetLastError();
   double SecondPt01 = ObjectGetValueByShift(aStringName01, iBarShift(NULL, 0, tempNumb200, TRUE));
   if (GetLastError() > 0/* NO_ERROR */) return (0);
   double USA01 = SecondPt01 - station02;
   if (IsInChanel(USA01, 0, 2.0 * Point) == 1) return (0);
   return (-1.0 * USA01);
}
//+------------------------------------------------------------------+
void TLMng_CheckNumTL(string &CheckNumb01[], string kudo01, int WolfWave02) {
   if (kudo01 == "" || WolfWave02 < 0) return;
   if (ArraySize(CheckNumb01) + 1 > WolfWave02) {
      if (!ObjectDelete(CheckNumb01[0])) Print("������ �������� ����� - ", CheckNumb01[0], " ��� ������ - ", GetLastError());
      ArrayCopy(CheckNumb01, CheckNumb01, 0, 1);
      CheckNumb01[ArraySize(CheckNumb01) - 1] = kudo01;
      return;
   }
   ArrayResize(CheckNumb01, ArraySize(CheckNumb01) + 1);
   CheckNumb01[ArraySize(CheckNumb01) - 1] = kudo01;
}
//+------------------------------------------------------------------+
void TLMng_DeleteAllLines() {
   int TrendLine05 = ArrayRange(ExtBuffer01, 0);
   if (TrendLine05 > 0) {
      for (int counter101 = 0; counter101 <= TrendLine05 - 1; counter101++)
         if (ObjectFind(ExtBuffer01[counter101]) > -1) ObjectDelete(ExtBuffer01[counter101]);
   }
   ArrayResize(ExtBuffer01, 0);
   TrendLine05 = 0;
   TrendLine05 = ArrayRange(watl01, 0);
   if (TrendLine05 > 0) 
   {
      for (int counter101 = 0; counter101 <= TrendLine05 - 1; counter101++)
         if (ObjectFind(watl01[counter101]) > -1) 
            ObjectDelete(watl01[counter101]);
   }
   ArrayResize(watl01, 0);
}
//+------------------------------------------------------------------+
void TLMng_DeleteLinesCurrentTF() {
   string aString333;
   string anArray101[];
   int TotalObjects01 = ObjectsTotal();
   if (TotalObjects01 != 0) {
      for (int mario = 0; mario <= TotalObjects01 - 1; mario++) {
         aString333 = ObjectName(mario);
         if (StringFind(aString333, StringConcatenate("Asys_AutoTL_", Period())) > -1) {
            ArrayResize(anArray101, ArraySize(anArray101) + 1);
            anArray101[ArraySize(anArray101) - 1] = aString333;
         }
      }
      if (ArraySize(anArray101) > 0) {
         for (int mario = 0; mario <= ArraySize(anArray101) - 1; mario++)
            if (ObjectFind(anArray101[mario]) > -1) 
               ObjectDelete(anArray101[mario]);
      }
   }
}
//+------------------------------------------------------------------+
void TLMng_DeleteLinesCurrentInd() {
   string aString333;
   string anArray101[];
   int TotalObjects01 = ObjectsTotal();
   if (TotalObjects01 != 0) {
      for (int mario = 0; mario <= TotalObjects01 - 1; mario++) {
         aString333 = ObjectName(mario);
         if (StringFind(aString333, "Asys_AutoTL") > -1) {
            ArrayResize(anArray101, ArraySize(anArray101) + 1);
            anArray101[ArraySize(anArray101) - 1] = aString333;
         }
      }
      if (ArraySize(anArray101) > 0) {
         for (int mario = 0; mario <= ArraySize(anArray101) - 1; mario++)
            if (ObjectFind(anArray101[mario]) > -1) ObjectDelete(anArray101[mario]);
      }
   }
}
//+------------------------------------------------------------------+
void TLMng_CountExt(double aDoubleNumber01, int tempNumb200, double station02, int tempNumber2000, double forex01, int &Time32, double &countext01) {
   int Shift100 = iBarShift(NULL, 0, tempNumb200, FALSE);
   int tempNumber102 = iBarShift(NULL, 0, tempNumber2000, FALSE);
   int minor01 = Shift100 - tempNumber102;
   int counter01 = Double2Int(MathRound(minor01 * aDoubleNumber01));
   double main01 = MathAbs(forex01 - station02);
   if (counter01 == 0) countext01 = forex01;
   else {
      if (forex01 > station02) countext01 = NormalizeDouble(forex01 + counter01 * main01 / minor01, Digits);
      if (forex01 < station02) countext01 = NormalizeDouble(forex01 - counter01 * main01 / minor01, Digits);
   }
   Time32 = Time[tempNumber102] + 60 * Period() * counter01;
}
//+------------------------------------------------------------------+
int WAMng_LookPrivWaveSameType(double &Array100[][6], int aColor02, int tempNumb200) {
   int tempNumber55;
   if (aColor02 <= 0 || tempNumb200 == 0) return (0);
   int AnotherCounter01 = tempNumb200 - 1;
   bool mario = FALSE;
   while (mario == FALSE) {
      tempNumber55 = WAMng_WaveType(Array100, AnotherCounter01);
      if (tempNumber55 > 0) {
         if (tempNumber55 == aColor02) {
            mario = TRUE;
            break;
         }
      }
      AnotherCounter01--;
      if (AnotherCounter01 < 0) mario = TRUE;
   }
   if (AnotherCounter01 > 0) return (AnotherCounter01);
   else return (0);
}
//+------------------------------------------------------------------+
int WAMng_WaveType(double &Array100[][6], int aColor02) {
   int Factory = WAMng_WaveCount(Array100);
   if (aColor02 < 1 || aColor02 > Factory) return (-1);
   return (Array100[aColor02 - 1][0]);
}
//+------------------------------------------------------------------+
int WAMng_WaveCount(double &Array100[][6]) {
   return (ArrayRange(Array100, 0));
}
//+------------------------------------------------------------------+
double WAMng_GetWavePiv(double &Array100[][6], int aColor02) {
   int Factory = WAMng_WaveCount(Array100);
   if (aColor02 < 1 || aColor02 > Factory) return (0);
   return (Array100[aColor02 - 1][3]);
}
//+------------------------------------------------------------------+
int WAMng_GetWavePivBar(double &Array100[][6], int aColor02) {
   int Factory = WAMng_WaveCount(Array100);
   if (aColor02 < 1 || aColor02 > Factory) return (0);
   return (Array100[aColor02 - 1][5]);
}
//+------------------------------------------------------------------+
int NewWave_Manager(int aColor01, int aColor02, int tempNumb200, double &tempArray1000[][6], double &ada_16[], int &tempNumber2000, int &Elliott02, int &Cartel28, int &Time32, bool Elliott04, int aColor020, int aColor024, string kudo018, int ai_56) {
   int tempInteger92;
   int Shift50;
   int tempshift100;
   Init_Wave_Manager(tempNumber2000, Elliott02, Cartel28);
   if (tempNumber01 == 0) {
      F_F_Zero(aColor02, tempNumb200, aColor01);
      Time32 = 0;
      DeInit_Wave_Manager(tempNumber2000, Elliott02, Cartel28);
      return (0);
   }
   if (ai_56 == 1 && ForecastHighTrendLine == TRUE && tempBool01 == TRUE) FTLMng_ReDraw(aColor01);
   if (THX1138 == 0) {
      F_S_Zero(aColor02, tempNumb200, ManyWave01, aColor01);
      if (THX1138 == 0) {
         Time32 = 0;
         DeInit_Wave_Manager(tempNumber2000, Elliott02, Cartel28);
         return (0);
      }
   }
   Add_Wave(tempNumber01, THX1138, ManyWave01, tempArray1000);
   Time32 = 1;
   int l_str2int_60 = StrToInteger(DoubleToStr(tempArray1000[ArrayRange(tempArray1000, 0) - 1][4], 0));
   datetime l_time_88 = Time[l_str2int_60];
   if (Elliott04) {
      tempInteger92 = l_str2int_60;
      Shift50 = iBarShift(NULL, 0, THX1138, FALSE);
      tempshift100 = iBarShift(NULL, 0, tempNumber01, FALSE);
      for (int li_104 = Shift50 - 1; li_104 > tempInteger92; li_104++) ada_16[li_104] = 0;
      ada_16[l_str2int_60] = tempArray1000[ArrayRange(tempArray1000, 0) - 1][3];
      if (ManyWave01 == 1) ada_16[l_str2int_60] += aColor020 * Point;
      else
         if (ManyWave01 == 2) ada_16[l_str2int_60] = ada_16[l_str2int_60] - aColor020 * Point;
      if (aColor01 < 50) {
         if (kudo018 != "") PlaySound(kudo018);
         if (aColor024 == 1) Alert(PrepareTextAlarm(Time[0], ManyWave01, tempArray1000[ArrayRange(tempArray1000, 0) - 1][3], l_time_88));
      }
   }
   if (ai_56 == 1 && ForecastHighTrendLine == TRUE) FTLMng_Main(aColor01, l_time_88, tempArray1000[ArrayRange(tempArray1000, 0) - 1][3], ManyWave01);
   tempNumber01 = THX1138;
   if (ManyWave01 == 1) ManyWave01 = 2;
   else {
      if (ManyWave01 == 2) ManyWave01 = 1;
      else ManyWave01 = -1;
   }
   THX1138 = 0;
   DeInit_Wave_Manager(tempNumber2000, Elliott02, Cartel28);
   return (0);
}
//+------------------------------------------------------------------+
void Init_Wave_Manager(int aColor01, int aColor02, int tempNumb200) {
   tempNumber01 = aColor01;
   THX1138 = aColor02;
   ManyWave01 = tempNumb200;
}
//+------------------------------------------------------------------+
void DeInit_Wave_Manager(int &aColor01, int &aColor02, int &tempNumb200) {
   aColor01 = tempNumber01;
   aColor02 = THX1138;
   tempNumb200 = ManyWave01;
}
//+------------------------------------------------------------------+
void F_F_Zero(int aColor01, int aColor02, int tempNumb200) {
   int WaveCount01;
   double WaveCount02;
   int ZeroYet01;
   if (Bars - tempNumb200 >= aColor02 << 1) {
      WaveCount01 = ChMnr_CurrentWaveType(aColor01, aColor02, tempNumb200);
      WaveCount02 = 0;
      ZeroYet01 = tempNumb200;
      tempNumber01 = 0;
      ManyWave01 = 0;
      if (WaveCount01 > 0) {
         WaveCount02 = ChMnr_FindZeroFromShift(aColor01, aColor02, ZeroYet01);
         if (WaveCount02 <= 0.0) return;
      } else {
         WaveCount01 = ChMnr_FirstWaveFromShift(aColor01, aColor02, ZeroYet01);
         if (WaveCount01 <= 0) return;
         WaveCount02 = ChMnr_FindZeroFromShift(aColor01, aColor02, ZeroYet01);
         if (WaveCount02 <= 0.0) return;
      }
      tempNumber01 = Time[ZeroYet01];
      ManyWave01 = WaveCount01;
   }
}
//+------------------------------------------------------------------+
void F_S_Zero(int aColor01, int aColor02, int tempNumb200, int WolfWave02) {
   int mario = ChMnr_CurrentWaveType(aColor01, aColor02, WolfWave02);
   if (tempNumber01 == 0 || ManyWave01 <= 0 || tempNumb200 <= 0) return;
   if (mario == 0) {
      THX1138 = 0;
      return;
   }
   if (mario == tempNumb200) {
      THX1138 = 0;
      return;
   }
   if (mario != tempNumb200) THX1138 = Time[WolfWave02];
}
//+------------------------------------------------------------------+
double ChMnr_FindZeroFromShift(int aColor01, int aColor02, int &tempNumb200) {
   int LowCounter01 = 0;
   double LowCounter02 = -99999;
   bool ZeroYet01 = FALSE;
   while (ZeroYet01 == FALSE) {
      if (ChMnr_IfZero(aColor01, aColor02, tempNumb200 + LowCounter01) == 1) {
         ZeroYet01 = TRUE;
         LowCounter02 = Time[tempNumb200 + LowCounter01];
         tempNumb200 += LowCounter01;
      }
      LowCounter01++;
      if (tempNumb200 + LowCounter01 >= Bars) {
         ZeroYet01 = TRUE;
         LowCounter02 = -55555;
      }
   }
   return (LowCounter02);
}
//+------------------------------------------------------------------+
int ChMnr_FirstWaveFromShift(int aColor01, int aColor02, int &tempNumb200) {
   int LowCounter01 = 0;
   int NegativeCounter01 = -99999;
   int tempNumber55 = 0;
   bool ZeroYet01 = FALSE;
   while (ZeroYet01 == FALSE) {
      tempNumber55 = ChMnr_CurrentWaveType(aColor01, aColor02, tempNumb200 + LowCounter01);
      if (tempNumber55 > 0) {
         NegativeCounter01 = tempNumber55;
         ZeroYet01 = TRUE;
         tempNumb200 += LowCounter01;
      }
      LowCounter01++;
      if (tempNumb200 + LowCounter01 >= Bars) {
         ZeroYet01 = TRUE;
         NegativeCounter01 = -55555;
      }
   }
   return (NegativeCounter01);
}
//+------------------------------------------------------------------+
int ChMnr_IfZero(int MAperiod01, int MAperiod02, int tempNumb200) {
   double Croatia01 = NormalizeToDigit(iMA(NULL, 0, MAperiod01, 0, MODE_SMA, PRICE_CLOSE, tempNumb200));
   double SecondPt01 = NormalizeToDigit(iMA(NULL, 0, MAperiod02, 0, MODE_LWMA, PRICE_WEIGHTED, tempNumb200));
   double USA01 = Croatia01 - SecondPt01;
   return (IsInChanel(USA01, 0, Trigger_Sens));
}
//+------------------------------------------------------------------+
int ChMnr_CurrentWaveType(int MAperiod01, int MAperiod02, int tempNumb200) {
   double l_ima_12 = iMA(NULL, 0, MAperiod01, 0, MODE_SMA, PRICE_CLOSE, tempNumb200);
   double l_ima_20 = iMA(NULL, 0, MAperiod02, 0, MODE_LWMA, PRICE_WEIGHTED, tempNumb200);
   double USA01 = l_ima_12 - l_ima_20;
   if (ChMnr_IfZero(MAperiod01, MAperiod02, tempNumb200) == 1) return (0);
   if (USA01 > 0.0) return (1);
   if (USA01 < 0.0) return (2);
   return (-1);
}
//+------------------------------------------------------------------+
int Add_Wave(int aColor01, int aColor02, int tempNumb200, double &tempArray1000[][6]) 
{
   int mario = ArrayRange(tempArray1000, 0);
   mario++;
   ArrayResize(tempArray1000, mario);
   tempArray1000[mario - 1][0] = tempNumb200;
   tempArray1000[mario - 1][1] = aColor01;
   tempArray1000[mario - 1][2] = aColor02;
   bool tempNumber55 = FALSE;
   if (mario - 2 >= 0) tempNumber55 = tempArray1000[mario - 2][5];
   int ZeroYet01 = FindPivot(aColor01, aColor02, tempNumb200, tempNumber55);
   if (ZeroYet01 != 0) 
   {
      tempArray1000[mario - 1][4] = iBarShift(NULL, 0, ZeroYet01, FALSE);
      tempArray1000[mario - 1][5] = ZeroYet01;
      if (tempNumb200 == 1) 
         tempArray1000[mario - 1][3] = High[iBarShift(NULL, 0, ZeroYet01, FALSE)];
      else if (tempNumb200 == 2) 
         tempArray1000[mario - 1][3] = Low[iBarShift(NULL, 0, ZeroYet01, FALSE)];
   }
   return (0);
}
//+------------------------------------------------------------------+
int FindPivot(int aColor01, int aColor02, int tempNumb200, int WolfWave02) {
   int Highest100;
   int Lowest100;
   if (tempNumb200 < 1 || aColor01 == 0 || aColor02 == 0) return (0);
   int tempShift100 = iBarShift(NULL, 0, aColor01, TRUE);
   int tempShift101 = iBarShift(NULL, 0, aColor02, TRUE);
   int tempShift102 = 0;
   if (WolfWave02 > 0) tempShift102 = iBarShift(NULL, 0, WolfWave02, TRUE);
   if (tempShift100 == -1 || tempShift101 == -1) return (0);
   int anInteger01 = 0;
   if (tempShift102 > 0) anInteger01 = tempShift102 - tempShift101 + 1;
   else anInteger01 = tempShift100 - tempShift101 + 1;
   if (tempNumb200 == 1) {
      Highest100 = iHighest(NULL, 0, MODE_HIGH, anInteger01, tempShift101);
      return (Time[Highest100]);
   }
   if (tempNumb200 == 2) {
      Lowest100 = iLowest(NULL, 0, MODE_LOW, anInteger01, tempShift101);
      return (Time[Lowest100]);
   }
   return (0);
}
//+------------------------------------------------------------------+
int init() {
   IndicatorName = GenerateIndicatorName("WALT");
   IndicatorObjPrefix = "__" + IndicatorName + "__";
   IndicatorShortName(IndicatorName);

   counted_bars = Bars;
   overkill = FALSE;
   TLMng_DeleteLinesCurrentTF();
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, HighSemaforSymbol);
   SetIndexBuffer(0, Semafor02);
   SetIndexEmptyValue(0, 0.0);
   SetIndexStyle(1, DRAW_ARROW);
   SetIndexArrow(1, LowSemaforSymbol);
   SetIndexBuffer(1, LowSemafor03);
   SetIndexEmptyValue(1, 0.0);
   SetIndexStyle(2, DRAW_ARROW);
   SetIndexArrow(2, LowestSemaforSymbol);
   SetIndexBuffer(2, DrawLow01);
   SetIndexEmptyValue(2, 0.0);
   if (High_period == 0 && Low_period == 0) {
      Alert("High_period � Low_period ����� 0. �����-�� ��� ��� ������ ���� ������ 0");
      deinit();
      return (0);
   }
   Semafor01 = High_period;
   buffer02 = Double2Int(MathRound(High_period / 7));
   LowSemafor02 = Low_period;
   LowSemafor01 = Double2Int(MathRound(Low_period / 5));
   if (Trigger_Sens <= 0) {
      Trigger_Sens = 2;
      Alert("<Trigger_Sens> cannot have zero or less value. Now it is adjusted by default");
   }
   _visibility.Init(IndicatorObjPrefix + "CloseButton", IndicatorName);
   return (0);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if (_visibility.HandleButtonClicks())
      start();
}
//+------------------------------------------------------------------+
void Clean()
{
   if (StayLinesAfterDelete == FALSE) 
      TLMng_DeleteAllLines();
   ObjectDelete(Forecast01);
   ArrayResize(ExtBuffer01, 0);
   ArrayResize(watl01, 0);
   ArrayResize(BufferArray01, 0);
   ArrayResize(BufferArray02, 0);
   ArrayResize(BufferArray03, 0);
   ArrayInitialize(Semafor02, 0.0);
   ArrayInitialize(LowSemafor03, 0.0);
   ArrayInitialize(DrawLow01, 0.0);
   ObjectDelete(aLabel01);
   ObjectDelete(level02);
   if (StayLinesAfterDelete == FALSE) 
      TLMng_DeleteLinesCurrentInd();
}
//+------------------------------------------------------------------+
int deinit() 
{
   Clean();
   ObjectsDeleteAll(ChartID(), IndicatorObjPrefix);
   return (0);
}
//+------------------------------------------------------------------+
int Double2Int(double aDoubleNumber01) {
   return (StrToInteger(DoubleToStr(aDoubleNumber01, 0)));
}
//+------------------------------------------------------------------+
int IsInChanel(double aDoubleNumber01, double tempNumber1000, double Elliott01) {
   double tempNumber100 = tempNumber1000 + Elliott01;
   double tempNumber101 = tempNumber1000 - Elliott01;
   if (aDoubleNumber01 <= tempNumber100 && aDoubleNumber01 >= tempNumber101) return (1);
   else return (0);
}
//+------------------------------------------------------------------+
double NormalizeToDigit(double aDoubleNumber01) {
   double tempNumber2000 = aDoubleNumber01;
   for (int mario = 1; mario <= Digits; mario++) tempNumber2000 = 10.0 * tempNumber2000;
   return (tempNumber2000);
}
//+------------------------------------------------------------------+
string PrepareTextAlarm(int aColor01, int aColor02, double tempNumber1000, int Where01) {
   string aString20 = "";
   aString20 = aString20 + TimeToStr(aColor01, TIME_DATE) + " " + TimeToStr(aColor01, TIME_MINUTES) + " : ";
   if (aColor02 == 1) aString20 = aString20 + "The top maximum is generated : ";
   if (aColor02 == 2) aString20 = aString20 + "The bottom minimum is generated : ";
   aString20 = aString20 + TimeToStr(Where01, TIME_DATE) + " " + TimeToStr(Where01, TIME_MINUTES) + " Price Value: ";
   aString20 = aString20 + DoubleToStr(tempNumber1000, Digits);
   return (aString20);
}
//+------------------------------------------------------------------+
void CreateLab(string tempLabel01) 
{
   if (tempLabel01 == aLabel01) {
      ObjectCreate(aLabel01, OBJ_LABEL, 0, Time[1], High[1]);
      ObjectSet(aLabel01, OBJPROP_CORNER, 0);
      ObjectSet(aLabel01, OBJPROP_XDISTANCE, 225);
      ObjectSet(aLabel01, OBJPROP_YDISTANCE, 8);
      ObjectSetText(aLabel01, "Waves Auto Trend Indicator", 10, "Arial", SaddleBrown);
   }
}
//+------------------------------------------------------------------+
