// -------------------------------------------
// KNOWLEDGE MAP KNOWLEDGE RESOURCES FUNCTIONS
// -------------------------------------------
// Copyright (c) 2004-2007 The Salamander Organization Ltd.  All Rights Reserved.
//
// THIS WORK IS SUBJECT TO U.K. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
//
// DISCLAIMER:
//
// The Salamander Organization Ltd. (hereto referred as "Salamander") makes no representations or warranties
// with respect to the contents or use of this code, and specifically disclaims any express or implied
// warranties of merchantability or fitness for any particular purpose.  Further, Salamander reserves the right
// to revise this publication and to make changes to its content, at any time, without obligation to notify any
// person or entity of such revisions or changes.
//
// Further, Salamander makes no representations or warranties with respect to any software, and specifically
// disclaims any express or implied warranties of merchantability or fitness for any particular purpose.  Salamander
// reserves the right to make changes to any and all parts of the software, at any time, without obligation to notify
// any person or entity of such changes.
//
// Inclusion of the above notice does not necessarily imply publication.

// ########################
// ### SYSTEM VARIABLES ###

var categoryBlockPrefix = "kr_catblock_";
var resourceBlockPrefix = "kr_resblock_";

var categoryPrefix = "kr_category_";
var resourcePrefix = "kr_resource_";

var categoryBlocks = new Array();
var categoryBlockCount = 0;

var resourceBlocks = new Array();
var resourceBlockCount = 0;

var krCategories = new Array();
var krCategoryCount = 0;

var krResources = new Array();
var krResourceCount = 0;

var catUid = 0;  // must initialise as 0
var resUid = 0;  // must initialise as 0

var currentCategoryUid = 0;  // must initialise as 0

var resSplit = "|||";  // must match resource details split in template


// ########################
// ### GLOBAL VARIABLES ###

usingKResources = true;


// ###############################
// ### TEMPLATE PAGE FUNCTIONS ###

// create a new textarea block to contain a knowledge category - called in the template for each category block
function AddCategoryArea()
{
	var uid = GetNewUid("category");  // get a fresh uid for this category

	var domId = categoryBlockPrefix + uid;

	WriteTextArea(domId);
	
	AddCategoryBlock(domId);
}

// create a new textarea block to contain a knowledge resource - called in the template for each resource block
// -- assumes that the category it is associated with was identified before it was called
function AddResourceArea()
{
	var uid = GetNewUid("resource");  // get a fresh uid for this resource

	var domId = resourceBlockPrefix + uid;

	WriteTextArea(domId, currentCategoryUid);
	
	AddResourceBlock(domId);
}

// #######################################
// ### TEMPLATE PAGE PARSING FUNCTIONS ###

// register a template category block
function AddCategoryBlock(domId)
{
	categoryBlocks[categoryBlockCount] = domId;
	
	categoryBlockCount++;
}

// register a template resource block
function AddResourceBlock(domId)
{
	resourceBlocks[resourceBlockCount] = domId;
	
	resourceBlockCount++;
}

// build category objects from the category blocks
function CreateCategories()
{
	// create a new category for each category block
	for (var i = 0; i < categoryBlockCount; i++)
	{
		var categoryDomId = new String(categoryBlocks[i]);
		
		var categoryId;
		var categoryName = "";
		
		var categoryBlock = document.getElementById(categoryDomId);
		
		if (categoryBlock)
		{
			// get the contents of the categoryBlock
			categoryName = categoryBlock.value;
		}
		
		var prefixRegexp = new RegExp(categoryBlockPrefix, "gi");
		
		categoryId = categoryDomId.replace(prefixRegexp, "");
		
		// if we've got a categoryName we are probably safe to add this as a category
		if (categoryName != "")
		{
			AddCategory(categoryId, categoryName);
		}
	}
}

// build resource objects from the resource blocks
// -- must be called after CreateCategories()
function CreateResources()
{
	// create a new resource for each resource block
	for (var i = 0; i < resourceBlockCount; i++)
	{
		var resourceDomId = new String(resourceBlocks[i]);
		var resourceDetails = new String("");
		
		var categoryId;
		var resourceId;
		var resourceName = "";
		var resourceLink = "";
		var resourceTooltip = "";
		var resourceImage = "";
		var resourceImageDescription = "";
		
		var resourceBlock = document.getElementById(resourceDomId);
		
		if (resourceBlock)
		{
			// get the contents of the resourceBlock
			resourceDetails = resourceBlock.value;
		}
		
		if (resourceDetails != "")
		{
			// parse the resource details into their component parts
			var resourceArray = resourceDetails.split(resSplit);
			
			if (resourceArray.length > 0)
			{
				categoryId = resourceArray[0];
				resourceName = resourceArray[1];
				resourceLink = resourceArray[2];
				resourceTooltip = resourceArray[3];
				resourceImage = resourceArray[4];
				resourceImageDescription = resourceArray[5];
			}
		}
				
		var prefixRegexp = new RegExp(resourceBlockPrefix, "gi");
				
		resourceId = resourceDomId.replace(prefixRegexp, "");
		
		// if categoryId has been assigned a real positive value and we've got a resourceName we're probably safe to add this resource
		if (categoryId >= 0 && resourceName != "")
		{
			AddResource(categoryId, resourceId, resourceName, resourceLink, resourceTooltip, resourceImage, resourceImageDescription);
		}
	}
}

// manages the parsing of the knowledge category & knowledge resource template blocks into category & resource objects
function ParseKnowledgeResourcesSection()
{
	CreateCategories();
	
	if (krCategoryCount > 0)
	{
		CreateResources();
	}
}

// ######################################################
// ### BUILD THE KNOWLEDGE RESOURCES NAVIGATION BLOCK ###

// write out the nav_menu items for the knowledge resources block
// -- requires that a "knowledge" block has been created for use in nav_menus_structure.js
function BuildKnowledgeResourcesNavBlock()
{	
	// iterate through the categories
	for (var i = 0; i < krCategoryCount; i++)
	{
		var category = krCategories[i];
		
		AddBlockItem_KnowledgeCategory(categoryPrefix + category.uid, category.name);
		
		// iterate through resources in this category
		for (var j = 0; j < category.count; j++)
		{
			var resource = category.resources[j];
			
			AddNavigationLink_KnowledgeResource(resource.name, resource.linkUrl, resource.tooltip, resourcePrefix + resource.uid, resource.image, resource.imageDesc);
		}
	}
}

// called from the template after the category & resource blocks have been written out
// -- effectively the main() call for knowledge_resources.js
function DoKnowledgeResources()
{
	ParseKnowledgeResourcesSection();
	BuildKnowledgeResourcesNavBlock();
}

// #############################################
// ### BUILD THE KNOWLEDGE RESOURCES OBJECTS ###

// [constructor] knowledge category object
// SUMMARY:
//		categoryId			- integer uid for this category
//		categoryName		- string name for this category (to appear in the page)
function krCategory(categoryId, categoryName)
{
	this.uid = categoryId;
	this.name = categoryName;
	this.resources = new Array();
	this.count = 0;
}

// [constructor] knowledge resource object
// SUMMARY:
//		resourceId			- integer uid for this resource
//		resourceName		- string name for this resource (to appear in the page)
//		resourceLink		- string url
//		resourceTooltip		- string tooltip
//		resourceImage		- string url for the image/icon
//		resourceImageDescription	- string description for the image/icon
function krResource(resourceId, resourceName, resourceLink, resourceTooltip, resourceImage, resourceImageDescription)
{
	this.uid = resourceId;
	this.name = resourceName;
	this.linkUrl = resourceLink;
	if (!resourceTooltip)
	{
		this.tooltip = "";
	}
	else
	{
		this.tooltip = resourceTooltip;
	}
	this.image = resourceImage;
	if (!resourceImageDescription)
	{
		this.imageDesc = "";
	}
	else
	{
		this.imageDesc = resourceImageDescription;
	}
}

// create and register a category object with the system
function AddCategory(categoryId, categoryName)
{
	var newCat = new krCategory(categoryId, categoryName);
	
	krCategories[krCategoryCount] = newCat;
	krCategoryCount++;
}

// create and register a resource object with the system
function AddResource(categoryId, resourceId, resourceName, resourceLink, resourceTooltip, resourceImage, resourceImageDescription)
{
	var newRes = new krResource(resourceId, resourceName, resourceLink, resourceTooltip, resourceImage, resourceImageDescription);
	
	krResources[krResourceCount] = newRes;
	krResourceCount++;
	
	AddResourceToCategory(newRes, categoryId);
}

// add a resource object to its containing category object
function AddResourceToCategory(resource, categoryId)
{
	var category;

	for (var i = 0; i < krCategoryCount; i++)
	{
		if (krCategories[i].uid == categoryId)
		{
			category = krCategories[i];
			break;  // found category, stop searching
		}
	}
	
	// check we've really got a category
	if (category.uid)
	{
		category.resources[category.count] = resource;
		
		category.count = category.count + 1;
	}
}

// #################################################
// ### MANAGE THE DISPLAY OF KNOWLEDGE RESOURCES ###

// show/hide the resources for this category - called by categories in the template
function ToggleResourceDisplay(categoryDomId)
{
	// iterate through the categories
	for (var i = 0; i < krCategoryCount; i++)
	{
		var category = krCategories[i];
		
		if ((categoryPrefix + category.uid) == categoryDomId)
		{
			// found the category - iterate through its resources
			for (var j = 0; j < category.count; j++)
			{
				var resource = category.resources[j];

				var resourceRow = document.getElementById(resourcePrefix + resource.uid);
				
				if (resourceRow)
				{
					if (resourceRow.style.display == "none")
					{
						resourceRow.style.display = "block";
						SaveResourceMenuState(categoryDomId, "show");
					}
					else
					{
						resourceRow.style.display = "none";
						SaveResourceMenuState(categoryDomId, "hide");
					}
				}
			}
		}
	}
}

// only show resources for this category
function ShowKnowledgeResources(categoryDomId)
{
	// iterate through the categories
	for (var i = 0; i < krCategoryCount; i++)
	{
		var category = krCategories[i];
		
		if ((categoryPrefix + category.uid) == categoryDomId)
		{
			// found the category - iterate through its resources
			for (var j = 0; j < category.count; j++)
			{
				var resource = category.resources[j];

				var resourceRow = document.getElementById(resourcePrefix + resource.uid);
				
				if (resourceRow)
				{
					if (resourceRow.style.display == "none")
					{
						resourceRow.style.display = "block";
					}
				}
			}
		}
	}
}

// only hide resources for this category
function HideKnowledgeResources(categoryDomId)
{
	// iterate through the categories
	for (var i = 0; i < krCategoryCount; i++)
	{
		var category = krCategories[i];
		
		if ((categoryPrefix + category.uid) == categoryDomId)
		{
			// found the category - iterate through its resources
			for (var j = 0; j < category.count; j++)
			{
				var resource = category.resources[j];

				var resourceRow = document.getElementById(resourcePrefix + resource.uid);
				
				if (resourceRow)
				{
					if (resourceRow.style.display == "block")
					{
						resourceRow.style.display = "none";
					}
				}
			}
		}
	}
}

// #############################################
// ### KNOWLEDGE RESOURCES SUPPORT FUNCTIONS ###

// get a new unique id
// SUMMARY:
//		uidType			- either "category" or "resource"
function GetNewUid(uidType)
{
	uidType = uidType.toLowerCase();  // case protection
	
	var uid;
	
	switch (uidType)
	{
		case "category" :
			uid = catUid;
			currentCategoryUid = uid;  // mark this as the current category
			catUid++;
			break;
		case "resource" :
			uid = resUid;
			resUid++;
			break;
		default :
			// error condition
			break;
	}
	
	return uid;
}

// write the opening <textarea> tag into the page with the appropriate domId
// SUMMARY:
//		domId			- DOM id for this template block
//		categoryId		- only passed for resources, identifies their containing categoryId (not categoryDomId)
function WriteTextArea(domId, categoryId)
{
	var textString = "<textarea id='" + domId + "' style='display:none;'>";
	
	if (categoryId >= 0)
	{
		textString += categoryId + resSplit;
	}

	document.write(textString);
}


// ######################################
// ### RESOURCE MENU MEMORY FUNCTIONS ###

var lastShownCategoryId = "";

var doingResourceStateLoad = false;

// save the current resource menu state
// SUMMARY:
//		categoryDomId		- string of the resource category id, with prefix
//		menuState			- string of either "show" or "hide"
//		doScrolling			- boolean to indicate whether scrolling is enabled
function SaveResourceMenuState(categoryDomId, menuState)
{
	// don't save state if we're loading states and not if we're initialising the page
	if (!doingResourceStateLoad && !doingPageInit)
	{
		var cookieVar = GetCookieVar("resourcemenu", true);

		if (cookieVar != "")
		{
			var cookieData = "";
			var state = "";

			// get the old cookie data
			var oldCookieData = GetFromCookie(cookieVar);

			switch (menuState)
			{
				case "show" :

					// category is displayed
					state = "1";

					break;

				case "hide" :

					// category is hidden
					state = "0";
					break;

				default :

					// no valid state indicated - error condition
					break;
			}

			// modify the old cookie data to get new cookie data
			cookieData = ModifyCookieData(oldCookieData, categoryDomId, state);

			// save the new cookie data
			SaveToCookie(cookieVar, cookieData);
		}
	}
}

// load the page state from cookie, if available
function LoadResourceMenuState()
{
	doingResourceStateLoad = true;  // mark start of state load (to prevent saves occuring too)
	
	var cookieVar = GetCookieVar("resourcemenu");
	
	if (cookieVar != "")
	{
		var stateData = GetFromCookie(cookieVar);
		
		// start initialising the page based on the cookie
		SetResourceMenuState(stateData);
	}
	
	doingResourceStateLoad = false;  // mark end of state load
}

// initialise the resource menu based on a set of state data
function SetResourceMenuState(stateData)
{
	if (stateData != "")
	{
		var stateString = new String(stateData);
		var stateParts = stateString.split(varSplit);
		
		if (stateParts.length > 0)
		{
			for (var i = 0; i < stateParts.length; i++)
			{
				if (i == 0)
				{
					// ignore the page path
				}
				else if (i == 1)
				{
					// ignore the last modified details
				}
				else
				{
					// process the val-value pairs
					var pairString = new String(stateParts[i]);
					var pairParts = pairString.split(pairSplit);

					if (pairParts.length == 2)
					{
						// got an expected pair, process it
						var categoryDomId = pairParts[0];
						var categoryState = pairParts[1];
						
						if (categoryDomId != "")
						{							
							switch (categoryState)
							{									
								case "1" :
								
									// show this category's resources									
									ShowKnowledgeResources(categoryDomId);
									
									lastShownCategoryId = categoryDomId;
									
									break;
									
								case "0" :
								
									// hide this category's resources
									HideKnowledgeResources(categoryDomId);
									break;
									
								default :
								
									// unrecognised state - do nothing
									break;
							}
						}
					}
				}
			}
		}
	}	
}

// scroll to the last category that was displayed
function ScrollToLastShownCategory()
{
	if (lastShownCategoryId != "")
	{		
		var resourceSection = document.getElementById(lastShownCategoryId);
		
		if (resourceSection)
		{
			resourceSection.scrollIntoView(false);
		}
	}
}

