//######################
// This library is for use with IndexGroupControl and IndexInstrumentPage.
// Both of which are in the FinancialExpress.CoreV22.BusinessUI.IndexControl namespace.
//###############################

/********** IndexGroups Class ***********/
function IndexGroups()
{
	this.Ready = false;
	this.Groups = [];
	return this;
}

// Initializes the IndexGroups object.
IndexGroups.prototype.Initialize = function(chartSpan, chartLink)
{
	this.ChartLink = chartLink.replace(/&amp;/g, '&');
	this.Form = this.GetForm();
		
	var groupCodes = this.GetGroupCodes();
	
	this.Ready = true;
		
	for (var i = 0; i < groupCodes.length; i++)
	{
		this.Add(groupCodes[i]);
	}

	this.SetSelectedGroup(groupCodes[0]);
	this.SetChartSpan(chartSpan);
}

// Gets a reference to the form in the page.
// Over-ride this method if required.
IndexGroups.prototype.GetForm = function()
{
	return document.forms[0];
}

// Returns an array of tab group codes from the IndexGroupControls on the page.
// Note that the ids of the controls must be of the form: Tab<Group>Group.
IndexGroups.prototype.GetGroupCodes = function()
{
	var res = [];
	var divs = document.getElementsByTagName('DIV');
	
	for (var i = 0; i < divs.length; i++)
	{
		var divId = divs[i].id;
		if (divId.indexOf('Tab') == 0 && divId.indexOf('Group') == divId.length - 5)
		{
			res.push(divId.substr('Tab'.length, divId.length - 'TabGroup'.length));
		}
	}
	
	if (res.length == 0)
	{
		alert('No IndexGroupControls could be found with required id attribute of the form: Tab<Group>Group.');
	}
	
	return res;
}

// Sets the selected tab group control denoted by the groupCode supplied.
IndexGroups.prototype.SetSelectedGroup = function(groupCode)
{
	if (!this.Ready)
	{
		return;
	}
	
	var group = this.Groups[groupCode];
	if (group == null)
	{
		alert('There is no group defined with code "' + groupCode + '".');
		return;
	}
	
	for (var code in this.Groups)
	{
		var grp = this.Groups[code];
		if (grp != null && grp.Show != null)
		{
			grp.Show(grp == group);
		}
	}
	
	this.m_SelectedGroup = groupCode;
	
}

// Gets the selected tab group.
IndexGroups.prototype.GetSelectedGroup = function()
{
	return this.m_SelectedGroup;
}

// Sets the chart span for all tab groups.
IndexGroups.prototype.SetChartSpan = function(chartSpan)
{
	if (!this.Ready)
	{
		return;
	}
	
	this.m_ChartSpan = chartSpan;
	for (var code in this.Groups)
	{
		var group = this.Groups[code];
		if (group != null && group.GroupCode != null)
		{
			group.RenderChart(chartSpan);
		}
	}
}

// Gets the chart span for all tab groups.
IndexGroups.prototype.GetChartSpan = function()
{
	return this.m_ChartSpan;
}

// Adds an IndexGroup to this instance.
IndexGroups.prototype.Add = function(groupCode)
{
	var group = new IndexGroup(this, groupCode);
	this.Groups[groupCode] = group;
	group.SetChartCode(null);
}

// Selects the tab group denoted by the groupCode supplied.
IndexGroups.prototype.SelectGroup = function(groupCode)
{
	var group = this.Groups[groupCode];
}

// Sets the chart code.
IndexGroups.prototype.SetChartCode = function(chartCode)
{
	if (!this.Ready)
	{
		return;
	}
	
	var group = this.Groups[this.m_SelectedGroup];
	if (group != null)
	{
		group.SetChartCode(chartCode);
	}
}

/********** IndexGroup Class ***********/

// Creates a new IndexGroup object.
function IndexGroup(indexGroups, groupCode)
{
	this.GroupCode = groupCode;
	var codeList = indexGroups.Form[groupCode + 'Codes'];
	if (codeList == null || codeList.value == '')
	{
		alert('Expected to find a hidden field named "' + groupCode + 'Codes" which contains a list of index codes.');
		return;
	}
	this.Codes = codeList.value.split(',');
	this.SelectedCode = 0;
	this.Parent = indexGroups;
	this.Form = indexGroups.Form;
	this.Panel = document.getElementById('Tab' + groupCode + 'Group');
	this.Chart = document.getElementById('Chart' + groupCode + 'Group');
	this.ChartSpans = this.GetChartSpans();
	return this;
}

// Shows the current tab.
IndexGroup.prototype.Show = function(show)
{
	this.Panel.style.display = show ? 'block' : 'none';
}

// Sets the chart code for the current tab group.
IndexGroup.prototype.SetChartCode = function(chartCode)
{
	var indexOfCode = 0;
	if (chartCode != null)
	{
		indexOfCode = this.Codes.indexOf(chartCode);
		if (indexOfCode == -1)
		{
			alert('Unable to find code "' + chartCode + '" for group "' + this.GroupCode + '".');
			return;
		}
	}
	this.SelectedCode = indexOfCode;
	this.RenderChart();
}

// Renders the chart as well as updating the selected index name and chart span.
IndexGroup.prototype.RenderChart = function(chartSpan)
{
	if (chartSpan == null)
	{
		chartSpan = this.Parent.GetChartSpan();
	}
	
	var chartSpan = this.HighlightChartSpanName(chartSpan);
	var chartSource = this.Parent.ChartLink.replace('{Code}', this.Codes[this.SelectedCode]).replace('{Span}', chartSpan).replace('{Group}', this.GroupCode);
	this.Chart.src = chartSource;
	this.HighlightIndexName();
}

// Highlights the name of the currently selected Index.
IndexGroup.prototype.HighlightIndexName = function()
{
	for (var i = 0; true; i++)
	{
		var id = 'Index' + this.GroupCode + (i + 1);
		var nameNode = document.getElementById(id);
		if (nameNode == null)
		{
			break;
		}
		this.SetSelected(nameNode, this.SelectedCode == i);
	}
}

// Gets an array of chart span anchor elements applicable to the current tab group.
IndexGroup.prototype.GetChartSpans = function()
{
	var tmp = [];
	var els = document.getElementsByTagName('A');
	
	for (var i = 0; i < els.length; i++)
	{
		var el = els[i];
		if (el.id != null && el.id.indexOf('Span' + this.GroupCode) == 0)
		{
			tmp.push(el);
		}
	}
	
	return tmp;
}

// Highlights the chart span as supplied in the parameter.
// If that one can't be selected, adds the one closest to it.
IndexGroup.prototype.HighlightChartSpanName = function(chartSpan)
{
	var spanFound = -1;
	
	for (var i = 0; i < this.ChartSpans.length; i++)
	{
		var span = this.ChartSpans[i];
		var selected = span.id == 'Span' + this.GroupCode + chartSpan;
		if (selected)
		{
			spanFound = i;
		}
		this.ChartSpans[i].className = '';
	}
	
	if (spanFound == -1)
	{
		spanFound = this.SelectClosestSpan(chartSpan);
	}
	
	this.SetSelected(this.ChartSpans[spanFound], true);
	var spanSet = this.ChartSpans[spanFound].id.substring('Span'.length + this.GroupCode.length);
	return spanSet;
}

// Return the zero-based index of the span closest to that which is not available for this tab.
IndexGroup.prototype.SelectClosestSpan = function(chartSpan)
{
	return 0;
}

// Sets the selected node to be active/inactive depending on the boolean isSelected paramter.
// Over-ride this method as required if the functionality doesn't suit your implementation.
IndexGroup.prototype.SetSelected = function(node, isSelected)
{
	node.className = isSelected ? 'Selected' : '';
}
