﻿var globalHCCRenderCount = 0;
var globalHCCRenderComplete = false;
var globalHCCCurrentWidth;
var globalCategoriesMovesHistory = new CategoriesMovesHistory();
var EnterpriseCommunitiesGlobalShellBGColour = "white";
var EnterpriseCommunitiesShowMultipleHCC = false;
var globalLoadCategories = false;

function ConceptTreeHorizontalCategoriesControl_Render_Wrapped(_width, _containerClientID, _menuID, _cbreference)
{
	if(_globalCookieTestResult)
	{
		var control = document.getElementById(_containerClientID); //the div containing the menu and bookmarks
		var menu = document.getElementById(_menuID);
		// this function ensures that the control has been rendered before proceeding
		if (control == null || menu == null)
		{
			setTimeout("ConceptTreeHorizontalCategoriesControl_Render("+_width+")", 200);
		}
		else
		{
		  if (_width)
		  {
		    control.style.width = _width + 'px';
		    globalHCCCurrentWidth = _width;
		  }
			var availableWidth = HorizontalCategoriesControl_CalculateAvailableWidth(control, _width);

		  menu.firstChild.style.visibility = "hidden";
		  
      var controlwidth = control.clientWidth || control.offsetWidth;
			// the controlwidth will be 0 if the control hasn't finished rendering so wait until it has
      if (controlwidth <= 0 && globalHCCRenderCount != 10)
      {
        if (globalVisibleTab.indexOf("myprofile") != -1 || globalVisibleTab.indexOf("genes") != -1)
					setTimeout("ConceptTreeHorizontalCategoriesControl_Render("+_width+")", 130);
				else
					return;
		  }
      else
      {
				// reset glob var
        globalHCCRenderCount = 0;
        
        if (!_width) // because it was set earlier in this method. Shouldn't matter, it should just set it to the same again
          globalHCCCurrentWidth = controlwidth;
        
			  // check to see if the menu and book markcontrol fit in the HCC
  	    
			  // if they don't fit we need to redraw the menu with less items
			  var menuitems = menu.getElementsByTagName("td");
  			   
			  var length = menuitems[0].clientWidth;
			  for (var index=1; index < menuitems.length; index++)
			  {
				  length += "," + menuitems[index].clientWidth;
			  }
//			  var bBin = document.getElementById("TCC_HorizontalCategoriesControl3_BreadBin");
//			  if(bBin != null)
//				  bBin.style.display = "none";
			  // this will be the index of the first item to be added to "more"    
			  var args = 'Action=RenderMenu';
			  args += '|availableWidth='+availableWidth;
			  args += '|lengthStr='+length;
			  eval(_cbreference); // callback to categories control
			}
		}
  }
}


function EnterpriseCommunitiesHorizontalCategoriesControl_Render_Wrapped(_width, _containerClientID, _menuID, _cbreference)
{

	if(_globalCookieTestResult)
	{
		var control = document.getElementById(_containerClientID); //the div containing the menu and bookmarks
		var menu = document.getElementById(_menuID);
		// this function ensures that the control has been rendered before proceeding
		if (control == null || menu == null)
		{
			setTimeout("EnterpriseCommunitiesHorizontalCategoriesControl_Render("+_width+")", 200);
		}
		else
		{
		  if (_width)
		  {
		    control.style.width = _width + 'px';
		    globalHCCCurrentWidth = _width;
		  }
			var availableWidth = HorizontalCategoriesControl_CalculateAvailableWidth(control, _width);

		  menu.firstChild.style.visibility = "hidden";
		  
      var controlwidth = control.clientWidth || control.offsetWidth;
			// the controlwidth will be 0 if the control hasn't finished rendering so wait until it has
      if (controlwidth <= 0 && globalHCCRenderCount != 10)
      {
        if (globalVisibleTab.indexOf("myprofile") != -1 || globalVisibleTab.indexOf("genes") != -1)
					setTimeout("EnterpriseCommunitiesHorizontalCategoriesControl_Render("+_width+")", 130);
				else
					return;
		  }
      else
      {
				// reset glob var
        globalHCCRenderCount = 0;
        
        if (!_width) // because it was set earlier in this method. Shouldn't matter, it should just set it to the same again
          globalHCCCurrentWidth = controlwidth;
        
			  // check to see if the menu and book markcontrol fit in the HCC
  	    
			  // if they don't fit we need to redraw the menu with less items
			  var menuitems = menu.getElementsByTagName("td");
  			   
			  var length = menuitems[0].clientWidth;
			  for (var index=1; index < menuitems.length; index++)
			  {
				  length += "," + menuitems[index].clientWidth;
			  }
//			  var bBin = document.getElementById("TCC_HorizontalCategoriesControl1_BreadBin");
//			  if(bBin != null)
//				  bBin.style.display = "none";
			  // this will be the index of the first item to be added to "more"    
			  var args = 'Action=RenderMenu';
			  args += '|availableWidth='+availableWidth;
			  args += '|lengthStr='+length;
			  eval(_cbreference); // callback to categories control
			}
		}
  }
}




function HorizontalCategoriesControl_Reload_Wrapped(_containerClientID, _menuID, _cbreference)
{
	var args = 'Action=ReloadMenu';
	eval(_cbreference);
}

function HorizontalCategoriesControl_CalculateAvailableWidth(_control, _width)
{
	var controlWidth = _width || _control.clientWidth || _control.offsetWidth;
	return availableWidth = controlWidth - 52;//allow an extra 52px for the "more" item
}

function HorizontalCategoriesControl_Resize_Wrapped(_width, _containerClientID, _menuID, _cbreference)
{
  var control = document.getElementById(_containerClientID); //the div containing the menu and bookmarks
  var menu = document.getElementById(_menuID);
  
  if (control != null && menu != null)
  {
		if (_width)
		  control.style.width = _width + 'px';
    var availableWidth = HorizontalCategoriesControl_CalculateAvailableWidth(control, _width);
    
    var args = 'Action=ResizeMenu';
    args += '|availableWidth='+availableWidth;
		eval(_cbreference); // callback to categories control

  }
}


function ConceptTreeHorizontalCategoriesControl_MenuItemSelected_Wrapped(_sender, _eventArgs, _topLevelTopicId, _cbreference, _loggedInUser)
{
    var item = _eventArgs.get_item();
    var ID = item.ID;
    var treeName = ''; 
    var treeToSelect = '';

    // Either selected the 'Your Maps' or category concept tree
    if (ID.indexOf('personal') > -1 || ID.indexOf('Personal') > -1)
    {
        treeToSelect = 'Personal';
        treeName = null;
    }
    else
    {
        treeToSelect = 'CS_' + ID;
        treeName = item.Text;
    }

    if (window.KGConceptsContainerControl_SwitchTabs)
        KGConceptsContainerControl_SwitchTabs(treeToSelect, treeName);
        
    SetSessionProperty('ConceptTreeTabbedView_SelectedTab', treeToSelect);      
    
    var currentLocation = window.location.href;
    var hostURL = currentLocation.substring(0, currentLocation.lastIndexOf('/') + 1);
    var currentPage = currentLocation.substring(currentLocation.lastIndexOf('/')+1, currentLocation.length).toLowerCase();
    var hostURLForRedirect = currentLocation.substring(0, currentLocation.lastIndexOf('/') + 1);
        
	if(currentPage == 'Home.aspx' || currentPage == 'home.aspx' || currentPage.match('home') == 'home' || currentPage.match('Home') == 'Home')
	{
	
	    if (item.Text.indexOf('Your Maps') > -1)
	    {
            SetSessionProperty('ConceptTopics_SelectedTopicName', 'Personal');
            SetSessionProperty('ConceptTopics_SelectedTopicGroupId', null);
            SetSessionProperty('ConceptKGCurrentGroupID', treeToSelect);
            SetSessionProperty('ConceptTopics_SelectedTopicGroupId', null);
            SetSessionProperty('ConceptTopics_SelectedTopicName', null);	        
	        
	    }
	    else	   	    
	    {
		    SetSessionProperty('ConceptTopics_SelectedTopicName', item.Text.replace('&','%26'));
		    SetSessionProperty('ConceptTopics_SelectedTopicGroupId', item.ID);
		    SetSessionProperty('ConceptKGCurrentGroupID', ID);
		}
		
    }
    
      
        
    // Make sure we callback to re-render the menu    
    var args = 'Action=RenderMenu|availableWidth=0|lengthStr=0';
    eval(_cbreference);         
        
}



function EnterpriseCommunitiesHorizontalCategoriesControl_MenuItemSelected_Wrapped(_sender, _eventArgs, _topLevelTopicId, _cbreference, _loggedInUser)
{

  if (window.CloseApplicationControl && m_applicationControlOpen && !m_appForceOpen)
  {
    CloseApplicationControl();
  }
  var currentLocation = window.location.href;
  //var currentPage = currentLocation.substring(currentLocation.lastIndexOf('/')+1, currentLocation.length).toLowerCase();
  //var hostURLForRedirect = currentLocation.substring(0, currentLocation.lastIndexOf('/') + 1);
  if(m_bEditable)
  {
		globalCatClick = true;
	}
  var hostURLForRedirect;
  var currentPage;
  if(currentLocation.indexOf("orderSuccessful") > 0)
  {
    currentPage = currentLocation.substring(currentLocation.indexOf("orderSuccessful"));
    hostURLForRedirect = currentLocation.substring(0, currentLocation.indexOf("orderSuccessful"));
  }
  else if (currentLocation.indexOf("orderFailed") > 0)
  {
    currentPage = currentLocation.substring(currentLocation.indexOf("orderFailed"));
    hostURLForRedirect = currentLocation.substring(0, currentLocation.indexOf("orderFailed"));
  }
  else
  {
    currentPage = currentLocation.substring(currentLocation.lastIndexOf('/')+1, currentLocation.length).toLowerCase();
    hostURLForRedirect = currentLocation.substring(0, currentLocation.lastIndexOf('/') + 1);
  }
  
  var item = _eventArgs.get_item();
  var cb = document.getElementById('CategoriesTreeCheckbox');
  
  if(item.Text == "" || item.Text == undefined)
  {		
		return;
	}
	
	if (isAuthenticated() == true)
  {
    var userID = WM_readCookie('UserID');
	  WM_setCookie('User' + userID + '_category', item.ID, m_catCookieExpiration);
	}
  
  var allowCallback = false;
  
  if(allowCallback == true && currentPage.toLowerCase().indexOf('apphome.aspx') == -1 &&
  (currentPage == 'Home.aspx' || currentPage == 'home.aspx' || currentPage.match('home') == 'home' || currentPage.match('Home') == 'Home'))
	{
	  if (window.Global_SemanticTreeHolderID && !Global_SemanticTreeHolderID)
		{
			//NavigationControl not ready, switch tabs calls will cause problems
			_eventArgs.set_cancel(true);
			return;
		}
		if(m_bEditable == true)
			SwitchEditableFlag();
		var homeLinkClicked = 0;
		
		globalFeaturedCategory = "true";
		
		var keys = 'Topics_SelectedTopicName|Topics_SelectedTopicGroupId|Topics_CategoryJustClicked|IndexedDocListMode|SelectedKnowdeSiblingInfo'
    var values = item.Text.replace('&','%26') + '|' + item.ID + '|true|Category|';
    SetSessionProperty(keys, values, true);
    
		setGenesTabMode("Category");
		_sender.IsSelecting = true;
		//ChangeTabFromMapView('genes', 'Genes'); //ChangeTab("genes", "genes", true);	
		setTimeout("LHNav_ChangeTab('genes', 'Genes Search', '');", 100);
		_sender.IsSelecting = false; // could set these further apart, but they're only used in the ChangeTab function atm.
		//  if move set to false, make sure you catch it in early returns
		// could pass it in to ChangeTab - but then there are lots of other calls to ChangeTab that don't need that parameter
		//TabContainerControl_CallbackDirection("genes");
		
		if(cb != null)
		{
			cb.disabled = false;
			HorizontalCategoriesControl_DisableCheckBox(cb);
			HorizontalCategoriesControl_OnCheckboxClick(cb, item);
		}

		// updates here may also need to go in hk.js HomeLinkClicked for clicking our top left icon
		//SetSessionProperty('ConceptTabbedView_SelectedTab', 'CS_' + _topLevelTopicId);
		// new default map will be load, clear old session
		//SetSessionProperty('SelectedKnowdeSiblingInfo', '');	
	  
		// reload the home page, otherwise redirect to home page
		if (homeLinkClicked == 0 && (currentPage.indexOf('home') > -1 || currentPage.length == 0))
		{
	        
          if ((item.ParentItem != null || item.ParentMenu.MenuId == HorizontalCategoriesControl_getBreadcrumbMenuID()) && EnterpriseCommunitiesShowMultipleHCC == true )
          {
            // the clicked item is in a submenu.  Show the breadcrumb trail
			var args = 'Action=ShowBreadcrumbTrail';
		    eval(_cbreference); // callback to categories control
			}
			else
			{
			  // clear the breadcrumb trail
		    HorizontalCategoriesControl_UpdateBreadcrumbTrail("");
		  }
      
			//draw the tree
			//KGNavigationControl_SwitchTabs('CS_' + _topLevelTopicId, item.Text);
			//KGNavigationControl_TreeNavBarRePopulate();
		  
			// select the Category Home tab
			globalIndexedDocsPageLoaded = false;
			//KGTabbedWindowsControl_CallbackTrigger("CategorySelected", null, false);
	    
			/*SetSessionProperty('KGMapViewCollapsed',false);
			var mapViewCollapsed = !globalMapPaneOpen;
			if (mapViewCollapsed == true) // map view is not visible - open the splitter
				DoExpandMapViewPane();*/
		}
		else
		{ 
//			SetSessionProperty('ConceptTabbedView_SelectedTab', 'Personal')
//			KGNavigationControl_SwitchTabs('Personal');
			var hostURL = currentLocation.substring(0, currentLocation.lastIndexOf('/') + 1);
			if(currentPage == 'Home.aspx' || currentPage == 'home.aspx' || currentPage.match('home') == 'home' || currentPage.match('Home') == 'Home')
			{
				SetSessionProperty('Topics_SelectedTopicName', item.Text.replace('&','%26'));
				SetSessionProperty('Topics_SelectedTopicGroupId', item.ID);
				SetSessionProperty('Topics_CategoryJustClicked', true);
		
//				KGNavigationControl_TreeNavBarRePopulate();
				globalIndexedDocsPageLoaded = false;
			  //KGTabbedWindowsControl_CallbackTrigger("CategorySelected", null, false);
				/*SetSessionProperty('KGMapViewCollapsed',false);
				var mapViewCollapsed = !globalMapPaneOpen;
				if (mapViewCollapsed == true) // map view is not visible - open the splitter
					DoExpandMapViewPane();*/
					
				// clear the breadcrumb trail
		    HorizontalCategoriesControl_UpdateBreadcrumbTrail("");
			}
			else
			{
				window.location = hostURL + 'home.aspx';
			}

		}
			  
	  // update tab selection
	  if (_sender.SelectedItem != null)
	  {
			// update tab selection
			// UNHIGLIGHT 
			HorizontalCategoriesControl_Unhighlight(_sender);
		  
		  // HIGHLIGHT 
		  HorizontalCategoriesControl_HighlightItem(item);
		  
			//UPDATE TAB & RENDER
			_sender.SelectedItem = item; // selected item should be the actual selected item not the top level item, otherwise unhighlight doesn't deselect the children, also sign in sign up could get the selected item id as "more"
			_sender.render();
	  }
	}
	else
	{
		globalFeaturedCategory = "true";
		var item = _eventArgs.get_item();
		if(item.ID != -1)
		{
		  if(currentPage.toLowerCase().indexOf("apphome.aspx") == -1)
			  window.location = hostURLForRedirect + 'home.aspx?category=' + item.ID;
			else
			  window.location = hostURLForRedirect + 'AppHome.aspx?category=' + item.ID;
		}
		else
		{
		  SetSessionForHomeClick();
			if (_loggedInUser == 'False')
			{
				// hide semantic tree, would be deal with in server side
			}
			else
				SetSessionProperty('Home_Link_Clicked', 'true');
			window.location = hostURLForRedirect + 'home.aspx';
		}
	}	
}

function EnterpriseCommunitiesHorizontalCategoriesControl_MenuItemMouseOver(_sender, _eventArgs)
{
//  var menuItem = _eventArgs.get_item();
//  if (menuItem.getItems().length > 0)//if the item has children to show
//  {
//    var menuGroupID = HorizontalCategoriesControl_GetMenuItemElementID(menuItem);
//    //HorizontalCategoriesControl_ShowMenuGroup(menuGroupID, 0, menuItem.ParentIndex);
//  }
}


function EnterpriseCommunitiesHorizontalCategoriesControl_MenuItemMouseOut(_sender, _eventArgs)
{
}

function ConceptTreeHorizontalCategoriesControl_MenuItemMouseOver(_sender, _eventArgs)
{
//  var menuItem = _eventArgs.get_item();
//  if (menuItem.getItems().length > 0)//if the item has children to show
//  {
//    var menuGroupID = HorizontalCategoriesControl_GetMenuItemElementID(menuItem);
//    HorizontalCategoriesControl_ShowMenuGroup(menuGroupID, 0, menuItem.ParentIndex);
//  }
}


function ConceptTreeHorizontalCategoriesControl_MenuItemMouseOut(_sender, _eventArgs)
{
}



function EnterpriseCommunitiesHorizontalCategoriesControl_CallbackDone_Wrapped(_args, _context, _thisClientID)
{



  // Check for a session time out before completing the callback
  if (CheckSessionTimeout())
    return;
    
  var argsSplit = _args.split('[@|@]');
  var action = argsSplit[0];
  switch (action)
  {
    case "RenderMenu":
    case "ResizeMenu":
    case "ReloadMenu":
      globalHCCRenderComplete = true;
      EnterpriseCommunitiesHorizontalCategoriesControl_UpdateMenu(argsSplit[1]);
      m_readyForResize = true;
      if (action == "RenderMenu" && EnterpriseCommunitiesShowMultipleHCC == true )
      { // incase a breadcrumb trail has been loaded and is still hidden. We only need this in the initial render
        HorizontalCategoriesControl_ShowLoadedBreadcrumbTrail();
      }
    break;
    case "ShowBreadcrumbTrail":
      HorizontalCategoriesControl_UpdateBreadcrumbTrail(argsSplit[1]);
      break;
    case "MoveSubCommunitySpace":
      // check for exceptions
      if (_args.indexOf("Exception") == 0 || _args.length == 0)
      {
        HorizontalCategoriesControl_CallbackError(_args, _context);
        return;
        // looking for indexOf == 0 instead of > -1 incase it's genuine html that happens to contain 'Exception' in there
        // e.g. a user called "... Exceptional ..." 
      }
      HorizontalCategoriesControl_HandleMoveCalbackDone(argsSplit[1]);
      break;
  }
}

function ConceptTreeHorizontalCategoriesControl_CallbackDone_Wrapped(_args, _context, _thisClientID)
{

  // Check for a session time out before completing the callback
  if (CheckSessionTimeout())
    return;
 
   
  var argsSplit = _args.split('[@|@]');
  var action = argsSplit[0];
  switch (action)
  {
    case "RenderMenu":
    case "ResizeMenu":
    case "ReloadMenu":
      globalHCCRenderComplete = true;
      ConceptTreeHorizontalCategoriesControl_UpdateMenu(argsSplit[1]);
      m_readyForResize = true;
      if (action == "RenderMenu" && EnterpriseCommunitiesShowMultipleHCC == true)
      { // incase a breadcrumb trail has been loaded and is still hidden. We only need this in the initial render
        HorizontalCategoriesControl_ShowLoadedBreadcrumbTrail();
      }
    break;
    case "ShowBreadcrumbTrail":
      HorizontalCategoriesControl_UpdateBreadcrumbTrail(argsSplit[1]);
      break;
    case "MoveSubCommunitySpace":
      // check for exceptions
      if (_args.indexOf("Exception") == 0 || _args.length == 0)
      {
        HorizontalCategoriesControl_CallbackError(_args, _context);
        return;
        // looking for indexOf == 0 instead of > -1 incase it's genuine html that happens to contain 'Exception' in there
        // e.g. a user called "... Exceptional ..." 
      }
      HorizontalCategoriesControl_HandleMoveCalbackDone(argsSplit[1]);
      break;
  }
}

function EnterpriseCommunitiesHorizontalCategoriesControl_CallbackError(_args, _context)
{
  var alertMessage = "The EnterpriseCommunitiesHorizontalCategoriesControl encountered an error. \n\n" + _args;
  alert(alertMessage);
}

function ConceptTreeHorizontalCategoriesControl_CallbackError(_args, _context)
{
  var alertMessage = "The ConceptTreeHorizontalCategoriesControl encountered an error. \n\n" + _args;
  alert(alertMessage);
}
		
function HorizontalCategoriesControl_GetBreadbin()
{
  var breadbinId = HorizontalCategoriesControl_GetBreadbinId();
  return document.getElementById(breadbinId);
}

function HorizontalCategoriesControl_HideBreadcrumbTrail(breadbin)
{
  // set display none - can still get it back if we need to, unless/until it gets clears
  // don't need to pass in breadbin
  if (!breadbin)
    breadbin = HorizontalCategoriesControl_GetBreadbin();
    
  if (breadbin)
  {
    breadbin.style.display = "none";
    
    // move the genes tab content up
    var genesTab = document.getElementById("TCC_genes");
    if (genesTab)
      genesTab.style.borderTop = "solid 35px white";
      // can't do this with css - see comment in HorizontalCategoriesControl_ShowLoadedBreadcrumbTrail
  }
}

function HorizontalCategoriesControl_ShowLoadedBreadcrumbTrail(breadbin)
{

  // set display - just showing one that we've already loaded, only if there is one 
  // don't need to pass in breadbin
  if (!breadbin)
    breadbin = HorizontalCategoriesControl_GetBreadbin();
    
  var breadcrumbMenu = HorizontalCategoriesControl_GetBreadcrumbMenu();
  // test whether the breadcrumb menu has been loaded
  // note it could be loaded by clicking an item; or it could be loaded (but hidden) in the initial load if there was a category in the query string
  //    so it's better to actually check the menu rather than trying to set a variable to test it
  if (breadcrumbMenu && breadcrumbMenu.element && breadcrumbMenu.element.innerHTML != "" && breadcrumbMenu.get_items().get_length() > 0)
  {
    // show the breadcrumbs
    breadbin.style.display = "block";
    
    // move the genes tab content down
    var genesTab = document.getElementById("TCC_genes");
    if (genesTab)
      genesTab.style.borderTop = "solid 42px white";
      // can't use css classes because there's another TabContainerShown/Hidden class for the tab
      // can't set 2 classes for the tab and update this one because in some places the class gets overwritten (className = "TabContainerShown")
      //    if I changed all those to 'replace', would have to hope no one added another in future
      //genesTab.className.replace("TabUnderBreadcrumbs", "TabUnderHcc");
  }
}

function HorizontalCategoriesControl_UpdateBreadcrumbTrail(_args)
{
  // call with _args = "" to clear it
  var breadbin = HorizontalCategoriesControl_GetBreadbin();
  if (breadbin) 
  {
    var menu = HorizontalCategoriesControl_GetBreadcrumbMenu();
    menu.Hide(); 
      // sometimes there's an ExpandGroup timeout set on the menu, so it calls ComponentArt_Menu_ExpandGroup after the menu's been written over here, and causes a runtime error 'ParentItemElement' is null
      // the timeout we need to clear is menu.ExpandTimeoutId (and probably menu.ExpandTimeoutGroupIndex) //clearTimeout(menu.ExpandTimeoutId);
      // but calling Hide clears those and more, incase there's anything else that could go wrong
    
  
    updateHolder(_args, breadbin);
    if (_args) // call with _args = "" to clear it
      HorizontalCategoriesControl_ShowLoadedBreadcrumbTrail(breadbin)
    else 
      HorizontalCategoriesControl_HideBreadcrumbTrail(breadbin);
  }
}

function HorizontalCategoriesControl_GetMenu()
{
  return eval(HorizontalCategoriesControl_getMenuID());
}

function HorizontalCategoriesControl_GetBreadcrumbMenu()
{
  return eval(HorizontalCategoriesControl_getBreadcrumbMenuID());
}

function HorizontalCategoriesControl_Unhighlight(menu)
{
  menu.SelectedItem.IsSelected = false;
	var tempSenderIterator = menu.SelectedItem;
	var hasSenderParent = new Boolean(true);
	while(hasSenderParent)
	{
		if(tempSenderIterator.ParentItem != null)
		{
			tempSenderIterator.ParentItem.IsSelected = false;
			tempSenderIterator = tempSenderIterator.ParentItem;
		}
		else
		{
			hasSenderParent = false;
		}
	}
	//need to render the menu after doing this (ComponentArt method)
	//but don't put it in this method, because in an item select, we unhighlight then rehighlight
	//  and don't want to call render twice 
}

function HorizontalCategoriesControl_HighlightItem(_item)
{
  _item.IsSelected = true;
	var tempItemIterator = _item;
	var hasItemParent = new Boolean(true);
	while(hasItemParent)
	{
		if(tempItemIterator.ParentItem != null)
		{
			tempItemIterator.ParentItem.IsSelected = true;
			tempItemIterator = tempItemIterator.ParentItem;
		}
		else
		{
			hasItemParent = false;
		}
	}
	//need to render the menu after doing this (ComponentArt method)
	//but don't put it in this method, because in an item select, we unhighlight then rehighlight
	//  and don't want to call render twice 
}


function ConceptTreeHorizontalCategoriesControl_UpdateMenu_Wrapped(_args, _menuHolderClientID, _menuClientID)
{
  var caMenu = HorizontalCategoriesControl_GetMenu();
  caMenu.Hide(); // hide the existing menu to make sure any timeouts get cleared before the menu is written over
  clearTimeout(caMenu.PropertyCalculationTimeoutId);
    
	var holder = document.getElementById(_menuHolderClientID);
  updateHolder(_args, holder);
  var menu = document.getElementById(_menuClientID);
  menu.style.display = "inline";
  
  // if we do a show/hide here in the js instead of during the callback, it's easier to switch it back later
  //    e.g. if we change tabs and there isn't a callback to the categories control
  // so at the server we always show the selection (as long as selection is enabled)
  if (HorizontalCategoriesControl_IsShowSelection())
  {
    //HorizontalCategoriesControl_ShowSelection(); // shown by default
  }
  else
  {
    HorizontalCategoriesControl_HideSelection();
  }
}



function EnterpriseCommunitiesHorizontalCategoriesControl_UpdateMenu_Wrapped(_args, _menuHolderClientID, _menuClientID)
{
  var caMenu = HorizontalCategoriesControl_GetMenu();
  caMenu.Hide(); // hide the existing menu to make sure any timeouts get cleared before the menu is written over
  clearTimeout(caMenu.PropertyCalculationTimeoutId);
    
	var holder = document.getElementById(_menuHolderClientID);
  updateHolder(_args, holder);
  var menu = document.getElementById(_menuClientID);
  menu.style.display = "inline";
  
  // if we do a show/hide here in the js instead of during the callback, it's easier to switch it back later
  //    e.g. if we change tabs and there isn't a callback to the categories control
  // so at the server we always show the selection (as long as selection is enabled)
  if (HorizontalCategoriesControl_IsShowSelection())
  {
//    HorizontalCategoriesControl_ShowSelection(); // shown by default
  }
  else
  {
    HorizontalCategoriesControl_HideSelection();
  }
}

function HorizontalCategoriesControl_IsShowSelection()
{
	// allow show which category is selected if we're on the home page and the genes tab is selected
	//var currentLocation = window.location.href;
	//var currentPage = currentLocation.substring(currentLocation.lastIndexOf('/')+1, currentLocation.length).toLowerCase();
	//if (currentPage.indexOf('home') != -1 && globalVisibleTab.toLowerCase().indexOf('genes') != -1)
	
	// if we're not on the home page, selection is disabled for the menu at the server, so it doesn't matter whether we show or hide it, you still won't see it
	if (window.globalVisibleTab && globalVisibleTab.toLowerCase().indexOf('genes') != -1)
	  return true;
	else
    return false;
}

function HorizontalCategoriesControl_ShowSelection()
{
  var menu = HorizontalCategoriesControl_GetMenu();
  if (menu.SelectedItem && !menu.IsSelecting) // if a select is in progress, save some work rendering the menu, 
                         // since the selected item is already out of date and it'll be redone anyway in the select
  {
    HorizontalCategoriesControl_HighlightItem(menu.SelectedItem);
    menu.render();
  }
}

function HorizontalCategoriesControl_HideSelection()
{
  var menu = HorizontalCategoriesControl_GetMenu();
  HorizontalCategoriesControl_Unhighlight(menu);
  menu.render();
  // don't actually unselect it by changing the SelectedItem, this way we can put it back easily if you switch tabs
}

function updateHolder(_args, _holder)
{
	var cdatas = _args.split('<![CDATA[');
  
  if (_holder != null)
  {
	  _holder.innerHTML = _args;
	  
	  var z = 0;
	  for(z = 1; z < cdatas.length; z++)
	  {
		  var posStart = cdatas[z].indexOf('window');      
		  var posEnd = cdatas[z].lastIndexOf('}') + 1;
		  if(posStart > -1 && posEnd > -1)
		  {
		  	if (posEnd < posStart)
		  	{
		      posEnd = cdatas[z].lastIndexOf(']') + 1;
		      var jscript = cdatas[z].substring(posStart, posEnd);
			    if(jscript.length != 0)
			    {
			      eval(jscript);
			    }
		    }
		    else
		    {
			    var jscript = cdatas[z].substring(posStart, posEnd);
			    if(jscript.length != 0)
			    {
				    eval(jscript);
				    var posNameStart = jscript.indexOf('window');
				    var posNameEnd = jscript.indexOf('=');
				    if(posNameStart > -1 && posNameEnd > -1)
				    {
				      var functionName = jscript.substring(posNameStart, posNameEnd);
				      eval(functionName+'()');
				    }
			    }
			  }
		  }
	  }
	}
}

function HorizontalCategoriesControl_ProcessCallBackError_Wrapped(_categoriesControlId)
{
  try
  {
    // Check for a session time out before completing the callback and before checking for exceptions
    if (CheckSessionTimeout())
      return;

    var holder = document.getElementById(_categoriesControlId);
    if (holder != null)
        holder.innerHTML = 'Exception occurred.';
  }
  catch (e) 
  {
    alert("An exception occurred in the script. Error name: " + e.name + ". Error message: " + e.message); 
    //debugger;
  }
}

function HorizontalCategoriesControl_DisableCheckBox_Wrapped(_checkbox, _menu)
{ 
  // update client template to make checkbox checked/unchecked
  if (_menu && _menu.ClientTemplates)
  { 
    var clientTemplate = _menu.ClientTemplates[0][1];
    if (clientTemplate)
    {
      if (_checkbox.disabled && clientTemplate.indexOf('display:none') == -1)
        _menu.ClientTemplates[0][1] = clientTemplate.replace('display:block','display:none');
      if (!_checkbox.disabled && clientTemplate.indexOf('display:none') > -1)
        _menu.ClientTemplates[0][1] = clientTemplate.replace('display:none','display:block');
    }
  }
}

function HorizontalCategoriesControl_ConfigureClicked(e, _itemID)
{
  CancelBubble(e);
  
  var strID = _itemID + "";
  KGPrivateSpaceAdminControl_OpenPrivateSpace(strID);
}

function HorizontalCategoriesControl_ShowMenuGroup(_menuGroupID, _iteration, _parentIndex)
{

  if (_iteration == null)
    _iteration = 0;
  else
    _iteration++;
  
  // get the menu group container
  var menuGroup = document.getElementById(_menuGroupID);
  if (menuGroup == null && _iteration <= 10)
  {
    // wait until it gets shown
    setTimeout("HorizontalCategoriesControl_ShowMenuGroup('" + _menuGroupID + "', " + _iteration + ", " + _parentIndex + ")", 100);
  }
  else if (_iteration > 10)
  {
    // this prevents the timeout from looping indefinitely if something goes wrong
    return;
  }
  else
  {
//  debugger;
    // ensure the container is the correct size
    menuGroup.parentNode.style.height = menuGroup.clientHeight + 2 + 'px';
    menuGroup.parentNode.style.width = menuGroup.clientWidth + 2 + 'px';
    //debugger;
    if (navigator.appName != "Microsoft Internet Explorer" && _parentIndex == -1)
    {
//			if(PanesAreSplit())
//			{
//				var paneTop = document.getElementById("Splitter1_pane_0");
//				if(paneTop != null)
//					menuGroup.parentNode.style.top = parseInt(paneTop.style.height.replace("px","")) + parseInt(menuGroup.parentNode.style.top.replace("px","")) + menuGroup.parentNode.offsetTop + 25;
//			}
//			else
//			{
//				menuGroup.parentNode.style.top = parseInt(menuGroup.parentNode.style.top.replace("px","")) + menuGroup.parentNode.offsetTop + 25;
    	//			}
    	menuGroup.parentNode.style.top = parseInt(menuGroup.parentNode.style.top.replace("px", "")) + menuGroup.parentNode.offsetTop + 25;
    }
  }
}

// finds the DOM element id for a component art menuItem object
function HorizontalCategoriesControl_GetMenuItemElementID(_menuItem)
{

  var indexArray = new Array();
  indexArray.push(_menuItem.get_index());
  
  while(_menuItem.ParentItem != null)
  {
    _menuItem = _menuItem.ParentItem;
    indexArray.push(_menuItem.get_index());
  }
  
  var groupId = _menuItem.ParentMenu.MenuId;
	var menuGroup = document.getElementById(groupId);
  var menuitems = menuGroup.getElementsByTagName("td");
  
  var menuItemElement = menuitems[indexArray[indexArray.length-1]];// get the menuItemElement at the index position given by the last array item
  groupId = "G" + menuItemElement.id;// get the id for the menuGroup that belongs to this menuItem
  indexArray.pop();// remove the last array item    

  
  if (groupId != "G")
  {   
  while (indexArray.length > 0)
  {
  	var menuGroup = document.getElementById(groupId);// get the menuGroup
    var menuitems = menuGroup.getElementsByTagName("nobr");// only one of these tags per menuitem (there are additional tds if a menu item has children)

    var menuItemElement = menuitems[indexArray[indexArray.length-1]];// get the menuItemElement at the index position given by the last array item
    
    // the dom nesting is different for items with children an those without.
    // first check the parentNode for the item id, then check higher up.
    menuItemId = menuItemElement.parentNode.id || menuItemElement.parentNode.parentNode.parentNode.parentNode.id
    groupId = "G" + menuItemId;// get the id for the menuGroup that belongs to this menuItem
    indexArray.pop();// remove the last array item    
  }
    }
  return groupId;
}

// the user clicked an up/down arrow to reorder the subcategories
function HorizontalCategoriesControl_MoverClick(_itemID, _dirn, _btn, e)
{
  try
  {
    CancelBubble(e);
    
    if (_btn.className.indexOf("Grey") > -1) // button is disabled, className is set to MoveUpGrey or MoveDownGrey
      return; 
    // the button still has onclick set even if it's grey and disabled - otherwise we need to update the onclick function sometimes when we reorder
    // and CancelBubble for grey button is good
      
    // get the item
    var menu = HorizontalCategoriesControl_GetMenu();
    var item = menu.FindItemById(_itemID);
    
    // double check it's moveable
    var oldPos = item.get_index();
    if (_dirn == "up" && oldPos == 0)
      return;
    else if (_dirn == "down" && oldPos == item.ParentItem.get_items().get_length())
      return;
    
    CollapseSubItems(item, menu, e);
    
    // life is easier if we always move something down, so we only need to keep track of the groupId(=item Id)
    //  - if the user clicked up, it's equivalent to clicking down on the item above
    var downItem;
    if (_dirn == "down")
      downItem = item;
    else if (_dirn == "up")
      downItem = HorizontalCategoriesControl_GetItemMovingDown(item);
    var groupId = downItem.GetProperty("ID");
    
    // move it ont ohe client first
    HorizontalCategoriesControl_MoveItemDownOnClientOnly(downItem, e);
    
    //fire callback
    //  callbacks might not reach the server in the expected order, so use the CategoriesMovesHistory object
    globalCategoriesMovesHistory.AddMove(groupId);
    var args = "Action=MoveSubCommunitySpace|MoveInfo=" + globalCategoriesMovesHistory.ToString();
    HorizontalCategoriesControl_CallbackTrigger(args);
  }
  catch(ex)
  { // try catch means don't fire the callback if something goes wrong
    alert("An exception occurred in the script. Error name: " + ex.name + ". Error message: " + ex.message); 
  }
}

function HorizontalCategoriesControl_GetItemMovingDown(_itemMovingUp)
{
  var pos = _itemMovingUp.get_index() - 1;
  return _itemMovingUp.ParentItem.Items()[pos];
}

function HorizontalCategoriesControl_MoveItemUpOnClientOnly(item)
{
  var downItem = HorizontalCategoriesControl_GetItemMovingDown(item);
  HorizontalCategoriesControl_MoveItemDownOnClientOnly(downItem);
}
    
function HorizontalCategoriesControl_MoveItemDownOnClientOnly(item, e)
{
  // updates how it looks on the client, but doesn't fire a callback

  var oldPos = item.get_index();
  var newPos = oldPos + 1;
  var parentItem = item.ParentItem; 
    
  // update the ComponentArt control/////////////////////////////
  var parentItems = parentItem.get_items();
  //    update the up/down arrows, if necessary
  if (oldPos == 0 || newPos == parentItems.get_length() - 1) // moved away from top or to the bottom
  {
    // for the CA - swap the clientTemplateIDs - so if you close the menu and reopen it it's swapped the greyed out arrows
    //    note - swap means we don't have to know what the templates are called here
    var otherItem = parentItem.Items()[newPos];
    
    var tempClientTemplateId = item.ClientTemplateId;
    item.ClientTemplateId = otherItem.ClientTemplateId;
    otherItem.ClientTemplateId = tempClientTemplateId;
  }
  //    move the item
  parentItems.insert(item, newPos); // don't remove it first - it makes CA throw an error if you move one then move another, the StorageIndex array goes wrong
  
  // render the changes///////////////////////////////////////////
  //    possible to call menu.render() - but it'll close all the sub-menus. 
  //    So either call render then reopen chain down to item's parent (I don't like the look of that)
  //    or update the UI without calling render (just a case of swapping 2 table rows)
  
  // update the UI without calling render
  var parentTable;
  try
  {
    var parentTableId = HorizontalCategoriesControl_GetMenuItemElementID(parentItem);
    parentTable = document.getElementById(parentTableId);
  }
  catch(ex)
  {// the HorizontalCategoriesControl_GetMenuItemElementID method might throw an error, if the menu's already closed
  }
  if (parentTable) // parent table might have been closed already
    SwapMoverTableRows(parentTable, oldPos, newPos)
}

function CollapseSubItems(_item, menu, e)
{
  // to change css class and close child items
  var itemElId = HorizontalCategoriesControl_GetMenuItemElementID(_item);
  if (itemElId.indexOf('G') == 0) // it's returning IDs starting with "G", which do usually exist, but the elements with the mouse out don't start with "G"
    itemElId = itemElId.substring(1);
    
  itemEl = document.getElementById(itemElId);
  ComponentArt_Menu_Support.ComponentArt_Menu_ItemMouseOut(itemEl, e);
  
  ComponentArt_Menu_Support.ComponentArt_Menu_CollapseGroup(menu, _item.StorageIndex);
}

function SwapMoverTableRows(_table, _oldPos, _newPos)
{
  var movingRow = _table.rows[_oldPos];
  var moveToRow = _table.rows[_newPos];  
  
  // handle the up and down arrows
  if (_oldPos == 0) // moving away from the top
  {
    // swap the class names for the up arrow - the one going to the top needs to be greyed out, the other doesn't
    SwapMoverProperties(movingRow, moveToRow, "MoveUp")
  }
  
  if (_newPos == _table.rows.length - 1) // moving to the bottom
  {
    // swap the class names for the down arrow - the one going to the bottom needs to be greyed out, the other doesn't
    SwapMoverProperties(movingRow, moveToRow, "MoveDown")
  }
  
  // swap the rows
  // _table.moveRow(oldPos, newPos); // is IE only 
  
  var movingRowClone = movingRow.cloneNode(true);
  var moveToRowClone = moveToRow.cloneNode(true);
  
  movingRow.parentNode.replaceChild(moveToRowClone, movingRow);
  moveToRow.parentNode.replaceChild(movingRowClone, moveToRow);
}

function SwapMoverProperties(_row1, _row2, _type)
{
  // we're relying on class names starting with _type (e.g. MoveUp, MoveUpGrey, MoveDownGrey)
  var mover1 = GetMoverFromParentEl(_row1, _type);
  var mover2 = GetMoverFromParentEl(_row2, _type);
    
  var tempClass = mover1.className;
  mover1.className = mover2.className;
  mover2.className = tempClass;
  
  var tempTitle = mover1.title;
  mover1.title = mover2.title;
  mover2.title = tempTitle;
}
    
function GetMoverFromParentEl(_parentEl, _type)
{
  // this works as long as the class names for the movers start with "MoveUp" or "MoveDown"
  var method = function(el){return (el.className.indexOf(_type) != -1);};
  var result = YAHOO.util.Dom.getElementsBy(method,null,_parentEl);
  return result[0];
}   

function HorizontalCategoriesControl_HandleMoveCalbackDone(_args)
{
  if (!_args || _args == "{}") 
    return;
  
  var retMsg = eval( '(' + _args + ')' );
  
  if (retMsg.Error == 'true')
  {
    var alertMessage = "Unfortunately Knowledge Genes was unable to save your changes due to an error.";
    alertMessage += "\n\n" + retMsg.Msg;
    alertMessage += "\n\nPlease reload the page.";
    alertMessage += "\nIf you continue to see this message, please contact our support team." ;
    alert(alertMessage);
  
    // undo the failed moves, they'll have been made on the client before the callback was fired
    var groupIds = retMsg.GroupIDs.replace(/,$/,'').split(','); // remove any final comma before splitting (there might not be one)
    var menu = HorizontalCategoriesControl_GetMenu();
    var item;
    for (var j=groupIds.length-1; j>=0; j--) // loop over them backwards to undo each change in order
    {
      item = menu.FindItemById(groupIds[j]);
      HorizontalCategoriesControl_MoveItemUpOnClientOnly(item)
    }
  }
  
  // clear the old ones from the history
  // do this even if there was an error, we won't use them again
  if (retMsg.HandledIndex)
  {
    globalCategoriesMovesHistory.RemoveToIndex(retMsg.HandledIndex);
  }
}

// object to store a history of the moves made when reordering sub categories
// along with an index to keep them in order and inline with the server
// because callbacks might not hit the server in the right order, so:
//  send the whole history back to the server in each callback (using the ToString method)
//  at the server, compare the last history index with an 'expectedIndex' session property (Page.Session["CategoriesMoveIndex"])
//    if it's the same, just do the last move, the same as normal, then increment 'expectedIndex'
//    if it's bigger, it means the callback has arrived out of order. So do all the moves from 'expectedIndex' to the end, and update 'expectedIndex'
//    if it's smaller, it means we've already handled it because a later callback arrived first, so do nothing
//  in callbackdone, clear the handled moves out of the history so it doesn't get too big
function CategoriesMovesHistory()
{
  this.Moves = new Array();
  this.MoveIndex = 0; // the index of the next move to be added - this should NEVER go down (but gets cleared when the page reloads, as does the session property)
  
  this.AddMove = function(_groupId)
  {
    var move = new CategoriesMove(this.MoveIndex, _groupId);
    this.Moves.push(move);
    this.MoveIndex++;
  }
  
  // remove all entries up to and including index
  //    shift removes the first entry - works because the array is always sorted by index
  this.RemoveToIndex = function(_index)
  {
    while (this.Moves[0] && this.Moves[0].Index <= _index)
      this.Moves.shift(); 
  }
  
  // returns each (comma separated) move separated by @
  // regex removes the final '@'
  this.ToString = function()
  {
    var result = '';
    for (j in this.Moves)
    {
      result += this.Moves[j].ToString() + '@'; 
    }
    result = result.replace(/@$/,''); 
    return result;
  }
}

// 'Move' object stores info about a move the user made to reorder the sub categories
function CategoriesMove(_index, _groupId)
{
  this.Index = _index;
  this.GroupId = _groupId;
  
  // returns comma separated values
  this.ToString = function()
  { 
    return this.Index + ',' + this.GroupId;
  }
}

function LoadCategoriesGenesTab() {

//	globalLoadCategories = false;
}
