//////////////////////////////////////////////
// ColumnBrowser Object VERSION_0.8
//////////////////////////////////////////////
//
// List control, 
//
// Ali Russell 10.2006
//
//////////////////////////////////////////////

var List = Class.create();
List.prototype = {
//
// Member Variables
m_controlSurface: null, 
m_allItems: null,
m_filteredItems: null,
m_displayedItems: null,
m_highlightItems: null,
m_selectedItems: null,
m_highlightRanges: null,
m_visibleItems: 0,
m_lastScrollPos: 0,
m_scrollPollTimeout: -1,
m_parentColumn: null,
m_firstItemIndex: "",
m_lastItemIndex: "",
m_dataFields: null,
m_sortField: "label",
m_filterObjects: null,
m_currentNodeMappings: new Object(),
m_previewTimeoutId: -1,
m_listScrollingTimeout: -1,
m_initialSelections: new Object(),
m_lastClickTime: 0,
m_lastClickElement: null,
m_dblClickTimeout: 500, // dbl click registered if clicks are within 0.5 seconds
m_doubleClickTimeoutId: -1,
m_selectedPreview: null,
m_lastClickInSlice: false,
m_tagItemTitleDesc: " { Scratchpad: Double click to add to your scratchpad! }",
m_multiplSelectItemTitleDesc: " { Multiple Selection: Shift click for multiple selection }",
m_loadItemsInView: false,
m_Count: 0,
m_filterOn: false,





//streamlined params
ssFilterText: "",
ssFilterToutId: -1,
disItemCount: 0,
allItemsLoaded: false,
m_DisplayItems: new Array(),
currentFilterText: "",

//
// Constructor
initialize: function(objectOptions)
	{
				
		//init the items array before parsing the options object
		this.m_allItems = new Array();
		
		
	
		//Override the defatul object parameters, with those from the objectOptions.
		ParseOptions(objectOptions, this);
		
		
		if (this.m_Count<=this.m_ItemsCount)
		{
			this.allItemsLoaded = true;
		}		

		

	
		//Create the column container div
		this.m_controlSurface = createDiv("List", true);
		this.m_controlSurface.style.display = "none";
		
		this.m_listItemHolder = createDiv("ListItemHolder", true);
		this.m_listItemHolder.style.overflow = "hidden";
		this.m_controlSurface.appendChild(this.m_listItemHolder);
		
		this.m_scrollSpacerDiv = createDiv("ScrollSpacer", true);
		this.m_listItemHolder.appendChild(this.m_scrollSpacerDiv);
		
		this.m_dataFields = new Object();

		this.m_filterObjects = new Object();

		this.m_displayedItems = new Array();
		this.m_filteredItems = new Array();
		
		

				
		
		//only add one ListItem size tester to the document.
		//if one does not exist create one, and assign it to 
		//a global variable
		if (window.ListItemSizeGuide)
		{
			this.m_dummyListItem = window.ListItemSizeGuide;
		}
		else
		{		
			var dummyContainer = document.createElement("div");
			dummyContainer.style.height="0px";
			dummyContainer.style.width="0px";
			dummyContainer.style.overflow="hidden";
			dummyContainer.style.visibility = "hidden";
			
			this.m_dummyListItem = createDiv("ListItem", true);
			this.m_dummyListItem.style.visibility = "hidden";
			
			this.m_dummyListItemContent = createDiv("Even", true);
			this.m_dummyListItemContent.innerHTML = "ListItem";
			this.m_dummyListItem.appendChild(this.m_dummyListItemContent);
			
			dummyContainer.appendChild(this.m_dummyListItem);
			
			document.body.appendChild(dummyContainer);
			window.ListItemSizeGuide = this.m_dummyListItem;
		}
				
				
		this.m_listItemHeight = this.m_dummyListItem.offsetHeight;
		//alert(this.m_listItemHeight);
		
		
	
		
		//Register custom events
		////////////////////////
		mSpaceApplication.Subscribe("mSpaceApplication.PageResize", this);
		
		//mSpaceApplication.Subscribe("Item.MouseOver", this);
		//mSpaceApplication.Subscribe("Item.MouseOut", this);
		mSpaceApplication.Subscribe("Item.MouseClick", this);
		mSpaceApplication.Subscribe("Column.ClearPreviewIcon", this);
		
		
		mSpaceApplication.Subscribe("Item.ScrollIntoView", this);
		
		
		//Register DOM events
		/////////////////////
		
		RegisterEvent(this.m_controlSurface, "DOMMouseScroll", this, "UpdateScrollPos");
		RegisterEvent(this.m_controlSurface, "scroll", this, "UpdateScrollPos");
		
		RegisterEvent(this.m_controlSurface, "mouseover", this, "StartScrollPoll");
		RegisterEvent(this.m_controlSurface, "mouseout", this, "MouseOut");
		
		
		
		//force an apply text filter, as items may have just been loaded
		this.ShowAllItems();
		
	},
	
Resize: function(isAnimating)
	{
		
			//if something is animating, dont bog down the 
			//speed with list resizing.
			if ((isAnimating) || (window.ColumnBrowser.m_isAnimating))
				return;
				
		var hasChanged = false;
		
		this.m_listItemHeight = this.m_dummyListItem.offsetHeight;
		
		if (this.m_listItemHeight<1)
		{
			this.m_listItemHeight = this.m_dummyListItem.firstChild.clientHeight;
			if (this.m_listItemHeight<1)
				return;
		}
		
		var surfaceheight = this.m_controlSurface.clientHeight;
		
		var items = Math.ceil(surfaceheight/this.m_listItemHeight);
		
		if (items!=(this.m_listItemHolder.childNodes.length-1))
		{
			if (((this.m_listItemHolder.childNodes.length-1)>items))
			{
				while ((this.m_listItemHolder.childNodes.length-1)>items)
				{
					var childNode = this.m_listItemHolder.lastChild;
					if (childNode!=this.m_scrollSpacerDiv)
					{
						try
						{
						this.m_listItemHolder.removeChild(childNode);
						}
						catch (e) {}
					}
				}
			}
			else
			{
				for (var i=(this.m_listItemHolder.childNodes.length-1);i<items;i++)
				{
					//Create the main holder
					var tempItem = createDiv("ListItem", true);
					
					//create the subContainer
					var childTempItem = createDiv("Even", true);					
					tempItem.appendChild(childTempItem);
					
					//Create the label
					var labelDiv = createDiv("Label", true);
					labelDiv.innerHTML =  ""
					childTempItem.appendChild(labelDiv);
					
					//Create the label
					var previewDiv = createDiv("Preview", true);
					previewDiv.innerHTML = "<img class='Preview' src='pics/ColumnBrowser/Columns/preview_btn.png' alt='Show Preview Cue'>";
					childTempItem.appendChild(previewDiv);						
					
					//Create the label
					var countDiv = createDiv("Count", true);
					countDiv.innerHTML =  "";
					childTempItem.appendChild(countDiv);					
					

					
	
					
					
					//Register events
					RegisterEvent(tempItem, "mouseover", this, "MouseOverListItem");
					RegisterEvent(tempItem, "mouseout", this, "MouseOutListItem");
					RegisterEvent(tempItem, "click", this, "MouseClickListItem", true);
					
					RegisterEvent(previewDiv, "mouseover", this, "MouseOverPreview");
					RegisterEvent(previewDiv, "mouseout", this, "MouseOutPreview");
					RegisterEvent(previewDiv, "click", this, "MouseClickPreview", true);
					
					
					this.m_listItemHolder.appendChild(tempItem);
				}
				hasChanged = true;
			}
		}
		
		var totalItems = this.m_Count;
		if (!this.allItemsLoaded && this.m_filterOn)
		{
			totalItems = this.disItemCount;
		}		
		var totalHeight = totalItems * this.m_listItemHeight;		
		
		this.m_listItemHolder.style.height = totalHeight + "px";
		
		this.m_visibleItems = items;
		
		if (hasChanged)
		{
			this.UpdateListItems();
		}
		
	},
	
Notify: function(eventName, eventParams)
	{
		switch(eventName)
		{
			case 'mSpaceApplication.PageResize' : this.Resize(eventParams); break;
			case 'Item.MouseOver' : this.ItemOver(eventParams); break;
			case 'Item.MouseOut' : this.ItemOut(eventParams); break;
			case 'Item.MouseClick' : this.ItemClick(eventParams); break;
			case 'Column.ClearPreviewIcon' : this.ClearPreview(eventParams); break;
			case 'Item.ScrollIntoView' : this.ScrollItemIntoView(eventParams); break;
			default: break;
		}
	},

UpdateScrollPos: function(e, element)
	{
		
		if (this.m_lastScrollPos!=this.m_controlSurface.scrollTop)
		{
			if (this.m_listScrollingTimeout!=-1)
			{
				clearInterval(this.m_listScrollingTimeout);
				this.m_listScrollingTimeout = -1;
			}
		
			this.m_scrollSpacerDiv.style.height = (this.m_controlSurface.scrollTop) + "px";
			if (this.m_controlSurface.scrollTop==0)
			{
				this.m_scrollSpacerDiv.style.display = "none";
			}
			else
			{
				this.m_scrollSpacerDiv.style.display = "";
			}
			this.m_lastScrollPos = this.m_controlSurface.scrollTop;
			this.UpdateListItems();
			
			

			
			var firstLetter = "A";
			var lastLetter = "Z";
			var actualAZ = this.m_atoz.split(',');
			
			if (!this.m_Items[this.m_firstItemIndex])
			{
				for (var x=0;x<actualAZ.length;x++)
				{
					var atz = actualAZ[x].split(':');
					if ((this.m_firstItemIndex)<atz[0])
					{
						break;
					}
					else if ((this.m_firstItemIndex)>=atz[0])
					{
						firstLetter = atz[1];
						
					}
				}				
			}
			else
			{
				firstLetter = this.m_Items[this.m_firstItemIndex].label;
			}			
			
			if (!this.m_Items[this.m_lastItemIndex])
			{
				for (var x=0;x<actualAZ.length;x++)
				{
					var atz = actualAZ[x].split(':');
					if ((this.m_lastItemIndex)<atz[0])
					{
						break;
					}
					else if ((this.m_lastItemIndex)>=atz[0])
					{
						lastLetter = atz[1];
						
					}
				}				
			}	
			else
			{
				lastLetter = this.m_Items[this.m_lastItemIndex].label;
			}
			
			if (firstLetter.length>0)
				firstLetter = firstLetter.charAt(0);
			if (lastLetter.length>0)
				lastLetter = lastLetter.charAt(0);				
				
			var popupString = firstLetter + " - " + lastLetter;
			
				
			
			
			var thisObj = this;
			mSpaceApplication.FireEvent("List.Scroll", { list: this, text: popupString });
			this.m_listScrollingTimeout = setTimeout(function() { thisObj.ScrollListStop(); }, 400);
		}	
	},
	
ScrollListStop: function(e, element)
	{
		if (this.m_loadItemsInView)
		{
			this.m_loadItemsInView = false;
			var startItem = Math.ceil(this.m_controlSurface.scrollTop/this.m_listItemHeight);
			mSpaceApplication.FireEvent("List.LoadPartialItems", { col: this.m_parentColumn, start: startItem });			
		}
	},
	
StartScrollPoll: function(e, element)
	{
		//set an interval for browsers that dont support onscroll
		var thisObj = this;
		this.m_scrollPollTimeout = setInterval(function() { thisObj.UpdateScrollPos(); }, 5);
	},
	
StopScrollPoll: function(e, element)
	{
		if (this.m_scrollPollTimeout!=-1)
		{
			clearInterval(this.m_scrollPollTimeout);
			this.m_scrollPollTimeout = -1;
		}
	},
	
UpdateListItems: function()
	{
		var startItem = Math.ceil(this.m_controlSurface.scrollTop/this.m_listItemHeight);
		this.m_currentNodeMappings = new Object();
		var totalSelectedItems = 0;
		for (d in this.m_Selected)
		{
			totalSelectedItems ++;
		}
		
		
		var totalItems = this.m_Count;
		if (!this.allItemsLoaded && this.m_filterOn)
		{
			totalItems = this.disItemCount;
		}
	
		
		var totalHeight = totalItems * this.m_listItemHeight;
		if (isNaN(totalHeight))
			totalHeight = 0;
		
		this.m_listItemHolder.style.height = totalHeight + "px";		
		
		this.m_loadItemsInView = false;
		this.m_currentStartItem = startItem;	
		
		
		for (var i=1;i<this.m_listItemHolder.childNodes.length;i++)
		{
			var divItem = this.m_listItemHolder.childNodes[i];
			
			if (isOdd(startItem + (i-1)))
			{
				divItem.firstChild.className = "Odd";
			}
			else
			{
				divItem.firstChild.className = "Even";
			}
			
			if(this.m_selectedPreview && this.m_selectedPreview.label == divItem.firstChild.firstChild.innerHTML)
			{
				divItem.firstChild.childNodes[1].firstChild.src="pics/ColumnBrowser/Columns/preview_btn_on.png";
			}
			else
			{
				divItem.firstChild.childNodes[1].firstChild.src="pics/ColumnBrowser/Columns/preview_btn.png";
			}
			


			var li_id = startItem + (i);
			if (this.allItemsLoaded)
			{
				li_id = this.m_DisplayItems[startItem + (i)];
			}
			
			if (this.m_Items[li_id])
			{
				
				var li = this.m_Items[li_id];
				var itemLabel = li.label;
				var itemUri = li.uri;
				
				if (totalSelectedItems>0)
				{
					divItem.firstChild.title = li.label + this.m_multiplSelectItemTitleDesc;
				}
				else
				{
					divItem.firstChild.title = li.label + this.m_tagItemTitleDesc;
				}
	
				if ((this.m_Highlighted[startItem + (i)]) && (window.g_backHighlight))
				{
					divItem.firstChild.className = "Highlighted";
				}
	
				if (this.m_Selected[startItem + (i)])
				{
					divItem.firstChild.className = "Selected";
					
				}
				
				if (i==1)
				{
					this.m_firstItemIndex = li_id;
				}
				this.m_lastItemIndex = li_id;
				
				divItem.firstChild.firstChild.innerHTML = li.label;

				/*
				if (li.goalCount)
				{					
					divItem.firstChild.childNodes[2].innerHTML = "(" + li.goalCount + ")";
				}
				else
				{
					divItem.firstChild.childNodes[2].innerHTML = "";
				}
				*/
				
				if (li.hasPreview==true)
				{
					divItem.firstChild.childNodes[1].style.display = "";
				}
				else
				{
					divItem.firstChild.childNodes[1].style.display = "none";
				}
				
				this.m_currentNodeMappings[li_id] = divItem;
				
				divItem.firstChild.firstChild.style.width = (divItem.clientWidth - divItem.firstChild.childNodes[1].offsetWidth - divItem.firstChild.childNodes[2].offsetWidth - 5) + "px";				
			}
			else if ((!this.allItemsLoaded) && ((startItem + (i))<=totalItems))
			{
				this.m_loadItemsInView = true;
				divItem.firstChild.firstChild.innerHTML = "Loading...";
				divItem.firstChild.childNodes[2].innerHTML = "";
				
				if (i==1)
				{
					this.m_firstItemIndex = li_id;
				}
				this.m_lastItemIndex = li_id;
				
			}
			else
			{
				divItem.firstChild.firstChild.innerHTML = "";
				divItem.firstChild.childNodes[2].innerHTML = "";
			}			
			
			
		
		}

		this.ToggleShowAll();
	},

GetListItem: function(domNode)
	{
		
		for (key in this.m_currentNodeMappings)
		{
			if (this.m_currentNodeMappings[key]==domNode)
			{
				return this.m_Items[key];
			}
		}
		
		return null;
	},

ContainsItem: function(uri)
	{	
		if (this.m_allItems[uri]!=null)
		{
			return true;
		}
		return false;
	},

ToggleShowAll: function()
	{
		var showall = false;
			for(id in this.m_Items)
			{
				if(this.m_Selected[id] == true)
				{
					showall = true;
					break;
				}
			}

			if(showall)
				this.m_parentColumn.m_allBtn.style.display='';
			else
				this.m_parentColumn.m_allBtn.style.display='none';
	},
	
GetNodeByUri: function(uri)
	{
			return this.m_currentNodeMappings[uri];
	},	
	
MouseOverListItem: function(e, element)
	{
		if(HelpOn)
		{
			mSpaceApplication.FireEvent("Help.ShowHighlight", {element: this.m_parentColumn.m_controlSurface, name: "Column.Open"});
			return;
		}
		
		mSpaceApplication.FireEvent("Cursor.Change", "pointer");
		//element.firstChild.className = "Over";
		var li = this.GetListItem(element);
		mSpaceApplication.FireEvent("Item.MouseOver", { sender: this, sourceItem: li, e: e, column: this.m_parentColumn });
	},
	
MouseOutListItem: function(e, element)
	{
		if(HelpOn)
		{
			mSpaceApplication.FireEvent("Help.HideHighlight");
		}
		//this.UpdateListItems();
		var li = this.GetListItem(element);
		
		mSpaceApplication.FireEvent("Item.MouseOut", { sender: this, sourceItem: li });
	},

MouseDblClickListItem: function(e, element)
	{
		var li = this.GetListItem(element);
		mSpaceApplication.FireEvent("Column.DoublecClick", {listitem: li, column: this.m_parentColumn});
	},
	
MouseClickListItem: function(e, element)
	{
		
		
		if ((this.m_lastClickElement==null) || (this.m_lastClickElement!=element))
		{
			this.m_lastClickElement = element;
			var thisObj = this;
			this.m_doubleClickTimeoutId = setTimeout(function() { thisObj.ActualMouseClickListItem(e, element); }, this.m_dblClickTimeout);
		}
		else
		{
			if (this.m_doubleClickTimeoutId!=-1)
			{
				clearTimeout(this.m_doubleClickTimeoutId);
				this.m_doubleClickTimeoutId = -1;
			}
			this.m_lastClickElement = null;
			this.MouseDblClickListItem(e, element);
		}
		
		

		
		
		
	},
	
ActualMouseClickListItem: function(e, element)
	{
		this.m_lastClickInSlice = true;
		this.m_lastClickElement = null;
		
		var li = this.GetListItem(element);
		
		if (this.m_Selected[li.id])
		{
			this.m_Selected[li.id] = false;
			this.UpdateListItems();
			
			mSpaceApplication.FireEvent("Log.Event", { type: "InteractEvent", message: "[Item UnSelect] " + li.label + " (uri: " + li.uri + " , column: " + this.m_parentColumn.m_Label + ")" });
			
			mSpaceApplication.FireEvent("Column.UnSelectItem", { column: this.m_parentColumn, listitem: li });
		}
		else
		{
			
			var isShift = false;
			
			//If the shift key is not pressed, clear all currently selected items
			try { //Hack for IE, does not seem to like this
			
				if (e.shiftKey)
				{
					isShift = true;
				}
			}
			catch (e)
			{
			}
			
			if (!isShift)
			{
				for (key in this.m_Selected)
				{
					this.m_Selected[key] = false;
				}				
			}
			
			this.m_Selected[li.id] = li;
			this.UpdateListItems();
			
			mSpaceApplication.FireEvent("Log.Event", { type: "InteractEvent", message: "[Item Select] " + li.label + " (uri: " + li.uri + " , column: " + this.m_parentColumn.m_Label + ")" });
			
			mSpaceApplication.FireEvent("Column.SelectItem", { column: this.m_parentColumn, listitem: li });
		}
		//this.ToggleShowAll();		
	},

MouseOut: function(e, element)
	{
		//this.UpdateListItems();
		this.StopScrollPoll(e, element);
		mSpaceApplication.FireEvent("Cursor.Reset");
	},
	
Clear: function()
	{
		
		this.m_Items = new Object();
		this.m_Selected = new Object();
		this.m_Highlighted = new Object();
		
		this.Resize();
		
		this.UpdateListItems();
	},
	
ReplaceItems: function(items)
	{
		ParseOptions(items, this);
		
				
		this.RefreshFilter();
		
	},
	
GetHistoryObject: function()
	{
		var historyObject = new Object();
		
		historyObject["DisplayedItems"] = this.m_Items;

		var newSelectedArr = new Array();
		for (var key in this.m_Selected)
		{
			if (this.m_Selected[key])
			{
				newSelectedArr.push(key);
			}
		}
		historyObject["SelectedItems"] = newSelectedArr;
		
		var newHighlArr = new Array();
		for (var key in this.m_Highlighted)
		{
			if (this.m_Highlighted[key])
			{
				newHighlArr.push(key);
			}
		}
		historyObject["HighlightItems"] = newHighlArr;
		
		return historyObject;
		
	},
	
LoadContents: function(newContents)
	{
			// DEPRICATED????
		/*
		if (newContents.items)
		{
			for (var i=0;i<newContents.items.length;i++)
			{
				var lItem = newContents.items[i];
				
				this.ParseDataField(lItem);
				
				this.m_allItems[lItem.uri] = lItem;
				this.m_displayedItems[i] = lItem.uri;
				this.m_filteredItems[i] = lItem.uri;
			}
				
		}
		
		this.m_highlightItems = new Object();
		this.m_selectedItems = this.m_initialSelections;
		this.m_initialSelections  = new Object();
		this.m_highlightRanges = new Object();
		
		this.RefreshFilter();*/
	},
	
UpdateData: function(columnDataObject, firstLoad)
	{
		var lastCount = this.m_Count;
		
		ParseOptions(columnDataObject, this);
		
		this.ssFilterText = "";
		if (columnDataObject.TextFilter)
		{
			this.ssFilterText = columnDataObject.TextFilter;
		}
		
		this.m_DisplayItems = new Array();
		if (!this.allItemsLoaded) 
		{
			this.ShowAllItems();
		}
		else
		{
			this.ApplyTextFilter(true);
		}
		
		
		this.allItemsLoaded = false;
		
		if (this.m_Count<=this.m_ItemsCount)
		{
			this.allItemsLoaded = true;
		}
		
		
		
		var scrollIntoViewItem = null;
	
		for (id in this.m_Selected)
		{
			if (scrollIntoViewItem==null)
			{
				scrollIntoViewItem = id;
			}
		}
		
		if (scrollIntoViewItem==null)
		{
			for (id in this.m_Highlighted)
			{
				if (scrollIntoViewItem==null)
				{
					scrollIntoViewItem = id;
				}
			}			
		}
		
	
		
		this.m_controlSurface.scrollTop = 0;
		this.m_scrollSpacerDiv.style.height = "0px";

		// Reset the last click switch
		//this.m_lastClickInSlice = false;
		
		this.RefreshFilter();
		
		
		
		if (scrollIntoViewItem!=null)
		{
			this.ScrollIdIntoView(scrollIntoViewItem);
		}
		
		
		
		this.m_parentColumn.UpdateTitle((this.m_SelectedCount>0), (this.m_HighlightedCount>0));
		
		
	},
	
ApplyFilters: function()
	{
		
		this.m_filterObjects;
		
		this.m_filteredItems = new Array();				
		
		for (var id in this.m_Items)
		{
			var li = this.m_Items[id];
			if (li!=null)
			{
				var addItem = true;
				for (key in this.m_filterObjects)
				{
					var filterFunction = this.m_filterObjects[key];
					if (filterFunction!=null)
					{
						if (!filterFunction(li, false))
						{
							addItem = false;
							break;
						}
					}
					
				}
			
				//if no object returns false, then add item to filter array 
				if (addItem)
				{
					this.m_Filtered.push(li.id);	
				}
				
			}
		}

		if(this.m_Filtered.length == 0 && this.m_parentColumn.m_searchTextBox.value != "")
		{
			if(this.m_parentColumn.m_searchTextBox.value != this.m_parentColumn.m_filterMessage)
				var noresult = "No results found for <i>'"+this.m_parentColumn.m_searchTextBox.value+"'</i>";
			else
				var noresult = "No results";
			this.m_parentColumn.m_noResults.innerHTML = noresult;
			this.m_parentColumn.m_noResults.style.display = "";
		}
		else
			this.m_parentColumn.m_noResults.style.display = "none";
			
		
		if (this.m_parentColumn.m_searchTextBox.value == "")
		{
			this.m_filterOn = false;
		}
		else
		{
			this.m_filterOn = true;
		}

	},
	
SortArrayItems: function(item1, item2)
	{
		var liItem1 = this.m_allItems[item1];
		var liItem2 = this.m_allItems[item2];
		
		if (liItem1[this.m_sortField] && liItem2[this.m_sortField])
		{
			if (liItem1[this.m_sortField] < liItem2[this.m_sortField])
			{
				return -1;
			}
			else if (liItem1[this.m_sortField] > liItem2[this.m_sortField])
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
		else
		{
			return 0;
		}
	},
	
ApplySort: function()
	{		
		if (this.m_dataFields[this.m_sortField])
		{
			this.m_Items.sort(SortArrayItems);
			
			this.ApplyFilters();
		}
	},
	
AddFilter: function(eventParams)
	{
		if (eventParams.object && eventParams.func)
		{
			this.m_filterObjects[eventParams.object] = eventParams.func;
		}
	},

RemoveFilter: function(eventParams)
	{
		if (eventParams.object)
		{
			this.m_filterObjects[eventParams.object] = null;
			this.RefreshFilter();
		}		
		
		
	},
	
ClearFilters: function()
	{
		//loop through each filter function and send a clear filter signal.
		for (key in this.m_filterObjects)
		{
			var filterFunction = this.m_filterObjects[key];
			if (filterFunction!=null)
			{
				filterFunction(null, true);			
			}
			
		}		
		
		this.m_filterOn = false;
	},
	
RefreshFilter: function(eventParams)
	{
		//this.ApplyFilters();
		
		this.Resize();
		
		this.UpdateListItems();
	},
	
ChangeSort: function(sortField)
	{
		this.m_sortField = sortField;
		
		this.ApplySort();
		
		this.UpdateListItems();
	},
	
ParseDataField: function(listItem)
	{
		for (key in listItem)
		{
			this.m_dataFields[key] = true;
		}
	},
	
ScrollIntoView: function(itemUri)
	{
		this.m_listItemHeight = this.m_dummyListItem.offsetHeight;
		
		var itemPos = -1;
		for (var i=0;i<this.m_filteredItems.length;i++)
		{
			var li = this.m_allItems[this.m_filteredItems[i]];
			if ((li.uri) && (li.uri==itemUri))
			{
				itemPos = i;
				break;
			}
		}
		
		if (itemPos!=-1)
		{
			var height = itemPos * this.m_listItemHeight;
			
			this.m_controlSurface.scrollTop = height;
		}
		
		
	},
	
ContainsField: function(field)
	{
		return this.m_dataFields[field];
	},
	
ItemOver: function(eventParams)
	{
		//If the column browser is not AcceptingInput, then dont apply the item over
		if (!window.ColumnBrowser.AcceptingInput())
		{
			return;
		}
		
		if (eventParams.sender && eventParams.sourceItem)
		{
			if (eventParams.sender!=this)
			{
				var node = this.GetNodeByUri(eventParams.sourceItem.uri);
				if (node!=null)
				{
					node.firstChild.className = "Over";
				}
			}
			else
			{
				var thisObj = this;
				var xPos = mousePosX(eventParams.e) + 10;
				var yPos = mousePosY(eventParams.e) - 10;
				
				//this.m_tooltipTimeout = setTimeout(function() {mSpaceApplication.FireEvent("Tooltip.Show", {sender: thisObj, x: xPos, y: yPos, message: 'Double click to save to Interests'}); }, TooltipTimeout);
			}
		}
	},
	
ItemOut: function(eventParams)
	{
		//If the column browser is not AcceptingInput, then dont apply the item out
		if (!window.ColumnBrowser.AcceptingInput())
		{
			return;
		}
		
		if ((eventParams.sender!=this) && (this.ContainsItem(eventParams.sourceItem)))
		{
			this.UpdateListItems();
		}
		else
		{
			/*if (this.m_tooltipTimeout!=-1)
				clearTimeout(this.m_tooltipTimeout);

			mSpaceApplication.FireEvent("Tooltip.Hide", {sender: this});*/
		}
	},
	
GetSelectedId: function(uri)
	{
		for (id in this.m_Selected)
		{
			if (this.m_Selected[id].uri == uri)
			{
				return id;
			}
		}
		return -1;
	},	
	
ItemClick: function(eventParams)
	{
		
		//If the column browser is not AcceptingInput, then dont apply the click
		if (!window.ColumnBrowser.AcceptingInput())
		{
			return;
		}
		
		if (eventParams.sender && eventParams.sourceItem)
		{
			if (eventParams.sender!=this && eventParams.sourceItem.column && eventParams.sourceItem.column==this.m_parentColumn.m_Uri)	
			{
				
				if(!this.m_parentColumn.m_isOpen)
				{
					mSpaceApplication.FireEvent("ColumnBrowser.QueueColumn", { column: this.m_parentColumn });
				}
				
					var li_Uri = eventParams.sourceItem.uri;                
					if (li_Uri.indexOf("http%3A%2F%2F")!=-1)
					{
					   li_Uri = URLDecode(eventParams.sourceItem.uri);
					}				
				
				var li = new Object();
				li.uri = li_Uri;
				
				var id = this.GetSelectedId(li.uri);
				
				/* Author: JRG 
				* forceSingleSelect is required for the new segmentation code. 
				* This clears all selections and then selects the item. This is to ensure selecting a clip results in the relevant Title & Segment being selected.
				*/

				if(eventParams.forceSingleSelect) 
				{
					this.ClearSelections();
					this.m_Selected[-1] = li;
					mSpaceApplication.FireEvent("Column.SelectItem", { column: this.m_parentColumn, listitem: li});
				}
				else 
				{
					if (id!=-1)
					{
						this.m_Selected[id] = false;
						mSpaceApplication.FireEvent("Column.UnSelectItem", { column: this.m_parentColumn, listitem: li});
					}
					else
					{
						this.m_Selected[-1] = li;
						mSpaceApplication.FireEvent("Column.SelectItem", { column: this.m_parentColumn, listitem: li});
					}
				}
							
			}
		}
		

	},

ShowAll: function()
	{
		this.m_Selected = new Object();
		this.UpdateListItems();

		mSpaceApplication.FireEvent("Column.UnSelectAll", {column: this.m_parentColumn});

		mSpaceApplication.FireEvent("Log.Event", { type: "InteractEvent", message: "[Column Unselect All] column: " + this.m_parentColumn.m_Label + ")" });
		mSpaceApplication.FireEvent("mSpaceHistory.PushHistory", null);

		this.m_parentColumn.m_allBtn.style.display='none';

		this.m_lastClickInSlice = false;
	},
	
Clear: function()
	{
		this.m_displayedItems = new Array();
		this.m_filteredItems = new Array();

		this.m_highlightItems = new Object();
		this.m_selectedItems = new Object();
		this.m_highlightRanges = new Object();
	},
	
MouseOverPreview: function(e, element)
	{
		if(HelpOn)
		{
			mSpaceApplication.FireEvent("Help.ShowHighlight", {element: this.m_parentColumn.m_controlSurface, name: "Column.Open"});
			return;
		}
		
		mSpaceApplication.FireEvent("Cursor.Change", "pointer");
		var li = this.GetListItem(element.parentNode.parentNode);
		if (li!=null)
		{
			var thisObj = this;
			this.m_previewTimeoutId = setTimeout(function() { thisObj.FirePreview(li, element); }, 750);
		}		
	},
	
MouseOutPreview: function(e, element)
	{
		if(HelpOn)
		{
			mSpaceApplication.FireEvent("Help.ShowHighlight");
		}
		
		if (this.m_previewTimeoutId!=-1)
		{
			clearTimeout(this.m_previewTimeoutId);
		}
	},	
	
MouseClickPreview: function(e, element)
	{
		var li = this.GetListItem(element.parentNode.parentNode);
		if (li!=null)
		{
			this.FirePreview(li);
		}
	},
	
FirePreview: function(li, element)
	{
		mSpaceApplication.FireEvent("Column.ClearPreviewIcon", {sender: this});
		this.m_selectedPreview = li; 

		mSpaceApplication.FireEvent("Log.Event", { type: "InteractEvent", message: "[Load Preview] " + li.label + " (uri: " + li.uri + " , column: " + this.m_parentColumn.m_Label + ")" });
		
		mSpaceApplication.FireEvent("Item.Preview", { sender: this, sourceItem: li, column: this.m_parentColumn });
	},

ClearPreview: function(eventParams)
	{
		if(this != eventParams.sender)
		{
			this.m_selectedPreview = null;
			this.UpdateListItems();
		}
	},
	
ClearSelections: function()
	{
		this.m_Selected = new Object();
	},
	
GetSliceString: function()
	{
		
		var returnDiv = createDiv("float", true);
		
		var totalCount = 0;
		
		var selectedCount = 0;
		var moreSelTooltip = "";
		for (id in this.m_Selected)
		{
			var li =  this.m_Selected[id];
		
			if (selectedCount<1)
			{
				var tempDiv = createDiv("selected", true);
				
				tempDiv.innerHTML = li.label;
				tempDiv.title = li.label + " {Click to Unselect}";
				
				
				var thisObj = this;
				RegisterEvent(tempDiv, "mouseover", this, "BreadcrumbMouseOver", false, false, li.id );
				RegisterEvent(tempDiv, "click", this, "BreadcrumbMouseUnSelect", false, false, li );
				
				returnDiv.appendChild(tempDiv);
			}
			else
			{
				if (selectedCount>1)
				{
					moreSelTooltip += " | ";
				}
				moreSelTooltip += li.label;
			}
			
			selectedCount ++;
			totalCount ++;
		}
	
		if (selectedCount>1)
		{
			var moreDiv = createDiv("more", true);
			moreDiv.title = moreSelTooltip;
			moreDiv.innerHTML = "[" + (selectedCount-1) + " more]";
			returnDiv.appendChild(moreDiv);
		}		
		
		
		if (selectedCount==0)
		{
			var highCount = 0;
			var moreTooltip = "";
			for (id in this.m_Highlighted)
			{
				var li =  this.m_Highlighted[id];
			
				if (highCount<1)
				{
					var tempDiv = createDiv("highlighted", true);
					tempDiv.innerHTML = li.label;
					
					tempDiv.title = li.label + " {Click to Select}";
					
					
					var thisObj = this;
					RegisterEvent(tempDiv, "mouseover", this, "BreadcrumbMouseOver", false, false, li.id );
					RegisterEvent(tempDiv, "click", this, "BreadcrumbMouseSelect", false, false, li );
					
					returnDiv.appendChild(tempDiv);
				}
				else
				{
					if (highCount>1)
					{
						moreTooltip += " | ";
					}					
					moreTooltip += li.label;
				}
				
				highCount ++;
				totalCount ++;
			}			
			
			if (highCount>1)
			{
				var moreDiv = createDiv("more", true);
				moreDiv.title = moreTooltip;
				moreDiv.innerHTML = "[" + (highCount-1) + " more]";
				returnDiv.appendChild(moreDiv);
			}			
		}
		
		if (totalCount==0)
		{
				var moreDiv = createDiv("colname", true);
				moreDiv.title = "No selections or highlights in " + this.m_parentColumn.m_Label;
				moreDiv.innerHTML = "(" + this.m_parentColumn.m_Label + ")";
				returnDiv.appendChild(moreDiv);			
		}
		
		return returnDiv;
	},
	
BreadcrumbMouseOver: function(e, element, name, params)
	{
		this.ScrollIdIntoView(params);
	},
	
BreadcrumbMouseUnSelect:function(e, element, name, li)
	{
			this.m_Selected[li.id] = false;
			this.UpdateListItems();
			
		mSpaceApplication.FireEvent("Column.UnSelectItem", { column: this.m_parentColumn, listitem: li });			
	},
	
BreadcrumbMouseSelect:function(e, element, name, li)
	{
			this.m_Selected[li.id] = li;
			this.UpdateListItems();
			
		mSpaceApplication.FireEvent("Column.SelectItem", { column: this.m_parentColumn, listitem: li });			
	},	
	
ScrollIdIntoView: function(eventParams)
	{		
		this.m_controlSurface.scrollTop = (eventParams-1)* this.m_listItemHeight;
		this.m_scrollSpacerDiv.style.height = (this.m_controlSurface.scrollTop) + "px";
		if (this.m_controlSurface.scrollTop==0)
		{
			this.m_scrollSpacerDiv.style.display = "none";
		}
		else
		{
			this.m_scrollSpacerDiv.style.display = "";
		}
		this.UpdateListItems();
	},
	
ScrollItemIntoView: function(eventParams)
	{
		if ((eventParams.uri) && (eventParams.column) && (eventParams.column=this.m_parentColumn.m_Uri))
		{
			alert(eventParams.uri);
			this.ScrollIntoView(eventParams.uri);
			
		}
	},
	
LoadVisibleListItems: function(colDetails, clear)
	{
		if (clear)
		{
			if (colDetails.Items)
			{
				this.m_Items = colDetails.Items;
			}
		}
		else
		{
			if (colDetails.Items)
			{
				for (id in colDetails.Items)
				{
					this.m_Items[id] = colDetails.Items[id];													
				}
			}
		}
		
		this.ShowAllItems();
		
		this.UpdateListItems();
	},
	
GetSelectedItems: function()
	{
		var arr = new Array();
		if (this.m_Selected)
		{
			for (id in this.m_Selected)
			{
				if (this.m_Selected[id])				
					arr.push(this.m_Selected[id]);													
			}
		}		
		
		return arr;
	},
	
Reset: function()
	{
		this.m_Selected = {};
		this.m_Highlighted = {};
		this.m_Items = new Array();
	},
	
SetTextFilter: function(filterText)
	{
		if (this.currentFilterText != filterText)
		{
			this.currentFilterText = filterText;
		
			this.ApplyTextFilter(true);			
		}
		
	},
	
ClearTextFilter: function()
	{
		if (this.currentFilterText!="")
		{
			this.currentFilterText = "";
		
			this.ApplyTextFilter(true);
		}
		
	},	
	
ApplyTextFilter: function(change)
	{
		
		
		if (this.allItemsLoaded)
		{
			if (change && (this.currentFilterText==""))
			{
				this.ShowAllItems();
			}
			else
			{
				this.LocalTextFilter();
			}
			
			this.Resize();
			this.UpdateListItems();
			return;
		}
		else
		{
			if (this.ssFilterToutId!=-1)
			{
				clearTimeout(this.ssFilterToutId);
			}
			
			
			var t = this;
			this.ssFilterToutId = setTimeout(function() { t.ServerTextFilter(change); }, 1000);
			
		}
		
		
		
	},
	
LocalTextFilter: function()
	{
		var filterArray = this.currentFilterText.toLowerCase().split("+");
		var matchesWord = false;
		this.m_DisplayItems = new Array();
		this.disItemCount = 0;
		for (var x =0; x<filterArray.length;x++)
		{
			var filterWord = filterArray[x];
			if (filterWord!="")
			{
				for (id in this.m_Items)
				{
					var li = this.m_Items[id];

					// Filter anywhere
					if (li.label.toLowerCase().indexOf(filterWord)!=-1)
					{
						this.disItemCount ++;
						this.m_DisplayItems[this.disItemCount] = id;
					}

				}
			}
		}		
	},
	
ServerTextFilter: function(change)
	{
		this.ssFilterToutId = -1;
		if (this.ssFilterText!=this.currentFilterText || change)
		{
			var startItem = Math.ceil(this.m_controlSurface.scrollTop/this.m_listItemHeight);
			mSpaceApplication.FireEvent("List.LoadPartialItems", { col: this.m_parentColumn, start: startItem, clear: true });
		}
			
	},
	
ShowAllItems: function()
	{
		this.m_DisplayItems = new Array();
		this.disItemCount = 0;
		for (id in this.m_Items)
		{
			this.disItemCount ++;
			this.m_DisplayItems[this.disItemCount] = id;
		}
	},
	
GetFilterUrlText: function()
	{
		var rS = "";
		if ((!this.allItemsLoaded) && (this.currentFilterText!=""))
		{
			rS = "&scol[]=scol:" + this.m_parentColumn.m_Uri + "&scol[]=val:" + URLEncode(this.currentFilterText);
		}
		
		return rS;
	}
	
}

