/*****************************************************************************
	This is a C++ source code file.  
	SaveSubgraphsToFile for more info pls DM me at https://twitter.com/MnuchinB
*****************************************************************************/

#include "sierrachart.h"
#include "scstudyfunctions.h"
#include "csv.h"
#include <vector>
#include <iostream>
#include <iterator>


SCDLLName("SaveSubgraphsToFile")

void WriteIntToLog (SCStudyInterfaceRef sc, const int integervalue, SCString Label)
{
	SCString Messagetw;
	Messagetw.Format(" %s : %i", Label.GetChars(), integervalue);
	sc.AddMessageToLog(Messagetw, 1);
}

void WriteFloatToLog (SCStudyInterfaceRef sc, const float floatvalue, SCString Label)
{
	SCString Messagetwf;
	Messagetwf.Format(" %s : %f", Label.GetChars(), floatvalue);
	sc.AddMessageToLog(Messagetwf, 1);
}

bool File_exists (const std::string& name) {
  struct stat buffer;   
  return (stat (name.c_str(), &buffer) == 0); 
}


/****************************************************************************/
SCSFExport scsf_SaveSubgraphsToFileLive(SCStudyInterfaceRef sc)
{
	// Set the configuration variables
	
	SCInputRef OutputFile = sc.Input[0];
    SCInputRef Input_ControlSubgraph1 = sc.Input[1];
	SCInputRef Input_ControlSubgraph2 = sc.Input[2];
    SCInputRef Input_ControlSubgraph3= sc.Input[3];
	SCInputRef Input_ControlSubgraph4= sc.Input[4];



 
	if (sc.SetDefaults)
	{
        OutputFile.Name = "The storage link";
        SCString OutputFileDefaultName;
        OutputFileDefaultName.Format("SaveSubgraphsToFile.txt");
        OutputFile.SetString(OutputFileDefaultName);
    
		Input_ControlSubgraph1.Name = "Select Subgraph 1";
		Input_ControlSubgraph1.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph2.Name = "Select Subgraph 2";
		Input_ControlSubgraph2.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph3.Name = "Select Subgraph 3";
		Input_ControlSubgraph3.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph4.Name = "Select Subgraph 4";
		Input_ControlSubgraph4.SetStudySubgraphValues(1, 1);


		sc.GraphName = "Save Subgraphs To File Live only";
		sc.StudyDescription = "Needs replay for past data - More info pls DM me at https://twitter.com/MnuchinB";
		sc.GraphRegion = 0;

		sc.AutoLoop = 1;
		sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL;

		return;
	}


	// Data processing


	int& PriorArraySizeSSF= sc.GetPersistentInt(1);
	int& Header2 = sc.GetPersistentInt(2);


	// writing headers

	if ( Header2 == 0 )
	{

		std::ifstream filetemp(OutputFile.GetString());
		bool IsEmpty = filetemp.peek() == EOF;
		filetemp.close();
		
		if (IsEmpty)
		{
			std::ofstream file(OutputFile.GetString(), std::ios_base::app);

			if (!file) {

			SCString Buffer;
			Buffer.Format("Unable to open file %s", OutputFile.GetString());
			sc.AddMessageToLog(Buffer, 1);
			
			}
			SCString Header = "Date,Time,Index,DateTime,SF1,SF2,SF3,SF4";
			file << Header;
			file << std::endl;
			Header2 = 1;
		}
		

	}

	// getting subgraphs

	SCFloatArray ControlSubgraph1;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph1.GetStudyID(), Input_ControlSubgraph1.GetSubgraphIndex(), ControlSubgraph1);

	SCFloatArray ControlSubgraph2;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph2.GetStudyID(), Input_ControlSubgraph2.GetSubgraphIndex(), ControlSubgraph2);

	SCFloatArray ControlSubgraph3;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph3.GetStudyID(), Input_ControlSubgraph3.GetSubgraphIndex(), ControlSubgraph3);

	SCFloatArray ControlSubgraph4;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph4.GetStudyID(), Input_ControlSubgraph4.GetSubgraphIndex(), ControlSubgraph4);



	if (sc.Index == 0)
	{
		PriorArraySizeSSF = sc.ArraySize;
    }


	if (PriorArraySizeSSF < sc.ArraySize)
	{

		std::ofstream file(OutputFile.GetString(), std::ios_base::app);

		if (!file) {

		SCString Buffer;
		Buffer.Format("Unable to open file %s", OutputFile.GetString());
		sc.AddMessageToLog(Buffer, 1);
		
		}

        int CurrentBarDate = sc.BaseDateTimeIn[sc.Index].GetDate();
		int CurrentBarTime = sc.BaseDateTimeIn[sc.Index].GetTime();
        int Year, Month, Day, Hour, Minute, Second;
		sc.BaseDateTimeIn[sc.Index].GetDateTimeYMDHMS(Year, Month, Day, Hour, Minute, Second);

		SCString BarDataString;
        SCString formatString = "%i,%i,%i,%i-%i-%i %i:%i:%i,%f,%f,%f,%f";
        BarDataString.Format(formatString, CurrentBarDate, CurrentBarTime, sc.Index, Year, Month, Day, Hour, Minute, Second, 
					ControlSubgraph1[sc.Index], ControlSubgraph2[sc.Index], ControlSubgraph3[sc.Index], ControlSubgraph4[sc.Index]);
        file << BarDataString;
		file << std::endl;
	}

	PriorArraySizeSSF = sc.ArraySize;

}


/****************************************************************************/
SCSFExport scsf_SaveSubgraphsToFilePastData(SCStudyInterfaceRef sc)
{
	// Set the configuration variables
	
	SCInputRef OutputFile = sc.Input[0];
    SCInputRef Input_ControlSubgraph1 = sc.Input[1];
	SCInputRef Input_ControlSubgraph2 = sc.Input[2];
    SCInputRef Input_ControlSubgraph3= sc.Input[3];
	SCInputRef Input_ControlSubgraph4= sc.Input[4];



 
	if (sc.SetDefaults)
	{
        OutputFile.Name = "The storage link";
        SCString OutputFileDefaultName;
        OutputFileDefaultName.Format("SaveSubgraphsToFile.txt");
        OutputFile.SetString(OutputFileDefaultName);
    
		Input_ControlSubgraph1.Name = "Select Subgraph 1";
		Input_ControlSubgraph1.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph2.Name = "Select Subgraph 2";
		Input_ControlSubgraph2.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph3.Name = "Select Subgraph 3";
		Input_ControlSubgraph3.SetStudySubgraphValues(1, 1);

        Input_ControlSubgraph4.Name = "Select Subgraph 4";
		Input_ControlSubgraph4.SetStudySubgraphValues(1, 1);


		sc.GraphName = "Save Subgraphs To File Past Data";
		sc.StudyDescription = "Save past data at a press of a button - More info pls DM me at https://twitter.com/MnuchinB";
		sc.GraphRegion = 0;

		sc.AutoLoop = 0;
		sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL;
		sc.ReceivePointerEvents = ACS_RECEIVE_POINTER_EVENTS_WHEN_ACS_BUTTON_ENABLED;

		return;
	}


	// Data processing

	int& r_MenuID = sc.GetPersistentInt(1);
	int& Header2 = sc.GetPersistentInt(2);
	int& Trigger1 = sc.GetPersistentInt(3);

	if (sc.IsFullRecalculation && sc.Index == 0) //This indicates a study is being recalculated.
	Trigger1 = 0;

	// adding the butons 

	if (sc.LastCallToFunction)
	{
		sc.SetCustomStudyControlBarButtonHoverText(1, "");
		sc.SetCustomStudyControlBarButtonText(1, "");
		sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_MenuID);
		return;
	}

	if (sc.UpdateStartIndex == 0)
	{
		// Set the ACS Control Bar button 1 hover text
		sc.SetCustomStudyControlBarButtonHoverText(1, "Export Subgraphs to file");

		// Set the ACS Control Bar button 1 text
		sc.SetCustomStudyControlBarButtonText(1, "Export Subgraphs to file");

		if (r_MenuID <= 0)
		{
			r_MenuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, "Export RR to txt");

		}

		if (r_MenuID < 0  ) 
		{
			SCString MessageText = "Add ACS Chart Shortcut menu item failed";
			sc.AddMessageToLog(MessageText, 1);
		}
	}

	// writing headers

	if ( Header2 == 0 )
	{

		std::ifstream filetemp(OutputFile.GetString());
		bool IsEmpty = filetemp.peek() == EOF;
		filetemp.close();
		
		if (IsEmpty)
		{
			std::ofstream file(OutputFile.GetString(), std::ios_base::app);

			if (!file) {

			SCString Buffer;
			Buffer.Format("Unable to open file %s", OutputFile.GetString());
			sc.AddMessageToLog(Buffer, 1);
			
			}
			SCString Header = "Date,Time,Index,DateTime,SF1,SF2,SF3,SF4";
			file << Header;
			file << std::endl;
			Header2 = 1;
		}
		

	}

	// getting subgraphs

	SCFloatArray ControlSubgraph1;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph1.GetStudyID(), Input_ControlSubgraph1.GetSubgraphIndex(), ControlSubgraph1);

	SCFloatArray ControlSubgraph2;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph2.GetStudyID(), Input_ControlSubgraph2.GetSubgraphIndex(), ControlSubgraph2);

	SCFloatArray ControlSubgraph3;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph3.GetStudyID(), Input_ControlSubgraph3.GetSubgraphIndex(), ControlSubgraph3);

	SCFloatArray ControlSubgraph4;
	sc.GetStudyArrayUsingID(Input_ControlSubgraph4.GetStudyID(), Input_ControlSubgraph4.GetSubgraphIndex(), ControlSubgraph4);


	// wait for an event
	if (sc.MenuEventID != 0)
	{

		if (Trigger1 == 0)
		{

			std::ofstream file(OutputFile.GetString(), std::ios_base::app);

			if (!file) {

			SCString Buffer;
			Buffer.Format("Unable to open file %s", OutputFile.GetString());
			sc.AddMessageToLog(Buffer, 1);
			
			}

			for ( int Index = 0 ; Index < sc.ArraySize ; Index++)
			{

				int CurrentBarDate = sc.BaseDateTimeIn[Index].GetDate();
				int CurrentBarTime = sc.BaseDateTimeIn[Index].GetTime();
				int Year, Month, Day, Hour, Minute, Second;
				sc.BaseDateTimeIn[Index].GetDateTimeYMDHMS(Year, Month, Day, Hour, Minute, Second);

				SCString BarDataString;
				SCString formatString = "%i,%i,%i,%i-%i-%i %i:%i:%i,%f,%f,%f,%f";
				BarDataString.Format(formatString, CurrentBarDate, CurrentBarTime, Index, Year, Month, Day, Hour, Minute, Second, 
							ControlSubgraph1[Index], ControlSubgraph2[Index], ControlSubgraph3[Index], ControlSubgraph4[Index]);
				file << BarDataString;
				file << std::endl;
			}

			Trigger1 = 1;
		}
	}

}

/****************************************************************************/
SCSFExport scsf_LoadSubgraphFromFile(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
	SCSubgraphRef Subgraph_High = sc.Subgraph[1];
	SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
	SCSubgraphRef Subgraph_Close = sc.Subgraph[3];

    SCInputRef InputFile = sc.Input[0];
	    
	if (sc.SetDefaults)
    {
        sc.GraphName = "Load Subgraphs From File";
		sc.StudyDescription = "More info pls DM me at https://twitter.com/MnuchinB";

		sc.AutoLoop = 1;
        // sc.GraphDrawType = GDT_CANDLESTICK;
        // sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		// sc.MaintainHistoricalMarketDepthData = 1;
        // sc.UsesMarketDepthData = 1;
		sc.UpdateAlways = 1;
		sc.ReceivePointerEvents = ACS_RECEIVE_POINTER_EVENTS_WHEN_ACS_BUTTON_ENABLED;

		Subgraph_Open.Name = "Subgraph1";
		Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Open.PrimaryColor = RGB(0,255,0);
		// Subgraph_Open.SecondaryColorUsed = true;
		// Subgraph_Open.SecondaryColor = RGB(0,255,0);
		Subgraph_Open.DrawZeros = true;

		Subgraph_High.Name = "Subgraph2";
		Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_High.PrimaryColor = RGB(128,255,128);
		Subgraph_High.DrawZeros = true;

		Subgraph_Low.Name = "Subgraph3";
		Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Low.PrimaryColor = RGB(255,0,0);
		// Subgraph_Low.SecondaryColor = RGB(255,0,0);
		// Subgraph_Low.SecondaryColorUsed = true;
		Subgraph_Low.DrawZeros = true;

		Subgraph_Close.Name = "Subgraph4";
		Subgraph_Close.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Close.PrimaryColor = RGB(255,128,128);
		Subgraph_Close.DrawZeros = true;

        InputFile.Name = "The storage file";
        SCString InputFileDefaultName;
        InputFileDefaultName.Format("SaveSubgraphsToFile.txt");
        InputFile.SetString(InputFileDefaultName);

        return;

	}

	// Data processing

    int& Trig1 = sc.GetPersistentInt(1);
    float& DateTimeDouble = sc.GetPersistentFloat(2);
    int& SubgraphIndex = sc.GetPersistentInt(3);



	if (sc.IsFullRecalculation && sc.Index == 0) //This indicates a study is being recalculated.
	Trig1 = 0;

	if( File_exists(InputFile.GetString()))
	{


		if(Trig1 == 0)
		{
			io::CSVReader<7> in(InputFile.GetString());
			in.read_header(io::ignore_extra_column, "Date","Time","Index","SF1", "SF2", "SF3", "SF4");
			float OpenV, HighV, LowV, CloseV;
			long int DateV, TimeV, IndexV;
		
			while(in.read_row(DateV, TimeV, IndexV, OpenV, HighV, LowV, CloseV))
			{

				SCDateTime DateTime(DateV,TimeV);
				int SubgraphIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, DateTime);
				Subgraph_Open[SubgraphIndex + 1] = OpenV;
				Subgraph_High[SubgraphIndex + 1] = HighV;
				Subgraph_Low[SubgraphIndex + 1] = LowV;
				Subgraph_Close[SubgraphIndex + 1] = CloseV;
				
			}

		}

		Trig1 = 1;
	}
	else 
	{
		if (Trig1 == 0)
		{
			sc.AddMessageToLog("File path does not exists", 1);
			Trig1 = 1;

		}
		
		else
		return;
	}
	
	

}

/****************************************************************************/
SCSFExport scsf_LoadSubgraphFromFileAOHLC(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
	SCSubgraphRef Subgraph_High = sc.Subgraph[1];
	SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
	SCSubgraphRef Subgraph_Close = sc.Subgraph[3];

    SCInputRef InputFile = sc.Input[0];
	    
	if (sc.SetDefaults)
    {
        sc.GraphName = "Load Subgraphs From File OHLC";
		sc.StudyDescription = "the 4 subgraphs have to be open / high / low / close in this order 1 / 2 / 3 / 4 More info pls DM me at https://twitter.com/MnuchinB";

		sc.AutoLoop = 1;
        sc.GraphDrawType = GDT_CANDLESTICK;
        // sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		// sc.MaintainHistoricalMarketDepthData = 1;
        // sc.UsesMarketDepthData = 1;
		sc.UpdateAlways = 1;
		sc.ReceivePointerEvents = ACS_RECEIVE_POINTER_EVENTS_WHEN_ACS_BUTTON_ENABLED;

		Subgraph_Open.Name = "Subgraph1";
		Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Open.PrimaryColor = RGB(0,255,0);
		Subgraph_Open.SecondaryColorUsed = true;
		Subgraph_Open.SecondaryColor = RGB(0,255,0);
		Subgraph_Open.DrawZeros = true;

		Subgraph_High.Name = "Subgraph2";
		Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_High.PrimaryColor = RGB(128,255,128);
		Subgraph_High.DrawZeros = true;

		Subgraph_Low.Name = "Subgraph3";
		Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Low.PrimaryColor = RGB(255,0,0);
		Subgraph_Low.SecondaryColor = RGB(255,0,0);
		Subgraph_Low.SecondaryColorUsed = true;
		Subgraph_Low.DrawZeros = true;

		Subgraph_Close.Name = "Subgraph4";
		Subgraph_Close.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Close.PrimaryColor = RGB(255,128,128);
		Subgraph_Close.DrawZeros = true;

        InputFile.Name = "The storage file";
        SCString InputFileDefaultName;
        InputFileDefaultName.Format("SaveSubgraphsToFile.txt");
        InputFile.SetString(InputFileDefaultName);

        return;

	}

	// Data processing

    int& Trig1 = sc.GetPersistentInt(1);
    float& DateTimeDouble = sc.GetPersistentFloat(2);
    int& SubgraphIndex = sc.GetPersistentInt(3);


	if (sc.IsFullRecalculation && sc.Index == 0) //This indicates a study is being recalculated.
	Trig1 = 0;

	if( File_exists(InputFile.GetString()))
	{


		if(Trig1 == 0)
		{
			io::CSVReader<7> in(InputFile.GetString());
			in.read_header(io::ignore_extra_column, "Date","Time","Index","SF1", "SF2", "SF3", "SF4");
			float OpenV, HighV, LowV, CloseV;
			long int DateV, TimeV, IndexV;
		
			while(in.read_row(DateV, TimeV, IndexV, OpenV, HighV, LowV, CloseV))
			{

				SCDateTime DateTime(DateV,TimeV);
				int SubgraphIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, DateTime);
				Subgraph_Open[SubgraphIndex + 1] = OpenV;
				Subgraph_High[SubgraphIndex + 1] = HighV;
				Subgraph_Low[SubgraphIndex + 1] = LowV;
				Subgraph_Close[SubgraphIndex + 1] = CloseV;
				
			}

		}

		Trig1 = 1;
	}
	else 
	{
		if (Trig1 == 0)
		{
			sc.AddMessageToLog("File path does not exists", 1);
			Trig1 = 1;

		}
		
		else
		return;
	}
	
	

}