/*IS 449 Group Project
Written by; Anthony Taylor*/
// Create request variable
var xmlhttp;
// Create companyId arrary to store company objects
var companyId = new Array();
// Declare url variable storing Ryan's pass-through proxy
var url="http://people.emich.edu/rvandael/449.php";
var companySearch="?company=";
var newLabelOrder = new Array(); 
var newValueOrder = new Array();
// Constructor defining company objects
function company(compId, compName, formType)
{
	this.id=compId;
	this.name=compName;
	this.type=formType;
}
// Find a corresponding id for a company
function findId(input)
{
	// Declare variable that will store value to return
	var idNum;
	// Iterate through company id array until the first instance of
	//		the company is located then return the id
	for(i=0; i<companyId.length; i++)
	{
		if(input==companyId[i].name)
		{
			idNum=companyId[i].id;
			return idNum;
		}
	}
}
// Load an XML document
function loadXMLDoc()
{
	// Determine browser type for specific request object
	browserObjCheck();
	// Object type identified
	if (xmlhttp!=null)
	{
		// Update page when ready
		xmlhttp.onreadystatechange=state_Change;
		xmlhttp.open("GET", url, true);
		xmlhttp.send(null);
	}
	// Alert user request object is null
	else
	{
		alert("  Your browser does not support XMLHTTP.  ");
	}
}
// Determine type of request object needed based on browser
function browserObjCheck()
{
	// Mozilla, Safari, etc.
	if (window.XMLHttpRequest)
	{
		 xmlhttp = new XMLHttpRequest();
	}
	// Microsoft
	else if (window.ActiveXObject)
	{
		try
		{
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(otherMicrosoft)
		{
			xmlhttp = new ActiveXObject("Msxm12.XMLHTTP");
		}
	}	
}
// We got a response
function state_Change()
{
	var temp;
	// if xmlhttp shows "loaded"
	if (xmlhttp.readyState==4)
	{
		// if "OK"
		if (xmlhttp.status==200)
		{
			// Store response as xml
			xml=xmlhttp.responseXML;
			temp=xml.getElementsByTagName("webfinancial");

			// Determine what was loaded
			// Free up memory
			if(temp[0].hasChildNodes())
			{
				switch(temp[0].childNodes[0].nodeName)
				{
					case "company":	companyLoad(temp[0].getElementsByTagName("company")); xml=null; temp=null; xmlhttp=null; break;
					case "filing":	financialData(temp[0].getElementsByTagName("filing")); xml=null; temp=null; xmlhttp=null; break;
					default: alert(" Problem retrieving XML data: " + xmlhttp.statusText); xml=null; temp=null; xmlhttp=null; break;
				}
			}
			else
			{
				alert(" Data not available, please choose another company");
			}
		}
		else
		{
			// Alert user that xml data was not retrieved
			alert(" Problem retrieving XML data: " + xmlhttp.statusText);
		}
	}
}
// Load retrieved data into companyId array
function companyLoad(data)
{
	// Use tempData to store each company object
	var tempData = new Object();
	// Traverse node tree and store data into array
	for(i=0;i<data.length;i++)
	{
		// Get each company's id, name, and form type available
		compId=data[i].getElementsByTagName("id");
		compId=compId[0].childNodes[0].nodeValue;
		compName=data[i].getElementsByTagName("name");
		compName=compName[0].childNodes[0].nodeValue;
		formType=data[i].getElementsByTagName("type");
		formType=formType[0].childNodes[0].nodeValue;
		// Load array with company objects
		tempData=new company(compId,compName,formType);
		companyId[i]=tempData;
	}
	companyList();
}
// Display financial summary and compute/display financial ratios
function financialData(filings)
{
	var label = new Array(); var labelVal = new Array();
	var temp, temp1, temp2, temp3, pDate, date;
	var counter = 0;
	
	for(i=1;i<=filings.length;i++)
	{		
		// Read in company elements
		temp=filings[0].childNodes[i];
		
		//alert(" temp.nodeName: " + temp.nodeName);
		if(temp!=undefined)
		{
			temp1=temp.nodeName;
			
			if(labelCheck(temp1))
			{
				temp2=temp.childNodes[0].nodeValue;
		
				// Store elements and values in temporary variables
				if(temp1=="period")
				{
					pDate=temp.childNodes[1];
			
					switch(pDate.nodeName)
					{
						case "instant": date=pDate.childNodes[0].nodeValue; break;
						case "startDate": date=pDate.childNodes[1].nodeValue; break;
						default: break;
					}
				}
				else
				{
					Ptemp=filings[1].getElementsByTagName(temp1);
					temp3=Ptemp[0].childNodes[0].nodeValue;
				}
			}
		}
		// Load temporary variables into corresponding arrays
		if(temp1!="period"&&labelCheck(temp1))
		{
			label[i]=temp1;
			counter=i*2;
			labelVal[counter]=temp2;
			counter++;
			labelVal[counter]=temp3;
		}
	}
	//sortLabels(label, labelVal)
	create3ColTable(label, labelVal, false, "compTbl", "compList");

	label=null; labelVal=null;
	temp=null; temp1=null; temp2=null; pDate=null; date=null;
}
// Dynamically create a table
function create3ColTable(tags, values, hasLinks, tbleClassId, tdClassId)
{
	var tables = document.getElementsByTagName("table");
	var theContainer = document.getElementById("tableContainer");
 
	if(tables.length > 0)
	{
		// Delete previous table
		document.getElementById("displayTable").parentNode.removeChild(document.getElementById("displayTable"));
	}

	var theTable = document.createElement("table");
	theTable.id = "displayTable";
	theTable.className = tbleClassId;
	var theTBody = document.createElement("tbody");
	var theRow, theCell, hyperLink, idLink;
	var temp1, temp2, temp3=null;
	var counter=0;
	
	if(!hasLinks)
	{
		formatLabels(tags);
		formatNumbers(values);
	}
	// Create and insert rows and cells into the body.
	for(index1=0; index1<=values.length; index1++)
	{
		if(hasLinks)
		{
			// Store values in temp variables for each cell to be displayed
			switch(counter)
			{
				case 0:	temp1=values[index1]; counter++; break;
				case 1: temp2=values[index1]; counter++; break;
				case 2:	temp3=values[index1]; counter++; break;
				default: break;
			}
		}
		else
		{
			temp1=tags[index1]; counter=index1*2;
			temp2=values[counter]; counter++;
			temp3=values[counter];
		}
		// Once temp variables have values, add values to table cells
		// In case total number of companies are not a multiple of 3, 
		// 	  run a final check for remaining values in values array
		// Make sure all companies are loaded
	  	if(temp1!=null && temp2!=null && temp3!=null || index1==values.length)
	  	{
			// If either temp2 or temp3 variable is null, store an empty string
			if(temp2==null){ temp2=" "; } if(temp3==null){ temp3=" "; }
			// Create a new row in the table
			theRow = document.createElement("tr");
			// Iterate 3 times to add 3 cells
			for (index2=0; index2<3; index2++)
		  	{
				// Create table data elements (cells)
				theCell = document.createElement("td");
				theCell.className = tdClassId;
				// If the table has hyperLinks; append anchor elements to the DOM
				if(hasLinks)
				{
					// Return the corresponding id for the selected company
					switch(index2)
					{
						case 0: idLink=findId(temp1); break; case 1: idLink=findId(temp2); break;
						case 2: idLink=findId(temp3); break; default: break;
					}
					// Create an anchor element and set the attribute
					hyperLink = document.createElement("a");
					hyperLink.setAttribute("href", "javascript:showSummary("+idLink+");");
					//hyperLink.setAttribute("onclick", showSummary(idLink));
					// Append text node to hyperLink
					switch(index2)
					{
						case 0: hyperLink.appendChild(document.createTextNode(temp1)); break;
						case 1: hyperLink.appendChild(document.createTextNode(temp2)); break;
						case 2: hyperLink.appendChild(document.createTextNode(temp3)); break;
						default: break;
					}
					// Append hyperLink to table data element (cell)
					theCell.appendChild(hyperLink);
				}
				else
				{
					// Create text nodes for each table data element
					switch(index2)
					{
						case 0: txtNode = document.createTextNode(temp1); break;
					  	case 1: txtNode = document.createTextNode(temp2); break;
					  	case 2: txtNode = document.createTextNode(temp3); break;
					  	default: break;
					}
					// Append the text node to the table data element (cell)
					theCell.appendChild(txtNode);
				}
				// Append the table data element (cell) to the row
				theRow.appendChild(theCell);
			}
			// Append each row to the table body element
			theTBody.appendChild(theRow);
			// Reset temp variables and counter
			temp1=null;temp2=null;temp3=null;counter=0;
		}
	}
	// Append the table body to the table
	theTable.appendChild(theTBody);
	// Insert the table into the document tree.
	theContainer.appendChild(theTable);
}
// Add company names to drop down list
function companyList()
{
	var numOfComp = new Array;
	var nameOfComp = new Array;
	var temp="first time around";
	var index=0;
	
	// Store unique company names for display
	for(a=0; a<companyId.length; a++)
	{
		// Perform these actions only if a unique company name
		// Always enter loop the first time around
		if(temp!=companyId[a].name || a==0)
		{
			if(companyId[a].name!="Old Mutual Advisor Funds")
			{
				nameOfComp[index]=companyId[a].name;
				temp=companyId[a].name;
				index++;
			}
		}
	}
	// Count and record the number of company names stored
	for(b=0; b<nameOfComp.length; b++)
	{
		numOfComp[b]=companyId[b].id;
	}
	// Display company names dynamically
	create3ColTable(numOfComp, nameOfComp, true, "compTbl","compList");
	// Free up memory
	numOfComp=null; nameOfComp=null; temp=null; index=null;
}
// New filing date was selected
function showSummary(identifier)
{
	var newURL=url+companySearch+identifier;
	// Determine browser type for specific request object
	browserObjCheck();
	// Update page when ready
	xmlhttp.onreadystatechange=state_Change;
	xmlhttp.open("GET", newURL, true);
	xmlhttp.send(null);
}
function formatNumbers(temp)
{
	var str, str1, str2, abbr;
	
	for(index=0;index<temp.length;index++)
	{
		str = String(temp[index]);
		str1 = String(temp[index]); str2 = String(temp[index]);
		
		
		
		switch(String(temp[index]).length)
		{
			case 0: case 1: case 2: case 3: case 4: case 5: case 6: break;
			case 7: abbr = str.substring(0,1); break;
			case 8: abbr = str.substring(0,2); break;
			case 9: abbr = str.substring(0,3); break;
			case 10: abbr = str1.slice(0,1)+","+str2.slice(1,4); break;
			case 11: abbr = str1.slice(0,2)+","+str2.slice(2,5); break;
			case 12: abbr = str1.slice(0,3)+","+str2.slice(3,6); break;
			default: break;
		}
		temp[index] = abbr;
	}
}
function formatLabels(temp)
{
	var oldLabel;
	
	for(index=0;index<temp.length;index++)
	{
		oldLabel = temp[index];
		switch(oldLabel)
		{
			case "NetIncome": temp[index] = "Net Income"; break;
			case "TotalCurrentAssets": temp[index] = "Current Assets"; break;
			case "Assets": temp[index] = "Total Assets"; break;
			case "CurrentLiabilities": temp[index] = "Current Liabilities"; break;
			case "Liabilities": temp[index] = "Total Liabilities"; break;
			case "StockholdersEquity": temp[index] = "Stockholders Equity"; break;
			default: break;
		}
	}
}
// Print financial summary information to the screen
function sortLabels(temp1, temp2)
{
	var preferredOrder = new Array("NetIncome", "TotalCurrentAssets","Assets","CurrentLiabilities",
								   "Liabilities","StockholdersEquity");
	var count1, count2 = 0;
	
	for(index1=0;index1<preferredOrder.length;index1++)
	{
		for(index2=0;temp1[index2]!=preferredOrder[index1]&&index2<50;index2++)
		{
			if(temp1[index2]==preferredOrder[index1])
			{
				newLabelOrder[index1]=preferredOrder[index1];
				count1=index1*2; count2=index2*2;
				newValueOrder[count1]=temp2[count2];
				count1++; count2++;
				newValueOrder[count1]=temp2[count2];
			}
		}
	}
}
function labelCheck(labelProvided)
{
	switch(labelProvided)
	{
		case "NetIncome": case "TotalCurrentAssets": case "Assets": case "CurrentLiabilities": return true;
		case "Liabilities": case "StockholdersEquity": case "period":
		return true;
		default: return false;
	}
}
// Get values returned from the server and print ratios to screen
function finAnalysis(x)
{
	var LongTermDebt, StockholdersEquity, Liabilities, Assets, IncomeLossContinuingOperationsBeforeIncomeTaxes,
	TotalDepreciationAmortization, AdjustmentDepreciationAmortization, InterestIncomeExpenseNet,
	TotalCurrentAssets, CurrentLiabilities, CashCashEquivalentsShortTermInvestments, ReceivablesNet,
	OperatingRevenue, NetIncome, InterestExpense = null;

	var count = 0;
	
	for(a=0;a<x[0].childNodes.length;a++)
	{
		// Get each individual label in list
		elementName=x[0].childNodes[a].nodeName;
		// Get values for each label
		elementValue=x[0].getElementsByTagName(elementName);
		elementValue=elementValue[0].childNodes[0].nodeValue;

		switch(elementName)
		{
			case "LongTermDebt": LongTermDebt=elementValue; break;
			case "StockholdersEquity": StockholdersEquity=elementValue; break;
			case "Liabilities": Liabilities=elementValue; break;
			case "Assets": Assets=elementValue; break;
			case "IncomeLossContinuingOperationsBeforeIncomeTaxes": IncomeLossContinuingOperationsBeforeIncomeTaxes=elementValue; break;
			case "TotalDepreciationAmortization": TotalDepreciationAmortization=elementValue; break;
			case "AdjustmentDepreciationAmortization": AdjustmentDepreciationAmortization=elementValue; break;
			case "InterestIncomeExpenseNet": InterestIncomeExpenseNet=elementValue; break;
			case "TotalCurrentAssets": TotalCurrentAssets=elementValue; break;
			case "CurrentLiabilities": CurrentLiabilities=elementValue; break;
			case "CashCashEquivalents":
			case "CashCashEquivalentsShortTermInvestments": CashCashEquivalentsShortTermInvestments=elementValue; break;
			case "AccountsReceivableTradeNet":
			case "AccountsNotesReceivableNet":
			case "ReceivablesNet": ReceivablesNet=elementValue; break;
			case "OperatingRevenue": OperatingRevenue=elementValue; break;
			case "NetIncome": NetIncome=elementValue; break;
			case "MinorityInterestNetTaxEffect":
			case "InterestExpense": InterestExpense=elementValue; break;
			default: break;
		}
	}
	
	
	
	// Compute Financial Ratios
	DebtToEquity(LongTermDebt, StockholdersEquity);
	TotalDebt(Liabilities, Assets);
	CurrentRat(TotalCurrentAssets, CurrentLiabilities);
	QuickRat(CashCashEquivalentsShortTermInvestments, ReceivablesNet, CurrentLiabilities);
	CashRat(CashCashEquivalentsShortTermInvestments, CurrentLiabilities);
	OPM(NetIncome, InterestExpense, OperatingRevenue);

	return 0;
}
// determine Debt to Equity ratio
function DebtToEquity(a, b)
{
	if(a==null || b==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// long term debt / stockholders equity
		d2er = a/b;
		return d2er;
	}
}

// determine Total Debt ratio
function TotalDebt(c, d)
{
	if(c==null || d==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// total liabilities / total assets
		tdr = c/d;
		return tdr;
	}
}
// determine Current Ratio
function CurrentRat(h, i)
{
	if(h==null || i==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// current assets / current liabilities
		crrntr = h/i;
		return crrntr;
	}
}
// determine Quick Ratio
function QuickRat(j, k, l)
{
	if(j==null || k==null || l==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// (cash + marketable securities + receivables) / current liabilities
		qckr = (j + k)/l;
		return qckr;
	}
}
// determine Cash Ratio
function CashRat(m, n)
{
	if(m==null || n==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// (cash + marketable securities) / current liabilities
		cshr = (m)/n;
		return cshr;
	}
}
// determine Operating profit margin
function OPM(o, p, q)
{
	if(o==null || p==null || q==null)
	{
		var emptyChar = "-";
		return emptyChar;
	}
	else
	{
		// (net income + interest) / sales
		opm = (o + p)/q;
		return opm;
	}
}
