/*****************************************************************************

This file contains the scsf_CopyOfBaseGraph function which is an Advanced
Custom Study function that creates a copy of the existing base graph in a
chart. You can modify this or use it as an example to create your own custom
chart.

If you want to create your own custom chart bars which are based upon the
underlying data in an Intraday chart data file, instead used the custom chart
bar interface which is demonstrated through the included 
ACSILCustomChartBars_Example.cpp file.

scsf_CopyOfBaseGraph is used to create custom chart bars but are based upon the
existing chart bars loaded within the chart. This may be useful for some purposes,
but in general it is an inefficient method to create custom chart bars.


*****************************************************************************/

#include "sierrachart.h"

/*==========================================================================*/
SCSFExport scsf_CopyOfBaseGraph(SCStudyInterfaceRef sc)
{
    SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
    SCSubgraphRef Subgraph_High = sc.Subgraph[1];
    SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
    SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
    SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
    SCSubgraphRef Subgraph_OpenInterest = sc.Subgraph[5];
    SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6];
    SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7];
    SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8];
    //SCSubgraphRef BidVol = sc.Subgraph[9];
//  SCSubgraphRef AskVol = sc.Subgraph[10];

    // Set configuration variables

    if (sc.SetDefaults)
    {
        // Set the defaults

        sc.GraphName = "Copy of BaseGraph Example";

        sc.StudyDescription = "This is an example of how to create a custom chart. This one is a copy of the BaseGraph.";

        // This member indicates that this is a custom chart study. 
        //  This can only be set when SetDefaults is true.
        sc.IsCustomChart = 1;  // true      
        sc.GraphRegion = 0;  // First region        
        sc.DrawZeros = 0;  // false     
        sc.GraphDrawType = GDT_OHLCBAR;
        sc.StandardChartHeader = 1; // true

        // Subgraphs

        Subgraph_Open.Name = "Open";
        Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;

        Subgraph_High.Name = "High";
        Subgraph_High.DrawStyle = DRAWSTYLE_LINE;

        Subgraph_Low.Name = "Low";
        Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;

        Subgraph_Last.Name = "Last";
        Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;

        Subgraph_Volume.Name = "Volume";
        Subgraph_Volume.DrawStyle = DRAWSTYLE_IGNORE;

        Subgraph_OpenInterest.Name = "# of Trades / OI";
        Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;

        Subgraph_OHLCAvg.Name = "OHLC Avg";
        Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE;

        Subgraph_HLCAvg.Name = "HLC Avg";
        Subgraph_HLCAvg.DrawStyle = DRAWSTYLE_IGNORE;

        Subgraph_HLAvg.Name = "HL Avg";
        Subgraph_HLAvg.DrawStyle = DRAWSTYLE_IGNORE;

    /*  BidVol.Name = "Bid Vol";
        BidVol.DrawStyle = DRAWSTYLE_IGNORE;

        AskVol.Name = "Ask Vol";
        AskVol.DrawStyle = DRAWSTYLE_IGNORE;*/

        return;
    }

    // If our start index is zero, then we want to clear our existing chart
    // data, if any, so we start clean to avoid any possible problems.  This
    // is accomplished by using sc.ResizeArrays.
    if (sc.UpdateStartIndex == 0)
    {
        sc.ResizeArrays(0);
    }

    // Do data processing
    for (int i = sc.UpdateStartIndex; i < sc.ArraySize; i++)
    {
        if (sc.OutArraySize - 1 < i)
            sc.AddElements(1);

        sc.DateTimeOut[i] = sc.BaseDateTimeIn[i];

        for (int SubGraph = 0; SubGraph <=8; SubGraph++)
        {
            sc.Subgraph[SubGraph][i] = sc.BaseDataIn[SubGraph][i];

            //For testing coloring bars
            //sc.Subgraph[SubGraph].DataColor[i] = RGB(255,255,255);
        }
    }
}


/*==========================================================================*/
SCSFExport scsf_ReverseOrderCopyOfBaseGraph(SCStudyInterfaceRef sc)
{
    SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
    SCSubgraphRef Subgraph_High = sc.Subgraph[1];
    SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
    SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
    SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
    SCSubgraphRef Subgraph_OpenInterest = sc.Subgraph[5];
    SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6];
    SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7];
    SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8];
    SCSubgraphRef Subgraph_BidVol = sc.Subgraph[9];
    SCSubgraphRef Subgraph_AskVol = sc.Subgraph[10];

    SCInputRef Input_InNumberOfBarsToReverse = sc.Input[1];

    // Set configuration variables

    if (sc.SetDefaults)
    {
        // Set the defaults
        sc.GraphName = "Reverse Copy of Base Graph";

        sc.AutoLoop = 0;

        // This member indicates that this is a custom chart study. 
        //  This can only be set when SetDefaults is true.
        sc.IsCustomChart = 1;  // true      
        sc.GraphRegion = 0;  // First region        
        sc.DrawZeros = 0;  // false     
        sc.GraphDrawType = GDT_OHLCBAR;
        sc.StandardChartHeader = 1; // true
        sc.GraphUsesChartColors = 1;

        Input_InNumberOfBarsToReverse.Name = "Number Of Bars To Reverse";
        Input_InNumberOfBarsToReverse.SetInt(1000);
        Input_InNumberOfBarsToReverse.SetIntLimits(10, 2000);

        return;
    }


    int &PriorBaseGraphArraySize = sc.GetPersistentInt(1);

    // If there is a full recalculation, then we want to clear the existing chart
    // data, if any, so we start clean to avoid any possible problems.  This
    // is accomplished by using sc.ResizeArrays.
    if (sc.IsFullRecalculation && sc.UpdateStartIndex==0)
    {
        sc.ResizeArrays(0);

        for (int SubgraphIndex = 0; SubgraphIndex <= NUM_BASE_GRAPH_ARRAYS; ++SubgraphIndex)
        {
            sc.Subgraph[SubgraphIndex].Name = sc.GetStudySubgraphName(0, SubgraphIndex);
        }

        PriorBaseGraphArraySize = 0;
    }

    int RequiredBarElements = min(sc.ArraySize, Input_InNumberOfBarsToReverse.GetInt());
    if (sc.OutArraySize < RequiredBarElements)
        sc.ResizeArrays(RequiredBarElements);
    //sc.AddElements(1);

    // Do data processing
    for (int InputDataIndex = sc.ArraySize - 1, OutputIndex = 0; InputDataIndex >= 0; InputDataIndex--, OutputIndex++)
    {
        sc.DateTimeOut[OutputIndex] = sc.BaseDateTimeIn[InputDataIndex];

        for (int SubGraph = 0; SubGraph <= NUM_BASE_GRAPH_ARRAYS; SubGraph++)
        {
            sc.Subgraph[SubGraph][OutputIndex] = sc.BaseDataIn[SubGraph][InputDataIndex];
        }

        //if there is no change in based graph array size, then one iteration is sufficient
        if (PriorBaseGraphArraySize == sc.ArraySize)
            break;
    }


    PriorBaseGraphArraySize = sc.ArraySize;
}