
#include "sierrachart.h"
#include "scstudyfunctions.h"

#include <vector>

/*============================================================================*/
int RequestValuesFromServer_2(SCStudyInterfaceRef sc);

void ClearRequest_2(SCStudyInterfaceRef sc);

bool GetValuesForDate_2(SCStudyInterfaceRef sc, SCDateTime BarDate, float* Values,unsigned int ArraySize);

/*============================================================================*/
SCSFExport scsf_TradingLevelsStudy(SCStudyInterfaceRef sc)
{
	const int LevelsCount = SC_SUBGRAPHS_AVAILABLE;
	SCInputRef Version = sc.Input[0];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Trading Levels";

		sc.GraphRegion = 0;
		sc.ScaleRangeType = SCALE_SAMEASREGION;
		sc.ValueFormat =  VALUEFORMAT_INHERITED;
		sc.AutoLoop = 0;
		sc.FreeDLL =false;
		sc.StudyDescription = "Requests line level values from Web server in the format 'YYYY-MM-DD, #, #, #, #' where the # is equal to the value of the line. There can be up to 60 level values.";


		for (int Index = 0; Index < LevelsCount; Index++)
		{
			SCString SubgraphName;
			SubgraphName.Format("Level %d", Index+1);
			sc.Subgraph[Index].Name = SubgraphName;
			sc.Subgraph[Index].DrawStyle = DRAWSTYLE_DASH;
			sc.Subgraph[Index].LineWidth = 2;
			sc.Subgraph[Index].PrimaryColor = RGB(0, 255, 0);
			sc.Subgraph[Index].DrawZeros = 0;  // false
			sc.Subgraph[Index].LineLabel = LL_DISPLAY_VALUE | LL_VALUE_ALIGN_CENTER | LL_VALUE_ALIGN_VALUES_SCALE;
		}

		return;
	}


	std::vector <SCString> *p_ValuesLineForDates = (std::vector <SCString>*)sc.GetPersistentPointer(1);
	std::vector <std::vector < char*> > *p_PointersToValuesForDates = (std::vector <std::vector < char*> >*)sc.GetPersistentPointer(2);

	if(sc.LastCallToFunction)
	{
		if(p_ValuesLineForDates != NULL)
		{
			delete p_ValuesLineForDates;
			sc.SetPersistentPointer(1, NULL);
		}

		if(p_PointersToValuesForDates != NULL)
		{
			delete p_PointersToValuesForDates;
			sc.SetPersistentPointer(2, NULL);
		}

		return;
	}

	if(p_ValuesLineForDates == NULL)
	{

		p_ValuesLineForDates = new std::vector <SCString>;

		if(p_ValuesLineForDates != NULL)
			sc.SetPersistentPointer(1, p_ValuesLineForDates);
		else
			return;
	}

	if(p_PointersToValuesForDates == NULL)
	{

		p_PointersToValuesForDates = new std::vector <std::vector < char*> >;

		if(p_PointersToValuesForDates != NULL)
			sc.SetPersistentPointer(2, p_PointersToValuesForDates);
		else
			return;
	}


	int& RequestState = sc.GetPersistentInt(1);
	SCDateTime& RequestDateTime = sc.GetPersistentSCDateTime(2);

	//Note: request data every 1 hour

	// This is to solve a condition when Apply is used from the Chart Studies window, and the initial state of the RequestState is remembered
	if (sc.UpdateStartIndex == 0  && RequestState == HTTP_REQUEST_MADE)
		ClearRequest_2(sc);  
	else if (sc.UpdateStartIndex == 0  && RequestState == HTTP_REQUEST_RECEIVED)
		ClearRequest_2(sc);
	else if (RequestDateTime == 0.0
		|| ( (sc.CurrentSystemDateTime - RequestDateTime) >= 1 * HOURS)
		)
		ClearRequest_2(sc);

	if (!RequestValuesFromServer_2(sc))
		return;

	if (sc.HTTPResponse == "HTTP_REQUEST_ERROR" || sc.HTTPResponse == "EMPTY_RESPONSE")
		sc .AddMessageToLog("There was an error requesting data from the server.", true);

	bool FullRecalculate = false;

	if(p_ValuesLineForDates->size() == 0)
	{
		sc.HTTPResponse.ParseLines(*p_ValuesLineForDates);

		std::vector <char *> EmptyVector;

		for (int Index = 0; Index < (int)p_ValuesLineForDates->size(); Index++)
		{
			p_PointersToValuesForDates->push_back(EmptyVector);
			p_ValuesLineForDates->at(Index).Tokenize(",", p_PointersToValuesForDates->back());
		}

		FullRecalculate = true;
	}


	if(p_PointersToValuesForDates->empty())
		return;


	if (FullRecalculate)
		sc.UpdateStartIndex= 0;

	float LevelValues[LevelsCount];

	SCDateTime PriorDate ;

	for (int BarIndex = sc.UpdateStartIndex; BarIndex<sc.ArraySize; BarIndex++)
	{
		SCDateTime IndexDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[BarIndex]);

		if (PriorDate != IndexDate)
			GetValuesForDate_2(sc, IndexDate, LevelValues, LevelsCount);

		PriorDate = IndexDate;

		for (unsigned int LevelIndex = 0; LevelIndex < LevelsCount; LevelIndex++)
			sc.Subgraph[LevelIndex][BarIndex] = LevelValues[LevelIndex];

	}

}

/*============================================================================*/
int RequestValuesFromServer_2(SCStudyInterfaceRef sc)
{
	SCString WebsiteURL;

	int& RequestState = sc.GetPersistentInt(1);

	if (RequestState == HTTP_REQUEST_NOT_SENT)
	{
		WebsiteURL.Format("http://www.sierrachart.com/test/LevelValues.php?Symbol=%s", sc.Symbol.GetChars());

		if (!sc.MakeHTTPRequest(WebsiteURL))
		{
			sc.AddMessageToLog("Error making HTTP Request.", true);
			RequestState = HTTP_REQUEST_ERROR;
		}
		else
		{
			RequestState = HTTP_REQUEST_MADE;
			sc.AddMessageToLog("Requesting data from Trading Levels server.",false);
		}

		return 0;
	}

	if (RequestState == HTTP_REQUEST_MADE && sc.HTTPResponse != "")
	{
		RequestState = HTTP_REQUEST_RECEIVED;
		return 1;
	}
	else if(RequestState == HTTP_REQUEST_MADE && sc.HTTPResponse == "")
	{
		return 0;
	}

	if (RequestState != HTTP_REQUEST_RECEIVED)
		return 0;

	return 1;
}

/*============================================================================*/
void ClearRequest_2(SCStudyInterfaceRef sc)
{
	int& RequestState = sc.GetPersistentInt(1);
	SCDateTime& RequestDateTime = sc.GetPersistentSCDateTime(2);

	std::vector <SCString> *p_ValuesLineForDates = (std::vector <SCString>*)sc.GetPersistentPointer(1);
	std::vector <std::vector < char*> > *p_PointersToValuesForDates = (std::vector <std::vector < char*> >*)sc.GetPersistentPointer(2);

	p_ValuesLineForDates->clear();
	p_PointersToValuesForDates->clear();

	RequestState = HTTP_REQUEST_NOT_SENT;
	RequestDateTime = sc.CurrentSystemDateTime;
}
/*============================================================================*/
bool GetValuesForDate_2(SCStudyInterfaceRef sc, SCDateTime BarDate, float* Values,unsigned int ArraySize)
{
	//Clean array
	for(unsigned int Index = 0; Index < ArraySize; Index++)
	{
		Values[Index] = 0.0;
	}

	std::vector <SCString> *p_ValuesLineForDates = (std::vector <SCString>*)sc.GetPersistentPointer(1);
	std::vector <std::vector < char*> > *p_PointersToValuesForDates = (std::vector <std::vector < char*> >*)sc.GetPersistentPointer(2);

	if (p_PointersToValuesForDates->size() < 1)
		return false;

	for(unsigned int Index = 0; Index < p_PointersToValuesForDates->size(); Index++)
	{
		SCDateTime DataDate =sc.DateStringToSCDateTime(p_PointersToValuesForDates->at(Index)[0]);
		if( DataDate != BarDate)
			continue;

		for(unsigned int ItemIndex = 1; ItemIndex < min(ArraySize+1 ,  p_PointersToValuesForDates->at(Index).size()); ItemIndex++ )
			Values[ItemIndex-1] = (float)atof(p_PointersToValuesForDates->at(Index)[ItemIndex]);



	}

	return true;
}
/*============================================================================*/

