﻿function ListViewItem(objListView, recordset)
{
	var THIS = this;
	this.ListView = objListView;
	this.Container = null;
	this.Selected = false;
	this.Id = 0;
	this.ResultOptions = null;
	this.Expanded = false;
	this.MoreInfo = null;
	this.Line1Text = "";
	this.Line2Text = "";
	this.MoreInfoText = "";
	this.ExpandButton = null;
	this.Index = null;

	this.Main = null;
	var MainInfo = null;

	var arrOptions = new Array();
	var aFirstOption = null;

	this.spnLine1 = null;
	this.spnLine2 = null;
	this.spnMoreInfo = null;

	//==========================================
	// Get the window object
	//==========================================
	function GetWindow()
	{
		return objListView.GetWindow();
	}
	
	//==========================================
	// Construct this class (is called at the end of construction (last line in class)
	//==========================================
	function Init()
	{
		try
		{
			//copy all the fields from the recordset into this list view item
			for (field in recordset)
			{
				if (field == "Rows" || field == "RecordCount" || field == "MasterRows")
					continue;
		
				if (typeof recordset[field] != "function")
					THIS[field] = recordset[field];
			}

			//fix incase - a list view item is used as a source for a new item
			THIS.ListView = objListView;
			THIS.ResultOptions = null;
			THIS.Expanded = false;
			THIS.MoreInfo = null;
			THIS.Line1Text = "";
			THIS.Line2Text = "";
			THIS.MoreInfoText = "";
			THIS.ExpandButton = null;
			THIS.spnLine1 = null;
			THIS.spnLine2 = null;
			THIS.spnMoreInfo = null;
			THIS.Index = THIS.ListView.Count;
		
			//create the item elements and set the text as appropriate
			THIS.Id = Number(recordset[THIS.ListView.KeyField]);

			//set THIS.Container to be the outer DIV, or HTML element
			THIS.Container = document.createElement("DIV");
			THIS.Container.onclick = Item_Click;

			THIS.ResultOptions = document.createElement("DIV");
			THIS.ResultOptions.className = "resultOptions";

			/*if (THIS.ListView.Line2Format != "")
			{
				//move the item up a bit!
				THIS.ResultOptions.style.marginTop = "2px";
			}*/

			THIS.Container.appendChild(THIS.ResultOptions);

			THIS.Main = document.createElement("DIV");
			THIS.Main.className = "main";

			THIS.ExpandButton = document.createElement("INPUT");
			THIS.ExpandButton.type = "button";
			THIS.ExpandButton.className = "expandButton";
			THIS.ExpandButton.value = "+";
			THIS.ExpandButton.onclick = ToggleExpanded;
			THIS.Main.appendChild(THIS.ExpandButton);

			if (BrowserDetect.browser == "Safari" || BrowserDetect.browser == "Chrome")
				THIS.ExpandButton.style.textIndent = "-2px";

			if (THIS.ListView.MoreInfoFormat == "")
			{
				THIS.ExpandButton.disabled = true;
				if (THIS.ListView.AlwaysShowExpandButton == true)
					THIS.ExpandButton.className = "expandButton disabled";
				else
					THIS.ExpandButton.className = "expandButton disabled hidden";
			}

			MainInfo = document.createElement("A");

			THIS.spnLine1 = document.createElement("SPAN");
			//THIS.spnLine1.innerHTML = GetText(THIS.ListView.Line1Format, recordset) + "<br />";
			THIS.SetLine1Text(THIS.ListView.Line1Format);
			MainInfo.appendChild(THIS.spnLine1);

			if (THIS.ListView.Line2Format != "")
			{
				CreateLine2();
				//THIS.spnLine2.innerHTML = GetText(THIS.ListView.Line2Format, recordset);
				THIS.SetLine2Text(THIS.ListView.Line2Format);
			}

			THIS.Main.appendChild(MainInfo);

			THIS.Container.appendChild(THIS.Main);

			AddOptions();
		
			THIS.MoreInfo = document.createElement("DIV");
			THIS.MoreInfo.className = "moreInfo";

			if (THIS.ListView.MoreInfoFormat != "")
			{
				CreateMoreInfo();
				THIS.SetMoreInfoText(THIS.ListView.MoreInfoFormat);
			}

			THIS.ListView.Container.appendChild(THIS.Container);
			THIS.SetSelected(false);
		}
		catch(e)
		{
			alert(e.Message);
		}
	}

	//==========================================
	// Create the elements for the line 2 text
	//==========================================
	function CreateLine2()
	{
		if (THIS.spnLine2 != null)
			return;

		THIS.spnLine2 = document.createElement("SPAN");
		THIS.spnLine2.style.paddingLeft = "23px";
		MainInfo.appendChild(THIS.spnLine2);
	}

	//==========================================
	// Create the elements for the more info text
	//==========================================
	function CreateMoreInfo()
	{
		if (THIS.spnMoreInfo != null)
			return;

		THIS.spnMoreInfo = document.createElement("SPAN");
		THIS.MoreInfo.appendChild(THIS.spnMoreInfo);
		THIS.Container.appendChild(THIS.MoreInfo);
	}

	//==========================================
	// this item has been clicked, raise any events
	//==========================================
	function Item_Click(evt)
	{
		if (THIS.ListView.Enabled)
		{
			evt = GetWindow().event ? GetWindow().event : evt;
			var target = evt.srcElement ? evt.srcElement : evt.target;

			if (target.tagName == "INPUT" && target.disabled)
				return;

			if ((evt.ctrlKey == false && THIS.ListView.MultiSelectRequiresCtrlKey == true) || THIS.ListView.MultiSelect == false)
				THIS.ListView.ClearSelection();

			var blnOldSelected = THIS.Selected;
			THIS.SetSelected(blnOldSelected == false);

			if (evt.ctrlKey && THIS.ListView.MultiSelect)
				return;

			if (THIS.ListView.ItemClicked != null)
			{
				var objResult = THIS.ListView.ItemClicked(THIS, evt);

				if (objResult == false)
					THIS.SetSelected(blnOldSelected);
			}
			else
			{
				HtmlPopup.Alert("Item has been clicked with id " + THIS.Id);
			}
		}
	}

	//==========================================
	// Add the options that are defined in the list view to this item
	//==========================================
	function AddOptions()
	{
		var intCount = THIS.ListView.Options.length;
		for (var intIndex = 0; intIndex < intCount; intIndex++)
		{
			var arrOption = THIS.ListView.Options[intIndex];
			var strText = arrOption[0];
			var fncCallback = arrOption[1];

			var intIndex = arrOptions.length;
			arrOptions.push(fncCallback);

			var aOption = document.createElement("A");
			aOption.innerHTML = strText;

			if (intIndex > 0)
			{
				//this is not the last option, add a pipe to delimit the options
				aOption.innerHTML = aOption.innerHTML;

				var spnPipe = document.createElement("SPAN");
				spnPipe.innerHTML = " | ";
				THIS.ResultOptions.appendChild(spnPipe);
			}
			else
				aFirstOption = aOption;

			aOption.id = intIndex;
			aOption.name = strText;
			aOption.onclick = Option_Click;

			THIS.ResultOptions.appendChild(aOption);
		}
	}

	//==========================================
	// Add an option to this item
	//==========================================
	this.AddOption = function AddOption(strText, fncCallback)
	{
		var intIndex = arrOptions.length;
		arrOptions.push(fncCallback);

		var aOption = document.createElement(fncCallback == null ? "LABEL" : "A");
		aOption.innerHTML = strText;

		var spnPipe = null;

		if (intIndex > 0)
		{
			//this is not the last option, add a pipe to delimit the options
			spnPipe = document.createElement("SPAN");
			spnPipe.innerHTML = "| ";
		}

		aOption.id = intIndex;
		aOption.name = strText;
		if (fncCallback != null)
			aOption.onclick = Option_Click;

		if (aFirstOption == null)
		{
			THIS.ResultOptions.appendChild(aOption);
			if (spnPipe != null)
				THIS.ResultOptions.appendChild(spnPipe);

			aFirstOption = aOption;
		}
		else
		{
			THIS.ResultOptions.insertBefore(aOption, aFirstOption);
			if (spnPipe != null)
				THIS.ResultOptions.insertBefore(spnPipe, aFirstOption);

			aFirstOption = aOption;
		}

		return aOption;
	}

	//==========================================
	// Clear the list of options for this item
	//==========================================
	this.ClearOptions = function ClearOptions()
	{
		arrOptions = new Array();
		THIS.ResultOptions.innerHTML = "";
		aFirstOption = null;
	}

	//==========================================
	// An option has been clicked, invoke the callback, passing in this item as the only argument
	//==========================================
	function Option_Click(evt)
	{
		evt = GetWindow().event ? GetWindow().event : evt;
		var target = evt.srcElement ? evt.srcElement : evt.target;

		//stop the event from firing Item_Click later
		if (evt.stopPropagation)
			evt.stopPropagation();
		evt.cancelBubble = true;
		evt.returnValue = false;

		//target = the A option element that was clicked.
		var intOptionIndex = Number(target.id.toString()); //get the name from the element, this contains the number of the option in the ListView.Options array.
		var strText = target.name.toString();

		var fncCallback = arrOptions[intOptionIndex];

		if (fncCallback != null)
			fncCallback(THIS, evt);
		else
			HtmlPopup.Alert("'" + strText + "' has been clicked on the item with id " + THIS.Id);
	}

	//==========================================
	// Toggle the expanded state of the list view item
	//==========================================
	function ToggleExpanded(evt)
	{
		evt = GetWindow().event ? GetWindow().event : evt;

		if (evt && evt != null)
		{
			//stop the event from firing Item_Click later
			if (evt.stopPropagation)
				evt.stopPropagation();
			evt.cancelBubble = true;
			evt.returnValue = false;
		}

		if (THIS.Expanded == true)
		{
			THIS.MoreInfo.style.display = "";
			THIS.Expanded = false;
			THIS.ExpandButton.value = "+";

			if (BrowserDetect.browser == "Safari" || BrowserDetect.browser == "Chrome")
				THIS.ExpandButton.style.textIndent = "-2px";
		}
		else
		{
			THIS.MoreInfo.style.display = "block";
			THIS.Expanded = true;
			THIS.ExpandButton.value = "-";

			if (BrowserDetect.browser == "Safari" || BrowserDetect.browser == "Chrome")
				THIS.ExpandButton.style.textIndent = "-1px";
		}

		if (evt != null)
		{
			if (THIS.ListView.ItemExpanded != null)
				THIS.ListView.ItemExpanded(THIS, THIS.Expanded);
		}

		return false;
	}

	//==========================================
	// Process the given format against the recordset and return the appropriate string
	//==========================================
	function GetText(strFormat, recordset)
	{
		var strEval = "";

		try
		{
			var strText = "";

			//strFormat will contain a string like: {VehicleID}, {RegistrationNumber}, {Make}
			//where each piece of text within braces is a field name
			//the values can be extracted by constructing the following code.
			//strText = "" + recordset["VehicleID"] + ", " + recordset["RegistrationNumber"] + ", " + recordset["Make"] + ""
			//which means that:
			//every "{" should be replaced with "\" + recordset['"
			//every "}" should be replaced with "'] + \""

			strEval = strFormat.replace(/\"/g, "\\\"");
			strEval = strEval.replace(/\n/g, "<br />");
			strEval = strEval.replace(/{/g, "\" + GetFieldText(\"");
			strEval = strEval.replace(/}/g, "\") + \"");
			strEval = "\"" + strEval + "\"";

			strText = eval(strEval);
			return strText;
		}
		catch (exc)
		{
			return "Could not format '" + strFormat + "'; " + exc.message;
		}
	}

	//==========================================
	// Get the value for the given field. if it is null or undefined return ""
	//==========================================
	function GetFieldText(strName, objParent)
	{
		var strFieldName = "";
		var strNullName = "";

		if (!objParent)
			objParent = THIS;

		if (strName.indexOf(':') != -1)
		{
			var arrParts = strName.split(':');
			strFieldName = arrParts[0];
			strNullName = arrParts[1];
		}
		else
			strFieldName = strName;

		if (strFieldName.indexOf('.') == -1)
		{
			if (objParent[strFieldName] && objParent[strFieldName] != null || (typeof (objParent[strFieldName]) == "number" && objParent[strFieldName] == 0))
				return objParent[strFieldName];
		}
		else
		{
			var arrParts = strFieldName.split('.');
			var strParent = arrParts[0];
			strFieldName = strFieldName.substring(strParent.length + 1);

			return GetFieldText(strFieldName, objParent[strParent]);
		}

		return strNullName;
	}

	//==========================================
	// Set the selected state of this list view item
	//==========================================
	this.SetSelected = function SetSelected(blnSelected)
	{
		this.Selected = blnSelected;

		if (this.Container.className == "")
			this.Container.className = "result";

		if (blnSelected)
		{
			this.Container.className = this.Container.className.replace(/ selected/g, "");
			this.Container.className += " selected";

			THIS.ListView.SelectedItems.removeItems([THIS]);
			THIS.ListView.SelectedItems.push(THIS);
		}
		else
		{
			this.Container.className = this.Container.className.replace(/ selected/g, "");

			THIS.ListView.SelectedItems.removeItems([ THIS ]);

			/*for (var intIndex = 0; intIndex < THIS.ListView.SelectedItems.length; intIndex++)
			{
				var objItem = THIS.ListView.SelectedItems[intIndex];
				if (objItem == THIS)
				{
					THIS.ListView.SelectedItems[intIndex] == null;
					break;
				}
			}*/

			/*for (var intIndex = THIS.ListView.SelectedItems.length - 1; intIndex >= 0; intIndex--)
			{
				
			}*/
		}
	}

	//==========================================
	// Set the expanded state of this list view item
	//==========================================
	this.SetExpanded = function SetExpanded(blnExpanded)
	{
		if (this.Expanded == blnExpanded || this.MoreInfo == null || this.ExpandButton == null)
			return;

		ToggleExpanded(null);
	}

	this.SetLine1Text = function SetLine1Text(strFormat)
	{	
		var strText = GetText(strFormat);
		this.spnLine1.innerHTML = strText + "<br/>";

		this.Line1Text = strText;
	}

	this.SetLine2Text = function SetLine2Text(strFormat)
	{
		CreateLine2();

		var strText = GetText(strFormat);
		this.spnLine2.innerHTML = strText;

		this.Line2Text = strText;

		if (strText == "")
			this.spnLine2.style.display = "none";
		else
			this.spnLine2.style.display = "";
	}

	this.SetMoreInfoText = function SetMoreInfoText(strFormat)
	{
		CreateMoreInfo();

		var strText = GetText(strFormat);
		this.spnMoreInfo.innerHTML = strText;

		this.MoreInfoText = strText;

		if (strText == "")
		{
			this.ExpandButton.disabled = true;
			if (this.ListView.AlwaysShowExpandButton == true)
				this.ExpandButton.className = "expandButton disabled";
			else
				this.ExpandButton.className = "expandButton disabled hidden";
		}
		else
		{
			this.ExpandButton.disabled = false;
			this.ExpandButton.className = "expandButton";
		}
	}
	
	Init();
}
