//Add trim functionality to String object
String.prototype.trim = function (){return this.replace(/^\s*/, "").replace(/\s*$/, "");}

//global variables
var m_PageSize
var m_QueryXML
var m_ResultsXML
var m_TotalResults
var m_TotalPages
var m_Source

function GuidestarSearch()
{
	//Initialize Variables
	m_PageSize = 10
	m_QueryXML = ""
	m_ResultsXML = ""
	m_TotalResults = 0
	m_TotalPages = 0
	m_Source = ""
		
	//Properties
	this.PageSize = PageSize
	this.QueryXML = QueryXML
	this.ResultsXML = ResultsXML
	this.TotalResults = TotalResults
	this.TotalPages = TotalPages
	this.Source = Source

	//Methods
	this.SearchGuidestar = SearchGuidestar
	this.LookupEIN = LookupEIN
	this.SetPageSize = SetPageSize
}

/*************************************************************************/
//Properties
function PageSize(){return m_PageSize}
function QueryXML(){return m_QueryXML}
function ResultsXML(){return m_ResultsXML}
function TotalResults(){return m_TotalResults}
function TotalPages(){return m_TotalPages}
function Source(){return m_Source}


/*************************************************************************/
//Methods

function SearchGuidestar(sKey, sOrg, sCity, sStateAbbrev, sStateFull, nPageNo)
{
	m_ResultsXML = ExecAjax("", "", sKey, sOrg, sCity, sStateAbbrev, sStateFull, nPageNo)
	if(m_ResultsXML.indexOf("###GUIDESTAR ERROR###") >= 0) return new Array (m_ResultsXML)
	else return ParseResultsXML(true)
	//else return new Array(m_ResultsXML.replace(/</g, "&lt;"))
}

/*************************************************************************/

function LookupEIN(sEIN)
{
	m_ResultsXML = ExecAjax("", "EIN", sEIN, "", "", "", "", 0)
	if(m_ResultsXML.indexOf("###GUIDESTAR ERROR###") >= 0) return new Array(m_ResultsXML)
	else return ParseResultsXML(true)
}

/*************************************************************************/

function GetRestrictedEINs()
{
	var sRet = ExecAjax("exceptions", "", "", "", "", "", "", 0)
	return sRet
}

/*************************************************************************/

function SetPageSize(newsize)
{
	m_PageSize = newsize
	CalcPages()
}

/*************************************************************************/
//Helper functions

function ExecAjax(sAction, sSearchType, sKey, sOrg, sCity, sStateAbbrev, sStateFull, nPageNo)
{
	var xmlHttp;
	
	var sQueryString = "action=" + sAction
	sQueryString += "&searchtype=" + sSearchType
	sQueryString += "&key=" + sKey
	sQueryString += "&orgname=" + sOrg
	sQueryString += "&city=" + sCity
	sQueryString += "&stateabbrev=" + sStateAbbrev
	sQueryString += "&statefull=" + sStateFull
	sQueryString += "&pageno=" + nPageNo
	sQueryString += "&pagesize=" + m_PageSize
	
	//Mozilla/Opera/Safari		 
	if (window.XMLHttpRequest)
		xmlHttp = new XMLHttpRequest();
	//IE (5, 6, 7)
	else if (window.ActiveXObject)
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	
	//verift that we have successfully instantiated an xml http request
	if (xmlHttp != null) {
		//open connection for synchronous processing
		xmlHttp.open("POST", "/Guidestar/Server/Guidestar.ashx", false);
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttp.send(sQueryString);
	}
	
	//make sure the status is "success"
	if (xmlHttp.status == 200 && xmlHttp.responseText) 
	{
		return xmlHttp.responseText;
	}
	else 
	{
		return "###GUIDESTAR ERROR###" + xmlHttp.responseText
	}
}

/*************************************************************************/

function ParseResultsXML(bSort)
{
	if(m_ResultsXML == "") return null
	
	var xmldoc;
	var arrRet = new Array()
	
	//Get restricted list
	var sExcludedList = GetRestrictedEINs()
	
	//Get an XML DOM object
	try
	{// code for IE
		xmldoc=new ActiveXObject("Microsoft.XMLDOM");
		xmldoc.async="false";
		xmldoc.loadXML(m_ResultsXML);
	}
	catch(e)
	{// code for Mozilla, Firefox, Opera, etc.
		try
		{
			var parser=new DOMParser();
			xmldoc=parser.parseFromString(m_ResultsXML,"text/xml");
		}
		catch(e)
		{
			return "ERROR";
		}
	}
	
	//get the source
	var node  = xmldoc.getElementsByTagName("source")[0]
	if(node)
	{
		m_Source = getNodeValue(node);
	}
	else
	{
		m_Source = "Guidestar"
	}
	
	//Get total results and calulate number pages
	m_TotalResults = getNodeValue(xmldoc.getElementsByTagName("totalResults")[0]);	
	CalcPages();
		
	//Get organizations
	arrOrgs = xmldoc.getElementsByTagName("organization")
	str = ""
	
	var nExcluded = 0
	var nIndex = 0
	
	for(x=0; x < arrOrgs.length; x++)
	{
		var oOrg = new Organization()
		var xmlbit = arrOrgs[x]
		oOrg = GetOrgInfo(xmlbit)
		if(sExcludedList.indexOf(oOrg.EIN) < 0)
		{
			arrRet[nIndex] = oOrg
			nIndex++
		}
		else
		{
			nExcluded++
		}
	}

	//if any results were exluded, adjust total count and page count accordingly	
	if(nExcluded > 0)
	{
		m_TotalResults -= nExcluded
		CalcPages()
	}
	
	//Sort if required
	//if(bSort){arrRet.sort(sortOrgs)}

	return arrRet
}

/*************************************************************************/

function sortOrgs(org1, org2)
{
	var retval = 0
	
	name1 = org1.OrgName.toUpperCase()
	name1 = name1.trim()
	
	name2 = org2.OrgName.toUpperCase()
	name2 = name2.trim()	
	
	if(name1 < name2){retval = -1}
	if(name1 == name2){retval = 0}
	if(name1 > name2){retval = 1}
	
	return retval
}

/*************************************************************************/

function GetOrgInfo(xml)
{
	//root variable is not the root of the document, merely a placeholder 
	//for the currentl level in the document.
	
	//Keep in mind that in Javascript, every node has a child node called #text
	//that contains the actual data for the node
	
	var org = new Organization()
	
	//start at the top...
	var root = xml
	
	org.ResultPosition = getNodeValue(xml.childNodes[0])
	
	//set to the generalInformation branch
	root = xml.childNodes[1]
	
	org.OrgName = getNodeValue(root.childNodes[0])
	org.EIN = getNodeValue(root.childNodes[1])
	
	//set to address
	root = xml.childNodes[1].childNodes[2]
	
	org.Addr1 = getNodeValue(root.childNodes[0])
	org.Addr2 = getNodeValue(root.childNodes[1])
	org.Addr3 = getNodeValue(root.childNodes[2])
	org.City = getNodeValue(root.childNodes[3])
	org.State = getNodeValue(root.childNodes[4])
	org.Zip = getNodeValue(root.childNodes[5])
	
	//set to contact
	root = xml.childNodes[1].childNodes[3]

	org.ContactPrefix = getNodeValue(root.childNodes[0])
	org.ContactFirst = getNodeValue(root.childNodes[1])
	org.ContactLast = getNodeValue(root.childNodes[2])
	org.ContactTitle = getNodeValue(root.childNodes[3])
	org.ContactEmail = getNodeValue(root.childNodes[4])
	org.ContactPhone = getNodeValue(root.childNodes[5])
	org.ContactFax = getNodeValue(root.childNodes[6])
	
	//set to executive
	root = xml.childNodes[1].childNodes[4]	
	
	org.ExecPrefix = getNodeValue(root.childNodes[0])
	org.ExecFirst = getNodeValue(root.childNodes[1])
	org.ExecLast = getNodeValue(root.childNodes[2])
	org.ExecTitle = getNodeValue(root.childNodes[3])
	
	//back to generalInformation
	root = xml.childNodes[1]
	
	org.RulingYear = getNodeValue(root.childNodes[5])
	org.YearFounded = getNodeValue(root.childNodes[6])
	org.Assets = getNodeValue(root.childNodes[7])
	org.Income = getNodeValue(root.childNodes[8])
	
	//set to ntees
	root = xml.childNodes[1].childNodes[9]
	
	//get list of NTEE's.  Store in ^ deliminted string in format code|description
	org.NTEEList = ""
	list = root.getElementsByTagName("ntee")
	
	for(q=0; q < list.length; q++)
	{
		code = getNodeValue(list[q].childNodes[0])
		desc = getNodeValue(list[q].childNodes[1])
		
		if(code != "")
		{
			if(org.NTEEList != ""){org.NTEEList += "^"}			
			org.NTEEList += code + "|" + desc
		}
	}
	
	//back to generalInformation
	root = xml.childNodes[1]
	
	org.IRSSubsection = getNodeValue(root.childNodes[10])
	org.URL = getNodeValue(root.childNodes[11])
	org.WorldLocations = getNodeValue(root.childNodes[12])
	org.Description = getNodeValue(root.childNodes[13])
	org.AKA = getNodeValue(root.childNodes[14])
	org.Deductibility = getNodeValue(root.childNodes[15])
	org.USALocations = getNodeValue(root.childNodes[16])
	
	//set to missionAndPrograms
	root = xml.childNodes[2]	
	
	org.Mission = getNodeValue(root.childNodes[0])
	org.Programs = getNodeValue(root.childNodes[1])
		
	return org
}

/*************************************************************************/

function CalcPages()
{
	if(m_TotalResults < 1)
	{
		m_TotalPages = 0
	}
	else
	{
		mod = m_TotalResults % m_PageSize
		m_TotalPages = Math.round(m_TotalResults / m_PageSize)
		if(mod > 0 && mod < 5){m_TotalPages++}
	}
}


/*************************************************************************/

function getNodeValue(node)
{
	if(node)
	{
		if(node.childNodes[0])
		{
			return node.childNodes[0].nodeValue
		}
		else
		{
			return ""
		}
	}
	else
	{
		return "error parsing node " + node
	}
}

/*************************************************************************/
/* ORGANIZATION OBJECT DEFINITION
/*************************************************************************/
function Organization()
{
	this.ResultPosition
	this.OrgName
	this.EIN
	this.Addr1
	this.Addr2
	this.Addr3
	this.City
	this.State
	this.Zip
	
	this.ContactPrefix
	this.ContactFirst
	this.ContactLast
	this.ContactTitle
	this.ContactEmail
	this.ContactPhone
	this.ContactFax
	
	this.ExecPrefix
	this.ExecFirst
	this.ExecLast
	this.ExecTitle
	
	this.RulingYear
	this.YearFounded
	this.Assets
	this.Income
	
	this.NTEEList
	
	this.IRSSubsection
	this.URL
	this.WorldLocations
	this.Description
	this.AKA
	this.Deductibility
	this.USALocations
	
	this.Mission
	this.Programs
}
