// The top of every source code file must include this line
#include "sierrachart.h"

SCDLLName("FC Horiz Line Subgraphs")

/* a node of the singly linked list */
struct Node
{
	double data;

	struct Node* next;
};

struct Node* Study01 = NULL;
struct Node* Study02 = NULL;
struct Node* Study03 = NULL;
struct Node* Study04 = NULL;
struct Node* Study05 = NULL;
struct Node* Study06 = NULL;

//struct Node* BelowMarket = NULL;
struct Node* TempNode = NULL;

/* A utility function to insert a node at the beginning of linked list */
void push(struct Node** head_ref, double new_data)
{
	/* allocate node */
	struct Node* new_node = new Node;

	/* put in the data */
	new_node->data = new_data;

	/* link the old list off the new node */
	new_node->next = (*head_ref);

	/* move the head to point to the new node */
	(*head_ref) = new_node;
}


/* A utility function to print linked list */
void printList(SCStudyInterfaceRef sc, struct Node* node)
{
	while (node != NULL)
	{
		SCString MessageOut;
		MessageOut.Format("Data: %f", node->data);
		sc.AddMessageToLog(MessageOut, 0);
		//MessageOut.Format("Color: %i", node->color);
		//sc.AddMessageToLog(MessageOut, 0);
		//MessageOut.Format("Source: %i", node->source);
		//sc.AddMessageToLog(MessageOut, 0);
		node = node->next;
	}
}

int countnodes(Node* node)
{
	int count = 0;
	if (node == NULL)
		return 0;
	while (node != NULL)
	{
		count++;
		node = node->next;
	}

	return count;
}

/* Function to reverse the linked list */
void reverse(Node* node)
{
	// Initialize current, previous and 
	// next pointers 
	Node* current = node;
	Node* prev = NULL;
	Node* next = NULL;

	while (current != NULL) {
		// Store next 
		next = current->next;

		// Reverse current node's pointer 
		current->next = prev;

		// Move pointers one position ahead. 
		prev = current;
		current = next;
	}
	current = prev;
}

// Function to delete the entire linked list 

//void deleteList(Node* head)
/* Function to delete the entire linked list */
void deleteList(Node** head_ref)
{

	/* deref head_ref to get the real head */
	Node* current = *head_ref;
	Node* next;

	while (current != NULL)
	{
		next = current->next;
		free(current);
		current = next;
	}

	/* deref head_ref to affect the real head back
		in the caller. */
	*head_ref = NULL;
}



// Returns the last node of the list 
struct Node* getTail(struct Node* cur)
{
	while (cur != NULL && cur->next != NULL)
		cur = cur->next;
	return cur;
}


// Partitions the list taking the last element as the pivot 
struct Node* partition(struct Node* head, struct Node* end,
	struct Node** newHead, struct Node** newEnd)
{
	struct Node* pivot = end;
	struct Node* prev = NULL, * cur = head, * tail = pivot;

	// During partition, both the head and end of the list might change 
	// which is updated in the newHead and newEnd variables 
	while (cur != pivot)
	{
		if (cur->data < pivot->data)
		{
			// First node that has a value less than the pivot - becomes 
			// the new head 
			if ((*newHead) == NULL)
				(*newHead) = cur;

			prev = cur;
			cur = cur->next;
		}
		else // If cur node is greater than pivot 
		{
			// Move cur node to next of tail, and change tail 
			if (prev)
				prev->next = cur->next;
			struct Node* tmp = cur->next;
			cur->next = NULL;
			tail->next = cur;
			tail = cur;
			cur = tmp;
		}
	}

	// If the pivot data is the smallest element in the current list, 
	// pivot becomes the head 
	if ((*newHead) == NULL)
		(*newHead) = pivot;

	// Update newEnd to the current last node 
	(*newEnd) = tail;

	// Return the pivot node 
	return pivot;
}


//here the sorting happens exclusive of the end node 
struct Node* quickSortRecur(struct Node* head, struct Node* end)
{
	// base condition 
	if (!head || head == end)
		return head;

	Node* newHead = NULL, * newEnd = NULL;

	// Partition the list, newHead and newEnd will be updated 
	// by the partition function 
	struct Node* pivot = partition(head, end, &newHead, &newEnd);

	// If pivot is the smallest element - no need to recur for 
	// the left part. 
	if (newHead != pivot)
	{
		// Set the node before the pivot node as NULL 
		struct Node* tmp = newHead;
		while (tmp->next != pivot)
			tmp = tmp->next;
		tmp->next = NULL;

		// Recur for the list before pivot 
		newHead = quickSortRecur(newHead, tmp);

		// Change next of last node of the left half to pivot 
		tmp = getTail(newHead);
		tmp->next = pivot;
	}

	// Recur for the list after the pivot element 
	pivot->next = quickSortRecur(pivot->next, newEnd);

	return newHead;
}

// The main function for quick sort. This is a wrapper over recursive 
// function quickSortRecur() 
void quickSort(struct Node** headRef)
{
	(*headRef) = quickSortRecur(*headRef, getTail(*headRef));
	return;
}

void InsertValueFromChartStudyID(SCStudyInterfaceRef sc, float Value, int source)
{

	switch (source)
	{
	case 1:
		//if (countnodes(Study01) < 10)
		push(&Study01, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	case 2:
		//if (countnodes(Study02) < 10)
		push(&Study02, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	case 3:
		//if (countnodes(Study03) < 10)
		push(&Study03, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	case 4:
		//if (countnodes(Study04) < 10)
		push(&Study04, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	case 5:
		//if (countnodes(Study05) < 10)
		push(&Study05, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	case 6:
		//if (countnodes(Study06) < 10)
		push(&Study06, sc.RoundToTickSize(Value, sc.TickSize));
		break;
	}

	return;
}




SCSFExport scsf_ChartStudy_ID_SG_Stack(SCStudyInterfaceRef sc)
{
	// Set configuration variables
	SCInputRef MiniVersion = sc.Input[0];

	//SCInputRef Chart1Number = sc.Input[1];
	//SCInputRef Chart2Number = sc.Input[2];
	//SCInputRef Chart3Number = sc.Input[3];
	//SCInputRef Chart4Number = sc.Input[4];

	SCInputRef EnableBlock01Study = sc.Input[5];
	SCInputRef Block01StudyIDRef = sc.Input[6];
	SCInputRef Block01SortBy = sc.Input[7];

	SCInputRef EnableBlock02Study = sc.Input[8];
	SCInputRef Block02StudyIDRef = sc.Input[9];
	SCInputRef Block02SortBy = sc.Input[10];

	SCInputRef EnableBlock03Study = sc.Input[11];
	SCInputRef Block03StudyIDRef = sc.Input[12];
	SCInputRef Block03SortBy = sc.Input[13];

	SCInputRef EnableBlock04Study = sc.Input[14];
	SCInputRef Block04StudyIDRef = sc.Input[15];
	SCInputRef Block04SortBy = sc.Input[16];

	SCInputRef EnableBlock05Study = sc.Input[17];
	SCInputRef Block05StudyIDRef = sc.Input[18];
	SCInputRef Block05SortBy = sc.Input[19];

	SCInputRef EnableBlock06Study = sc.Input[20];
	SCInputRef Block06StudyIDRef = sc.Input[21];
	SCInputRef Block06SortBy = sc.Input[22];

	SCInputRef BarsToCalc = sc.Input[95];
	SCInputRef DebugMode = sc.Input[96];

	SCInputRef Block01SG01 = sc.Input[31];
	SCInputRef Block01SG02 = sc.Input[32];
	SCInputRef Block01SG03 = sc.Input[33];
	SCInputRef Block01SG04 = sc.Input[34];
	SCInputRef Block01SG05 = sc.Input[35];
	SCInputRef Block01SG06 = sc.Input[36];
	SCInputRef Block01SG07 = sc.Input[37];
	SCInputRef Block01SG08 = sc.Input[38];
	SCInputRef Block01SG09 = sc.Input[39];
	SCInputRef Block01SG10 = sc.Input[40];
	SCInputRef Block02SG01 = sc.Input[41];
	SCInputRef Block02SG02 = sc.Input[42];
	SCInputRef Block02SG03 = sc.Input[43];
	SCInputRef Block02SG04 = sc.Input[44];
	SCInputRef Block02SG05 = sc.Input[45];
	SCInputRef Block02SG06 = sc.Input[46];
	SCInputRef Block02SG07 = sc.Input[47];
	SCInputRef Block02SG08 = sc.Input[48];
	SCInputRef Block02SG09 = sc.Input[49];
	SCInputRef Block02SG10 = sc.Input[50];
	SCInputRef Block03SG01 = sc.Input[51];
	SCInputRef Block03SG02 = sc.Input[52];
	SCInputRef Block03SG03 = sc.Input[53];
	SCInputRef Block03SG04 = sc.Input[54];
	SCInputRef Block03SG05 = sc.Input[55];
	SCInputRef Block03SG06 = sc.Input[56];
	SCInputRef Block03SG07 = sc.Input[57];
	SCInputRef Block03SG08 = sc.Input[58];
	SCInputRef Block03SG09 = sc.Input[59];
	SCInputRef Block03SG10 = sc.Input[60];
	SCInputRef Block04SG01 = sc.Input[61];
	SCInputRef Block04SG02 = sc.Input[62];
	SCInputRef Block04SG03 = sc.Input[63];
	SCInputRef Block04SG04 = sc.Input[64];
	SCInputRef Block04SG05 = sc.Input[65];
	SCInputRef Block04SG06 = sc.Input[66];
	SCInputRef Block04SG07 = sc.Input[67];
	SCInputRef Block04SG08 = sc.Input[68];
	SCInputRef Block04SG09 = sc.Input[69];
	SCInputRef Block04SG10 = sc.Input[70];
	SCInputRef Block05SG01 = sc.Input[71];
	SCInputRef Block05SG02 = sc.Input[72];
	SCInputRef Block05SG03 = sc.Input[73];
	SCInputRef Block05SG04 = sc.Input[74];
	SCInputRef Block05SG05 = sc.Input[75];
	SCInputRef Block05SG06 = sc.Input[76];
	SCInputRef Block05SG07 = sc.Input[77];
	SCInputRef Block05SG08 = sc.Input[78];
	SCInputRef Block05SG09 = sc.Input[79];
	SCInputRef Block05SG10 = sc.Input[80];
	SCInputRef Block06SG01 = sc.Input[81];
	SCInputRef Block06SG02 = sc.Input[82];
	SCInputRef Block06SG03 = sc.Input[83];
	SCInputRef Block06SG04 = sc.Input[84];
	SCInputRef Block06SG05 = sc.Input[85];
	SCInputRef Block06SG06 = sc.Input[86];
	SCInputRef Block06SG07 = sc.Input[87];
	SCInputRef Block06SG08 = sc.Input[88];
	SCInputRef Block06SG09 = sc.Input[89];
	SCInputRef Block06SG10 = sc.Input[90];



	//SCInputRef StudyValueFormat = sc.Input[66];





	SCSubgraphRef 	Block01_00 = sc.Subgraph[0];
	SCSubgraphRef 	Block01_01 = sc.Subgraph[1];
	SCSubgraphRef 	Block01_02 = sc.Subgraph[2];
	SCSubgraphRef 	Block01_03 = sc.Subgraph[3];
	SCSubgraphRef 	Block01_04 = sc.Subgraph[4];
	SCSubgraphRef 	Block01_05 = sc.Subgraph[5];
	SCSubgraphRef 	Block01_06 = sc.Subgraph[6];
	SCSubgraphRef 	Block01_07 = sc.Subgraph[7];
	SCSubgraphRef 	Block01_08 = sc.Subgraph[8];
	SCSubgraphRef 	Block01_09 = sc.Subgraph[9];
	SCSubgraphRef 	Block02_00 = sc.Subgraph[10];
	SCSubgraphRef 	Block02_01 = sc.Subgraph[11];
	SCSubgraphRef 	Block02_02 = sc.Subgraph[12];
	SCSubgraphRef 	Block02_03 = sc.Subgraph[13];
	SCSubgraphRef 	Block02_04 = sc.Subgraph[14];
	SCSubgraphRef 	Block02_05 = sc.Subgraph[15];
	SCSubgraphRef 	Block02_06 = sc.Subgraph[16];
	SCSubgraphRef 	Block02_07 = sc.Subgraph[17];
	SCSubgraphRef 	Block02_08 = sc.Subgraph[18];
	SCSubgraphRef 	Block02_09 = sc.Subgraph[19];
	SCSubgraphRef 	Block03_00 = sc.Subgraph[20];
	SCSubgraphRef 	Block03_01 = sc.Subgraph[21];
	SCSubgraphRef 	Block03_02 = sc.Subgraph[22];
	SCSubgraphRef 	Block03_03 = sc.Subgraph[23];
	SCSubgraphRef 	Block03_04 = sc.Subgraph[24];
	SCSubgraphRef 	Block03_05 = sc.Subgraph[25];
	SCSubgraphRef 	Block03_06 = sc.Subgraph[26];
	SCSubgraphRef 	Block03_07 = sc.Subgraph[27];
	SCSubgraphRef 	Block03_08 = sc.Subgraph[28];
	SCSubgraphRef 	Block03_09 = sc.Subgraph[29];
	SCSubgraphRef 	Block04_00 = sc.Subgraph[30];
	SCSubgraphRef 	Block04_01 = sc.Subgraph[31];
	SCSubgraphRef 	Block04_02 = sc.Subgraph[32];
	SCSubgraphRef 	Block04_03 = sc.Subgraph[33];
	SCSubgraphRef 	Block04_04 = sc.Subgraph[34];
	SCSubgraphRef 	Block04_05 = sc.Subgraph[35];
	SCSubgraphRef 	Block04_06 = sc.Subgraph[36];
	SCSubgraphRef 	Block04_07 = sc.Subgraph[37];
	SCSubgraphRef 	Block04_08 = sc.Subgraph[38];
	SCSubgraphRef 	Block04_09 = sc.Subgraph[39];
	SCSubgraphRef 	Block05_00 = sc.Subgraph[40];
	SCSubgraphRef 	Block05_01 = sc.Subgraph[41];
	SCSubgraphRef 	Block05_02 = sc.Subgraph[42];
	SCSubgraphRef 	Block05_03 = sc.Subgraph[43];
	SCSubgraphRef 	Block05_04 = sc.Subgraph[44];
	SCSubgraphRef 	Block05_05 = sc.Subgraph[45];
	SCSubgraphRef 	Block05_06 = sc.Subgraph[46];
	SCSubgraphRef 	Block05_07 = sc.Subgraph[47];
	SCSubgraphRef 	Block05_08 = sc.Subgraph[48];
	SCSubgraphRef 	Block05_09 = sc.Subgraph[49];
	SCSubgraphRef 	Block06_00 = sc.Subgraph[50];
	SCSubgraphRef 	Block06_01 = sc.Subgraph[51];
	SCSubgraphRef 	Block06_02 = sc.Subgraph[52];
	SCSubgraphRef 	Block06_03 = sc.Subgraph[53];
	SCSubgraphRef 	Block06_04 = sc.Subgraph[54];
	SCSubgraphRef 	Block06_05 = sc.Subgraph[55];
	SCSubgraphRef 	Block06_06 = sc.Subgraph[56];
	SCSubgraphRef 	Block06_07 = sc.Subgraph[57];
	SCSubgraphRef 	Block06_08 = sc.Subgraph[58];
	SCSubgraphRef 	Block06_09 = sc.Subgraph[59];



	if (sc.SetDefaults)
	{
		sc.GraphName = "Multi-Study History";

		sc.GraphRegion = 0;
		sc.ScaleRangeType = SCALE_SAMEASREGION;
		sc.UpdateAlways = 1;
		sc.AutoLoop = 1;

		sc.HideStudy = 0;

		// inputs

		// MiniVersion.Name = "Mini Version?";
		MiniVersion.SetYesNo(0);


		// Four OHLC Charts
		Block01StudyIDRef.SetDescription("Up to 6 chart/ID/SG values can be added to the list of for sorting in to subgraphs 0-9, 10-10, etc. It must also be enabled to be included in the sorted list.");


		Block01StudyIDRef.Name = "Select Chart # Study ID & SG for Block 1";
		Block02StudyIDRef.Name = "Select Chart # Study ID & SG for Block 2";
		Block03StudyIDRef.Name = "Select Chart # Study ID & SG for Block 3";
		Block04StudyIDRef.Name = "Select Chart # Study ID & SG for Block 4";
		Block05StudyIDRef.Name = "Select Chart # Study ID & SG for Block 5";
		Block06StudyIDRef.Name = "Select Chart # Study ID & SG for Block 6";


		Block01SortBy.Name = "Sort Block01 By Time or Value";
		Block02SortBy.Name = "Sort Block02 By Time or Value";
		Block03SortBy.Name = "Sort Block03 By Time or Value";
		Block04SortBy.Name = "Sort Block04 By Time or Value";
		Block05SortBy.Name = "Sort Block05 By Time or Value";
		Block06SortBy.Name = "Sort Block06 By Time or Value";

		//Block01SortBy.SetDescription("Sort By Time: Newest to Oldest (SG");

		//                                       Chart #, ID, SG-1

		Block01StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block01SortBy.SetCustomInputStrings("Time(Newest to Oldest); Value (Lowest to Highest)");
		Block01SortBy.SetCustomInputIndex(0);

		Block02StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block02SortBy.SetCustomInputStrings("Newest to Oldest; Highest to Lowest");
		Block02SortBy.SetCustomInputIndex(0);

		Block03StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block03SortBy.SetCustomInputStrings("Newest to Oldest; Highest to Lowest");
		Block03SortBy.SetCustomInputIndex(0);

		Block04StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block04SortBy.SetCustomInputStrings("Newest to Oldest; Highest to Lowest");
		Block04SortBy.SetCustomInputIndex(0);

		Block05StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block05SortBy.SetCustomInputStrings("Newest to Oldest; Highest to Lowest");
		Block05SortBy.SetCustomInputIndex(0);

		Block06StudyIDRef.SetChartStudySubgraphValues(1, 1, 0); 	// default 
		Block06SortBy.SetCustomInputStrings("Newest to Oldest; Highest to Lowest");
		Block06SortBy.SetCustomInputIndex(0);


		Block01SG01.SetDescription("These values will be output to Block 1 and the appropriate SG number. Note that Enable Block 1 should be set to 10 Manual Inputs.");
		Block01SG02.SetDescription("These values will be output to Block 2 and the appropriate SG number. Note that Enable Block 2 should be set to 10 Manual Inputs.");
		Block01SG03.SetDescription("These values will be output to Block 3 and the appropriate SG number. Note that Enable Block 3 should be set to 10 Manual Inputs.");
		Block01SG04.SetDescription("These values will be output to Block 4 and the appropriate SG number. Note that Enable Block 4 should be set to 10 Manual Inputs.");
		Block01SG05.SetDescription("These values will be output to Block 5 and the appropriate SG number. Note that Enable Block 5 should be set to 10 Manual Inputs.");
		Block01SG06.SetDescription("These values will be output to Block 6 and the appropriate SG number. Note that Enable Block 6 should be set to 10 Manual Inputs.");

		Block01SG01.Name = "Block01 SG01 Value";
		Block01SG02.Name = "Block01 SG02 Value";
		Block01SG03.Name = "Block01 SG03 Value";
		Block01SG04.Name = "Block01 SG04 Value";
		Block01SG05.Name = "Block01 SG05 Value";
		Block01SG06.Name = "Block01 SG06 Value";
		Block01SG07.Name = "Block01 SG07 Value";
		Block01SG08.Name = "Block01 SG08 Value";
		Block01SG09.Name = "Block01 SG09 Value";
		Block01SG10.Name = "Block01 SG10 Value";
		Block02SG01.Name = "Block02 SG01 Value";
		Block02SG02.Name = "Block02 SG02 Value";
		Block02SG03.Name = "Block02 SG03 Value";
		Block02SG04.Name = "Block02 SG04 Value";
		Block02SG05.Name = "Block02 SG05 Value";
		Block02SG06.Name = "Block02 SG06 Value";
		Block02SG07.Name = "Block02 SG07 Value";
		Block02SG08.Name = "Block02 SG08 Value";
		Block02SG09.Name = "Block02 SG09 Value";
		Block02SG10.Name = "Block02 SG10 Value";
		Block03SG01.Name = "Block03 SG01 Value";
		Block03SG02.Name = "Block03 SG02 Value";
		Block03SG03.Name = "Block03 SG03 Value";
		Block03SG04.Name = "Block03 SG04 Value";
		Block03SG05.Name = "Block03 SG05 Value";
		Block03SG06.Name = "Block03 SG06 Value";
		Block03SG07.Name = "Block03 SG07 Value";
		Block03SG08.Name = "Block03 SG08 Value";
		Block03SG09.Name = "Block03 SG09 Value";
		Block03SG10.Name = "Block03 SG10 Value";
		Block04SG01.Name = "Block04 SG01 Value";
		Block04SG02.Name = "Block04 SG02 Value";
		Block04SG03.Name = "Block04 SG03 Value";
		Block04SG04.Name = "Block04 SG04 Value";
		Block04SG05.Name = "Block04 SG05 Value";
		Block04SG06.Name = "Block04 SG06 Value";
		Block04SG07.Name = "Block04 SG07 Value";
		Block04SG08.Name = "Block04 SG08 Value";
		Block04SG09.Name = "Block04 SG09 Value";
		Block04SG10.Name = "Block04 SG10 Value";
		Block05SG01.Name = "Block05 SG01 Value";
		Block05SG02.Name = "Block05 SG02 Value";
		Block05SG03.Name = "Block05 SG03 Value";
		Block05SG04.Name = "Block05 SG04 Value";
		Block05SG05.Name = "Block05 SG05 Value";
		Block05SG06.Name = "Block05 SG06 Value";
		Block05SG07.Name = "Block05 SG07 Value";
		Block05SG08.Name = "Block05 SG08 Value";
		Block05SG09.Name = "Block05 SG09 Value";
		Block05SG10.Name = "Block05 SG10 Value";
		Block06SG01.Name = "Block06 SG01 Value";
		Block06SG02.Name = "Block06 SG02 Value";
		Block06SG03.Name = "Block06 SG03 Value";
		Block06SG04.Name = "Block06 SG04 Value";
		Block06SG05.Name = "Block06 SG05 Value";
		Block06SG06.Name = "Block06 SG06 Value";
		Block06SG07.Name = "Block06 SG07 Value";
		Block06SG08.Name = "Block06 SG08 Value";
		Block06SG09.Name = "Block06 SG09 Value";
		Block06SG10.Name = "Block06 SG10 Value";

		Block01SG01.SetFloat(0);
		Block01SG02.SetFloat(0);
		Block01SG03.SetFloat(0);
		Block01SG04.SetFloat(0);
		Block01SG05.SetFloat(0);
		Block01SG06.SetFloat(0);
		Block01SG07.SetFloat(0);
		Block01SG08.SetFloat(0);
		Block01SG09.SetFloat(0);
		Block01SG10.SetFloat(0);
		Block02SG01.SetFloat(0);
		Block02SG02.SetFloat(0);
		Block02SG03.SetFloat(0);
		Block02SG04.SetFloat(0);
		Block02SG05.SetFloat(0);
		Block02SG06.SetFloat(0);
		Block02SG07.SetFloat(0);
		Block02SG08.SetFloat(0);
		Block02SG09.SetFloat(0);
		Block02SG10.SetFloat(0);
		Block03SG01.SetFloat(0);
		Block03SG02.SetFloat(0);
		Block03SG03.SetFloat(0);
		Block03SG04.SetFloat(0);
		Block03SG05.SetFloat(0);
		Block03SG06.SetFloat(0);
		Block03SG07.SetFloat(0);
		Block03SG08.SetFloat(0);
		Block03SG09.SetFloat(0);
		Block03SG10.SetFloat(0);
		Block04SG01.SetFloat(0);
		Block04SG02.SetFloat(0);
		Block04SG03.SetFloat(0);
		Block04SG04.SetFloat(0);
		Block04SG05.SetFloat(0);
		Block04SG06.SetFloat(0);
		Block04SG07.SetFloat(0);
		Block04SG08.SetFloat(0);
		Block04SG09.SetFloat(0);
		Block04SG10.SetFloat(0);
		Block05SG01.SetFloat(0);
		Block05SG02.SetFloat(0);
		Block05SG03.SetFloat(0);
		Block05SG04.SetFloat(0);
		Block05SG05.SetFloat(0);
		Block05SG06.SetFloat(0);
		Block05SG07.SetFloat(0);
		Block05SG08.SetFloat(0);
		Block05SG09.SetFloat(0);
		Block05SG10.SetFloat(0);
		Block06SG01.SetFloat(0);
		Block06SG02.SetFloat(0);
		Block06SG03.SetFloat(0);
		Block06SG04.SetFloat(0);
		Block06SG05.SetFloat(0);
		Block06SG06.SetFloat(0);
		Block06SG07.SetFloat(0);
		Block06SG08.SetFloat(0);
		Block06SG09.SetFloat(0);
		Block06SG10.SetFloat(0);



		EnableBlock01Study.SetDescription("Block 1 controls SG 1-10. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");
		EnableBlock02Study.SetDescription("Block 2 controls SG 11-20. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");
		EnableBlock03Study.SetDescription("Block 3 controls SG 21-30. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");
		EnableBlock04Study.SetDescription("Block 4 controls SG 31-40. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");
		EnableBlock05Study.SetDescription("Block 5 controls SG 41-50. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");
		EnableBlock06Study.SetDescription("Block 6 controls SG 51-60. <br>Off: Outputs will be zero<br> Chart/ID/SG: Enter the Chart/ID/Subgraph of a study. Zeros will be ignored. The last 10 values of will be output sorted by Time or Value<br>10 manual inputs: Enter up to 10 Horizontal Lines per block.");


		EnableBlock01Study.Name = "Enable Block 1";
		EnableBlock01Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock01Study.SetCustomInputIndex(0);

		EnableBlock02Study.Name = "Enable Block 2";
		EnableBlock02Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock02Study.SetCustomInputIndex(0);

		EnableBlock03Study.Name = "Enable Block 3";
		EnableBlock03Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock03Study.SetCustomInputIndex(0);

		EnableBlock04Study.Name = "Enable Block 4";
		EnableBlock04Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock04Study.SetCustomInputIndex(0);

		EnableBlock05Study.Name = "Enable Block 5";
		EnableBlock05Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock05Study.SetCustomInputIndex(0);

		EnableBlock06Study.Name = "Enable Block 6";
		EnableBlock06Study.SetCustomInputStrings("Off; Chart/ID/SG; 10 Manual Inputs");
		EnableBlock06Study.SetCustomInputIndex(0);




		BarsToCalc.Name = "Bars to Output";
		BarsToCalc.SetInt(500);

		//DisplayTicks.Name = "Display S/R as Ticks";
		//DisplayTicks.SetYesNo(1);

		DebugMode.Name = "Debug Mode";
		DebugMode.SetYesNo(0);



		// Subgraphs
		Block01_00.Name = "Block01_00";
		Block01_01.Name = "Block01_01";
		Block01_02.Name = "Block01_02";
		Block01_03.Name = "Block01_03";
		Block01_04.Name = "Block01_04";
		Block01_05.Name = "Block01_05";
		Block01_06.Name = "Block01_06";
		Block01_07.Name = "Block01_07";
		Block01_08.Name = "Block01_08";
		Block01_09.Name = "Block01_09";
		Block02_00.Name = "Block02_00";
		Block02_01.Name = "Block02_01";
		Block02_02.Name = "Block02_02";
		Block02_03.Name = "Block02_03";
		Block02_04.Name = "Block02_04";
		Block02_05.Name = "Block02_05";
		Block02_06.Name = "Block02_06";
		Block02_07.Name = "Block02_07";
		Block02_08.Name = "Block02_08";
		Block02_09.Name = "Block02_09";
		Block03_00.Name = "Block03_00";
		Block03_01.Name = "Block03_01";
		Block03_02.Name = "Block03_02";
		Block03_03.Name = "Block03_03";
		Block03_04.Name = "Block03_04";
		Block03_05.Name = "Block03_05";
		Block03_06.Name = "Block03_06";
		Block03_07.Name = "Block03_07";
		Block03_08.Name = "Block03_08";
		Block03_09.Name = "Block03_09";
		Block04_00.Name = "Block04_00";
		Block04_01.Name = "Block04_01";
		Block04_02.Name = "Block04_02";
		Block04_03.Name = "Block04_03";
		Block04_04.Name = "Block04_04";
		Block04_05.Name = "Block04_05";
		Block04_06.Name = "Block04_06";
		Block04_07.Name = "Block04_07";
		Block04_08.Name = "Block04_08";
		Block04_09.Name = "Block04_09";
		Block05_00.Name = "Block05_00";
		Block05_01.Name = "Block05_01";
		Block05_02.Name = "Block05_02";
		Block05_03.Name = "Block05_03";
		Block05_04.Name = "Block05_04";
		Block05_05.Name = "Block05_05";
		Block05_06.Name = "Block05_06";
		Block05_07.Name = "Block05_07";
		Block05_08.Name = "Block05_08";
		Block05_09.Name = "Block05_09";
		Block06_00.Name = "Block06_00";
		Block06_01.Name = "Block06_01";
		Block06_02.Name = "Block06_02";
		Block06_03.Name = "Block06_03";
		Block06_04.Name = "Block06_04";
		Block06_05.Name = "Block06_05";
		Block06_06.Name = "Block06_06";
		Block06_07.Name = "Block06_07";
		Block06_08.Name = "Block06_08";
		Block06_09.Name = "Block06_09";

		for (int i = 0; i < 60; i++)
		{
			sc.Subgraph[i].DrawStyle = DRAWSTYLE_LINE;
			sc.Subgraph[i].LineWidth = 3;
			sc.Subgraph[i].PrimaryColor = RGB(0, 255, 0);
			sc.Subgraph[i].IncludeInStudySummary = 0;
		}





		return;
	}



	// Is User Allowed?
	if (sc.IsUserAllowedForSCDLLName == false)
	{
		if (sc.Index == 0)
		{
			sc.AddMessageToLog("You are not allowed to use this study", 1);
		}
		return;

	}

	//For safety we must never do any order management while historical data is being downloaded.
	if (sc.ChartIsDownloadingHistoricalData(sc.ChartNumber))
		return;

	if (sc.Index < sc.ArraySize - BarsToCalc.GetInt())
		return;

	// Persistent Variables
	int& skip = sc.GetPersistentInt(0);
	int& DistanceValue = sc.GetPersistentInt(1);
	int& LastLogMessageIdentifier = sc.GetPersistentInt(2);

	float& CurrentValue = sc.GetPersistentFloat(0);

	SCDateTime& LastAdjustmentDateTime = sc.GetPersistentSCDateTime(1);
	SCDateTime SCDateTimeVariable;


	// Only check once a second

	if (!sc.IsReplayRunning())
		LastAdjustmentDateTime = SCDateTimeVariable.GetTimeAsSCDateTime();
	else if (sc.IsReplayRunning())
		LastAdjustmentDateTime = sc.LatestDateTimeForLastBar;

	if (((sc.LatestDateTimeForLastBar - LastAdjustmentDateTime) < 1) && !sc.IsReplayRunning())
	{
		if (DebugMode.GetYesNo() && LastLogMessageIdentifier != 6)
		{
			LastLogMessageIdentifier = 6;
			sc.AddMessageToLog("Time interval has not elapsed yet for 'Every N Seconds'.", 0);
		}
		return;
	}

	if (sc.UpdateStartIndex == 0)
		LastLogMessageIdentifier = 0;


	//  Update the LastAdjustmentDateTime



	// Other declarations
	float TickOutput;

	SCFloatArray Block01Study;
	SCFloatArray Block02Study;
	SCFloatArray Block03Study;
	SCFloatArray Block04Study;
	SCFloatArray Block05Study;
	SCFloatArray Block06Study;


	// Retrieve chart/id/sg values
	sc.GetStudyArrayFromChartUsingID(Block01StudyIDRef.GetChartNumber(), Block01StudyIDRef.GetStudyID(), Block01StudyIDRef.GetSubgraphIndex(), Block01Study);
	sc.GetStudyArrayFromChartUsingID(Block02StudyIDRef.GetChartNumber(), Block02StudyIDRef.GetStudyID(), Block02StudyIDRef.GetSubgraphIndex(), Block02Study);
	sc.GetStudyArrayFromChartUsingID(Block03StudyIDRef.GetChartNumber(), Block03StudyIDRef.GetStudyID(), Block03StudyIDRef.GetSubgraphIndex(), Block03Study);
	sc.GetStudyArrayFromChartUsingID(Block04StudyIDRef.GetChartNumber(), Block04StudyIDRef.GetStudyID(), Block04StudyIDRef.GetSubgraphIndex(), Block04Study);
	sc.GetStudyArrayFromChartUsingID(Block05StudyIDRef.GetChartNumber(), Block05StudyIDRef.GetStudyID(), Block05StudyIDRef.GetSubgraphIndex(), Block05Study);
	sc.GetStudyArrayFromChartUsingID(Block06StudyIDRef.GetChartNumber(), Block06StudyIDRef.GetStudyID(), Block06StudyIDRef.GetSubgraphIndex(), Block06Study);




	int DrawingIndex = -1;
	//int Color;
	int Direction;
	//int LastBar = sc.UpdateStartIndex;
	int LastBar = sc.ArraySize - 1;

	float BeginVal;
	float EndVal;
	float MaxPrice;
	float MinPrice;
	float LastPrice = sc.BaseDataIn[SC_LAST][LastBar];

	int& CountHigh = sc.GetPersistentInt(0) = 0;
	int& CountHighTotal = sc.GetPersistentInt(1) = 0;
	int& CountLow = sc.GetPersistentInt(2) = 30;
	int& CountLowTotal = sc.GetPersistentInt(3) = 30;
	//int& p_MiniVersion = sc.GetPersistentInt(4) = MiniVersion.GetYesNo();

	unsigned int OutColor;

	double& GroupHigh = sc.GetPersistentDouble(0) = DBL_MAX;
	double& GroupLow = sc.GetPersistentDouble(1) = 0;







	// Get Study Values from other charts and colors from study settings

	//float StudyValues[10];
	float Value = 0;
	int CountNonZero;
	int StudyLastBar;
	int nodecountA;
	int nodecountB;
	int nodecountTemp;

	if (EnableBlock01Study.GetIndex() == 1 && Block01Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block01Study.GetArraySize() - 1;
		int i = 0;

		while (CountNonZero < 10 && i < Block01Study.GetArraySize())
		{
			Value = Block01Study[StudyLastBar - i];
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 1);
				CountNonZero++;
			}
			i++;
		}
		if (Block01SortBy.GetInt() == 1)
			quickSort(&Study01);
	}
	if (EnableBlock02Study.GetIndex() == 1 && Block02Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block02Study.GetArraySize() - 1;
		int i = 0;

		while (CountNonZero < 10 && i < Block02Study.GetArraySize())
		{
			Value = Block02Study[StudyLastBar - i];
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 2);
				CountNonZero++;
			}
			i++;
		}
		if (Block02SortBy.GetInt() == 1)
			quickSort(&Study02);
	}
	if (EnableBlock03Study.GetIndex() == 1 && Block03Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block03Study.GetArraySize() - 1;					// <-------------------- Change Here
		int i = 0;

		while (CountNonZero < 10 && i < Block03Study.GetArraySize())	// <-------------------- Change Here
		{
			Value = Block03Study[StudyLastBar - i];						// <-------------------- Change Here
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 3);				// <-------------------- Change Here
				CountNonZero++;
			}
			i++;

		}
		if (Block03SortBy.GetInt() == 1)
			quickSort(&Study03);
	}
	if (EnableBlock04Study.GetIndex() == 1 && Block04Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block04Study.GetArraySize() - 1;					// <-------------------- Change Here
		int i = 0;

		while (CountNonZero < 10 && i < Block04Study.GetArraySize())	// <-------------------- Change Here
		{
			Value = Block04Study[StudyLastBar - i];						// <-------------------- Change Here
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 4);				// <-------------------- Change Here
				CountNonZero++;
			}
			i++;
		}
		if (Block04SortBy.GetInt() == 1)
			quickSort(&Study04);
	}
	if (EnableBlock05Study.GetIndex() == 1 && Block05Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block05Study.GetArraySize() - 1;					// <-------------------- Change Here
		int i = 0;

		while (CountNonZero < 10 && i < Block05Study.GetArraySize())	// <-------------------- Change Here
		{
			Value = Block05Study[StudyLastBar - i];						// <-------------------- Change Here
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 5);				// <-------------------- Change Here
				CountNonZero++;
			}
			i++;

		}
		if (Block05SortBy.GetInt() == 1)
			quickSort(&Study05);
	}
	if (EnableBlock06Study.GetIndex() == 1 && Block06Study.GetArraySize() > 1)
	{
		CountNonZero = 0;
		StudyLastBar = Block06Study.GetArraySize() - 1;					// <-------------------- Change Here
		int i = 0;

		while (CountNonZero < 10 && i < Block06Study.GetArraySize())	// <-------------------- Change Here
		{
			Value = Block06Study[StudyLastBar - i];						// <-------------------- Change Here
			if (Value != 0)
			{
				InsertValueFromChartStudyID(sc, Value, 6);				// <-------------------- Change Here
				CountNonZero++;
			}
			i++;
		}
		if (Block06SortBy.GetInt() == 1)
			quickSort(&Study06);
	}

	if (EnableBlock01Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 31; i <= 40; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}
	if (EnableBlock02Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 41; i <= 50; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}
	if (EnableBlock03Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 51; i <= 60; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}
	if (EnableBlock04Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 61; i <= 70; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}
	if (EnableBlock05Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 71; i <= 80; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}
	if (EnableBlock06Study.GetIndex() == 2)
	{
		// Loop through inputs and copy to outputs
		for (int i = 81; i <= 90; i++)
			sc.Subgraph[i - 31][sc.Index] = sc.Input[i].GetFloat();
	}

	if (DebugMode.GetYesNo())
	{
		sc.AddMessageToLog("Linked List Study01 after sorting", 0);
		printList(sc, Study01);

		sc.AddMessageToLog("Linked List Study02 after sorting", 0);
		printList(sc, Study02);

		sc.AddMessageToLog("Linked List Study03 after sorting", 0);
		printList(sc, Study03);

		sc.AddMessageToLog("Linked List Study04 after sorting", 0);
		printList(sc, Study04);

		sc.AddMessageToLog("Linked List Study05 after sorting", 0);
		printList(sc, Study05);

		sc.AddMessageToLog("Linked List Study06 after sorting", 0);
		printList(sc, Study06);


	}

	nodecountA = countnodes(Study01);


	// Assign to  subgraphs 10 at a time

	for (int i = 9; i >= 0; i--)
	{
		if (EnableBlock01Study.GetYesNo())
		{
			if (Study01 != NULL)
			{
				sc.Subgraph[i][sc.Index] = Study01->data;
				Study01 = Study01->next;
			}
		}


		if (EnableBlock02Study.GetYesNo())
		{
			if (Study02 != NULL)
			{
				sc.Subgraph[10 + i][sc.Index] = Study02->data;
				Study02 = Study02->next;
			}
		}

		if (EnableBlock03Study.GetYesNo())
		{
			if (Study03 != NULL)
			{
				sc.Subgraph[20 + i][sc.Index] = Study03->data;
				Study03 = Study03->next;
			}
		}

		if (EnableBlock04Study.GetYesNo())
		{
			if (Study04 != NULL)
			{
				sc.Subgraph[30 + i][sc.Index] = Study04->data;
				Study04 = Study04->next;
			}
		}

		if (EnableBlock05Study.GetYesNo())
		{
			if (Study05 != NULL)
			{
				sc.Subgraph[40 + i][sc.Index] = Study05->data;
				Study05 = Study05->next;
			}
		}

		if (EnableBlock06Study.GetYesNo())
		{
			if (Study06 != NULL)
			{
				sc.Subgraph[50 + i][sc.Index] = Study06->data;
				Study06 = Study06->next;
			}
		}
	}



	// cleanup
	deleteList(&Study01);
	deleteList(&Study02);
	deleteList(&Study03);
	deleteList(&Study04);
	deleteList(&Study05);
	deleteList(&Study06);


	//nodecountA = countnodes(AboveMarket);
	//nodecountB = countnodes(BelowMarket);
	//nodecountTemp = countnodes(TempNode);
	//int dtemp;
	//if (nodecountA)
	//	dtemp = 0;


}
