#property copyright "KK"
#property strict

#property description "CCI arrows based on the cross of the zero line from below or from above."
#property description "Displays red and blue arrows for Short and Long signals."
#property description "Includes dual EMAs (50 blue, 100 red) with dashed lines."
#property description "5 CCI period options with on-chart buttons: 28, 140, 280, 560, 700"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

// EMA buffers (drawn first)
#property indicator_color1  clrBlue
#property indicator_type1   DRAW_LINE
#property indicator_style1  STYLE_DASHDOT
#property indicator_width1  1
#property indicator_label1  "EMA 50"

#property indicator_color2  clrRed
#property indicator_type2   DRAW_LINE
#property indicator_style2  STYLE_DASHDOT
#property indicator_width2  1
#property indicator_label2  "EMA 100"

// Arrow buffers (drawn on top)
#property indicator_color3  clrAqua
#property indicator_type3   DRAW_ARROW
#property indicator_width3  1
#property indicator_label3  "CCI Buy"

#property indicator_color4  clrYellow
#property indicator_type4   DRAW_ARROW
#property indicator_width4  1
#property indicator_label4  "CCI Sell"

enum enum_candle_to_check
{
    Current,
    Previous
};

input int CCI_Period_1 = 140;    // CCI Period 1
input int CCI_Period_2 = 280;   // CCI Period 2
input int CCI_Period_3 = 560;   // CCI Period 3
input int CCI_Period_4 = 700;   // CCI Period 4
input int CCI_Period_5 = 1400;   // CCI Period 5
input int EMA_Fast = 50;        // Fast EMA Period
input int EMA_Slow = 100;       // Slow EMA Period
input bool EnableNativeAlerts = false;
input bool EnableEmailAlerts = false;
input bool EnablePushAlerts = false;
input enum_candle_to_check TriggerCandle = Previous;
input int ButtonX = 1450;         // Button X Position
input int ButtonY = 200;         // Button Y Position

double dEMA_Fast[];
double dEMA_Slow[];
double dUpCCIBuffer[];
double dDownCCIBuffer[];

int myEMA_Fast;
int myEMA_Slow;

int LastAlertDirection;
datetime LastAlertTime;
bool FirstRun;

// CCI Period options
int CCI_Periods[5];
int CurrentPeriodIndex = 0;
int CurrentCCI_Period;

// Button names
string ButtonNames[5];

// Multiple CCI handles - one for each period
int CCI_Handles[5];

void OnInit()
{
    FirstRun = true;
    LastAlertDirection = 0;
    LastAlertTime = D'01.01.1970';
    
    // Initialize CCI periods from inputs
    CCI_Periods[0] = CCI_Period_1;
    CCI_Periods[1] = CCI_Period_2;
    CCI_Periods[2] = CCI_Period_3;
    CCI_Periods[3] = CCI_Period_4;
    CCI_Periods[4] = CCI_Period_5;
    
    // Read saved period index from global variable
    string gvName = "CCI_Period_Index_" + _Symbol + "_" + IntegerToString(_Period);
    if(GlobalVariableCheck(gvName))
    {
        CurrentPeriodIndex = (int)GlobalVariableGet(gvName);
        if(CurrentPeriodIndex < 0 || CurrentPeriodIndex > 4)
            CurrentPeriodIndex = 0;
    }
    
    CurrentCCI_Period = CCI_Periods[CurrentPeriodIndex];

    IndicatorSetString(INDICATOR_SHORTNAME, "CCI Arrows (" + IntegerToString(CurrentCCI_Period) + ") + EMA(" + IntegerToString(EMA_Fast) + "," + IntegerToString(EMA_Slow) + ")");

    // EMA buffers (index 0 and 1 - drawn first/behind)
    SetIndexBuffer(0, dEMA_Fast, INDICATOR_DATA);
    SetIndexBuffer(1, dEMA_Slow, INDICATOR_DATA);
    
    // Arrow buffers (index 2 and 3 - drawn on top)
    SetIndexBuffer(2, dUpCCIBuffer, INDICATOR_DATA);
    SetIndexBuffer(3, dDownCCIBuffer, INDICATOR_DATA);
    
    ArraySetAsSeries(dEMA_Fast, true);
    ArraySetAsSeries(dEMA_Slow, true);
    ArraySetAsSeries(dUpCCIBuffer, true);
    ArraySetAsSeries(dDownCCIBuffer, true);

    PlotIndexSetInteger(2, PLOT_ARROW, 233);
    PlotIndexSetInteger(3, PLOT_ARROW, 234);

    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0);
    
    // Create ALL CCI handles at once - one for each period
    for(int i = 0; i < 5; i++)
    {
        CCI_Handles[i] = iCCI(NULL, 0, CCI_Periods[i], PRICE_CLOSE);
    }
    
    // Create EMA handles
    myEMA_Fast = iMA(NULL, 0, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
    myEMA_Slow = iMA(NULL, 0, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
    
    CreateButtons();
}

void OnDeinit(const int reason)
{
    DeleteButtons();
    
    // Release ALL CCI handles
    for(int i = 0; i < 5; i++)
    {
        if(CCI_Handles[i] != INVALID_HANDLE) IndicatorRelease(CCI_Handles[i]);
    }
    
    if(myEMA_Fast != INVALID_HANDLE) IndicatorRelease(myEMA_Fast);
    if(myEMA_Slow != INVALID_HANDLE) IndicatorRelease(myEMA_Slow);
}

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    if(id == CHARTEVENT_OBJECT_CLICK)
    {
        // Check which button was clicked
        for(int i = 0; i < 5; i++)
        {
            if(sparam == ButtonNames[i])
            {
                ObjectSetInteger(0, ButtonNames[i], OBJPROP_STATE, false);
                
                if(CurrentPeriodIndex == i) return; // Already on this period
                
                CurrentPeriodIndex = i;
                CurrentCCI_Period = CCI_Periods[i];
                
                Print("=== SWITCHING TO CCI PERIOD: ", CurrentCCI_Period, " ===");
                
                // Save to global variable
                string gvName = "CCI_Period_Index_" + _Symbol + "_" + IntegerToString(_Period);
                GlobalVariableSet(gvName, CurrentPeriodIndex);
                
                UpdateButtons();
                UpdateIndicatorName();
                
                // NUCLEAR OPTION: Reload the entire chart
                long chartID = ChartID();
                string symbol = ChartSymbol(chartID);
                ENUM_TIMEFRAMES period = ChartPeriod(chartID);
                
                ChartSetSymbolPeriod(chartID, symbol, period);
                
                Print("=== CHART RELOADED ===");
                
                return;
            }
        }
    }
}

void CreateButtons()
{
    int buttonWidth = 70;
    int buttonHeight = 25;
    int buttonSpacing = 5;
    
    for(int i = 0; i < 5; i++)
    {
        ButtonNames[i] = "CCI_Button_" + IntegerToString(CCI_Periods[i]);
        
        if(ObjectCreate(0, ButtonNames[i], OBJ_BUTTON, 0, 0, 0))
        {
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_XDISTANCE, ButtonX);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_YDISTANCE, ButtonY + (buttonHeight + buttonSpacing) * i);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_XSIZE, buttonWidth);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_YSIZE, buttonHeight);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_CORNER, CORNER_LEFT_UPPER);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_FONTSIZE, 9);
            ObjectSetString(0, ButtonNames[i], OBJPROP_TEXT, "CCI " + IntegerToString(CCI_Periods[i]));
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_COLOR, clrWhite);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BGCOLOR, (i == CurrentPeriodIndex) ? clrGreen : clrDarkSlateGray);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BORDER_COLOR, clrBlack);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_SELECTABLE, false);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_SELECTED, false);
        }
    }
}

void UpdateButtons()
{
    for(int i = 0; i < 5; i++)
    {
        if(ObjectFind(0, ButtonNames[i]) >= 0)
        {
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BGCOLOR, (i == CurrentPeriodIndex) ? clrGreen : clrDarkSlateGray);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_STATE, false);
        }
    }
}

void DeleteButtons()
{
    for(int i = 0; i < 5; i++)
    {
        if(ObjectFind(0, ButtonNames[i]) >= 0)
        {
            ObjectDelete(0, ButtonNames[i]);
        }
    }
}

void UpdateIndicatorName()
{
    IndicatorSetString(INDICATOR_SHORTNAME, "CCI Arrows (" + IntegerToString(CurrentCCI_Period) + ") + EMA(" + IntegerToString(EMA_Fast) + "," + IntegerToString(EMA_Slow) + ")");
}

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[])
{
    ArraySetAsSeries(High, true);
    ArraySetAsSeries(Low, true);
    ArraySetAsSeries(Time, true);

    int counted_bars = prev_calculated;
    if (counted_bars > 0) counted_bars--;
    int limit = rates_total - 1 - counted_bars;

    double CCIBuffer[];
    double EMA_FastBuffer[];
    double EMA_SlowBuffer[];
    
    // Use the CURRENT period's handle
    if(CopyBuffer(CCI_Handles[CurrentPeriodIndex], 0, 0, rates_total, CCIBuffer) <= 0) return 0;
    if(CopyBuffer(myEMA_Fast, 0, 0, rates_total, EMA_FastBuffer) <= 0) return 0;
    if(CopyBuffer(myEMA_Slow, 0, 0, rates_total, EMA_SlowBuffer) <= 0) return 0;
    
    ArraySetAsSeries(CCIBuffer, true);
    ArraySetAsSeries(EMA_FastBuffer, true);
    ArraySetAsSeries(EMA_SlowBuffer, true);

    if (limit == 1) limit++; // Always redraw latest two bars.
    for (int i = 0; i < limit; i++)
    {
        // Calculate EMAs
        dEMA_Fast[i] = EMA_FastBuffer[i];
        dEMA_Slow[i] = EMA_SlowBuffer[i];
        
        // Initialize arrow buffers
        dUpCCIBuffer[i] = 0;
        dDownCCIBuffer[i] = 0;

        double myCCInow = CCIBuffer[i];
        double myCCI2 = CCIBuffer[i + 1]; // CCI one bar ago.

        if (myCCInow >= 0) // Is above zero.
        {
            if((myCCInow > 0) && (myCCI2 < 0)) // Did it cross from below 0?
            {
                int highest = iHighest(NULL, 0, MODE_HIGH, 20, i);
                int lowest = iLowest(NULL, 0, MODE_LOW, 20, i);
                double distance = (High[highest] - Low[lowest]) * 0.02;
                dUpCCIBuffer[i] = Low[i] - 2 * distance;
            }
        }

        if (myCCInow < 0) // Is below zero.
        {
            if((myCCInow < 0) && (myCCI2 > 0)) // Did it cross from above 0?
            {
                int highest = iHighest(NULL, 0, MODE_HIGH, 20, i);
                int lowest = iLowest(NULL, 0, MODE_LOW, 20, i);
                double distance = (High[highest] - Low[lowest]) * 0.02;
                dDownCCIBuffer[i] = High[i] + 2 * distance;
            }
        }
    }

    if ((!FirstRun) && ((EnableNativeAlerts) || (EnableEmailAlerts) || (EnablePushAlerts)))
    {
        if (((TriggerCandle > 0) && (Time[0] > LastAlertTime)) || (TriggerCandle == 0))
        {
            string Text;
            // Up arrow alert.
            if ((dUpCCIBuffer[TriggerCandle] != 0) && (LastAlertDirection != 1))
            {
                Text = "Up Arrow";
                if (EnableNativeAlerts) Alert(Text);
                Text = "CCI Arrows (" + IntegerToString(CurrentCCI_Period) + "): " + _Symbol + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 7) + " - " + Text + ".";
                if (EnableEmailAlerts) SendMail("CCI Arrows Alert", Text);
                if (EnablePushAlerts) SendNotification(Text);
                LastAlertTime = Time[0];
                LastAlertDirection = 1;
            }
            // Down arrow alert.
            if ((dDownCCIBuffer[TriggerCandle] != 0) && (LastAlertDirection != -1))
            {
                Text = "Down Arrow";
                if (EnableNativeAlerts) Alert(Text);
                Text = "CCI Arrows (" + IntegerToString(CurrentCCI_Period) + "): " + _Symbol + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 7) + " - " + Text + ".";
                if (EnableEmailAlerts) SendMail("CCI Arrows Alert", Text);
                if (EnablePushAlerts) SendNotification(Text);
                LastAlertTime = Time[0];
                LastAlertDirection = -1;
            }
        }
    }
    
    FirstRun = false;

    return rates_total;
}
//+------------------------------------------------------------------+