var TYPE_MAP = 0;
var TYPE_SECTION = 1;
var TYPE_TAG = 2;

var SPLIT_STRING = "<|>";
var CurrentSelectedSponsorID = -1;
var CurrentSelectedTagIDs = null;
var SponsorClearTimeoutID = -1;

function TagmapViewer(instance_name)
{
	this.InstanceName = instance_name;
	this.ClassName = "TagmapViewer";
	
	this.Conn = new AjaxConnection("config_central/tagmap_viewer/data_viewer.php");
	
	this.TagMapThumbnails = "http://solarteam.org/config_central/tagmap_viewer/images/tagmap/sizes/37x37/";
	this.TagMapBigThumbnails = "http://solarteam.org/config_central/tagmap_viewer/images/tagmap/sizes/55x55/";
	this.TagMapImages = "http://solarteam.org/config_central/tagmap_viewer/images/tagmap/sizes/565x424/";
	
	this.Sponsors = new Array();
	this.CurrentSceneSponsors = new Array();
	
	this.Views = new Array();
	this.CurrentView = null;
	this.CurrentScene = null;
	
	this.FadeInTagsPending = new Array();
	
	this.HoverOutTimerID = -1;
	this.ScrollTimerID = -1;
	
	this.Initialize = function()
	{
		this.UpdateSponsors();
	}
	
	this.UpdateSponsors = function()
	{
		var obj = new AjaxObject(this);
		obj.Parameters.push("action=get_sponsors");
		obj.Callback = this.UpdateSponsorsCallback;
		
		this.Conn.DoAjax(obj);
	}
	
	this.UpdateSponsorsCallback = function(response)
	{
		this.Owner.Sponsors = new Array();
	
		for(var i = 0; i < response.childNodes.length; i++)
		{
			var currentSponsor = response.childNodes[i];
			var id 			= currentSponsor.childNodes[0].firstChild.nodeValue;
			var name 		= currentSponsor.childNodes[1].firstChild.nodeValue;
			var page_url 	= currentSponsor.childNodes[2].firstChild.nodeValue;
			var site_url 	= currentSponsor.childNodes[3].firstChild.nodeValue;
			var page_id 	= currentSponsor.childNodes[4].firstChild.nodeValue;
			
			this.Owner.Sponsors[id] = new Array();
			this.Owner.Sponsors[id]["id"] 		= id;
			this.Owner.Sponsors[id]["name"] 	= name;
			this.Owner.Sponsors[id]["page_url"] = page_url;
			this.Owner.Sponsors[id]["site_url"] = site_url;
			this.Owner.Sponsors[id]["page_id"] 	= page_id;
			this.Owner.Sponsors[id]["tags"] = new Array();
		}
		
		// Got sponsors list.. now get views
		this.Owner.UpdateViewAndScenes();
	}
	
	this.UpdateViewAndScenes = function()
	{
		var obj = new AjaxObject(this);
		obj.Callback = this.UpdateViewandScenesCallback;
		obj.Parameters.push("action=section_list");
		
		this.Conn.DoAjax(obj);
	}
	
	this.UpdateViewandScenesCallback = function(response)
	{
		var viewListingCode = "";
		var sceneListingCode = "";
		
		var viewsContainer = document.getElementById("tagmap_view_listing");
		
		var firstView = -1;
		
		for(var i = 0; i < response.childNodes.length; i++)
		{
			var curSection 	= response.childNodes[i];
			var id 			= curSection.childNodes[0].firstChild.nodeValue;
			var name 		= curSection.childNodes[1].firstChild.nodeValue;
			var description = curSection.childNodes[2].firstChild.nodeValue;
			var views 		= curSection.childNodes[3];
			
			var section_id = id;
			
			for(var p = 0; p < views.childNodes.length; p++)
			{
				var currentView 	= views.childNodes[p];
				id 					= currentView.childNodes[0].firstChild.nodeValue;
				name 				= currentView.childNodes[1].firstChild.nodeValue;
				description 		= currentView.childNodes[2].firstChild.nodeValue;
				image 				= currentView.childNodes[3].firstChild.nodeValue;
				scenes 				= currentView.childNodes[4];
				
				if(firstView == -1)
				{
					firstView = id;
				}
				
				viewListingCode += "<a href=\"#\" id=\"tagmap_view_" + id + "\" onclick=\"tagmapviewer.SelectView(" + id + ")\" title=\"" + name + ":" + description + "\">";
				viewListingCode += "<img src=\"" + this.Owner.TagMapBigThumbnails + image + "\" alt=\"" + description + "\" />";
				viewListingCode += "</a>";
				
				var view_id = id;
				
				this.Owner.Views[view_id] 					= new Array();
				this.Owner.Views[view_id]["id"] 			= id;
				this.Owner.Views[view_id]["name"] 			= name;
				this.Owner.Views[view_id]["description"] 	= description;
				this.Owner.Views[view_id]["image"] 			= image;
				this.Owner.Views[view_id]["scenes"] 		= new Array();
				
				for(var k = 0; k < scenes.childNodes.length; k++)
				{
					var currentScene 	= scenes.childNodes[k];
					id 					= currentScene.childNodes[0].firstChild.nodeValue;
					name 				= currentScene.childNodes[1].firstChild.nodeValue;
					description 		= currentScene.childNodes[2].firstChild.nodeValue;
					image 				= currentScene.childNodes[3].firstChild.nodeValue;
					
					var scene_id = id;
					
					this.Owner.Views[view_id]["scenes"][scene_id] 					= new Array();
					this.Owner.Views[view_id]["scenes"][scene_id]["id"] 			= id;
					this.Owner.Views[view_id]["scenes"][scene_id]["name"] 			= name;
					this.Owner.Views[view_id]["scenes"][scene_id]["description"] 	= description;
					this.Owner.Views[view_id]["scenes"][scene_id]["image"]	 		= image;
					this.Owner.Views[view_id]["scenes"][scene_id]["tags"]			= new Array();
				}
				
			}
		}
		viewsContainer.innerHTML = viewListingCode;
		
		if(firstView != -1)
		{
			this.Owner.SelectView(firstView);
		}
		
	}
	
	this.SelectView = function(id)
	{
		if(this.CurrentView != null && this.CurrentView["id"] == id)
		{
			// Already selected
			return;
		}
		
		for(var view_id in this.Views)
		{
			document.getElementById("tagmap_view_" + view_id).className = "";
		}
		document.getElementById("tagmap_view_" + id).className = "selected";
	
		var scenes = this.Views[id]["scenes"];
		var sceneListingCode = "";
		var sceneContainer = document.getElementById("tagmap_scene_listing");
		var firstScene = -1;
		
		for(var scene_id in scenes)
		{
			var currentScene = scenes[scene_id];
			
			sceneListingCode += "<a href=\"#\" id=\"tagmap_scene_" + scene_id + "\" onclick=\"tagmapviewer.SelectScene(" + scene_id + ")\" title=\"" + currentScene["description"] + "\">";
				sceneListingCode += "<img id=\"" + "tagmap_scene_thumb_" + scene_id + "\" src=\"" + this.TagMapThumbnails + currentScene["image"] + "\" alt=\"" + currentScene["description"] + "\" />";
			sceneListingCode += "</a>";
			
			if(firstScene == -1)
			{
				firstScene = scene_id;
			}
		}
		
		sceneContainer.innerHTML = sceneListingCode;
		
		this.CurrentView = id;
		
		if(firstScene != -1)
		{
			this.SelectScene(firstScene);
		}
	}
	
	this.SelectScene = function(id)
	{
		if(this.CurrentScene != null && this.CurrentScene == id)
		{
			return;
		}
	
		var owner = this;
		var sceneData = this.Views[this.CurrentView]["scenes"][id];
		
		// hide the tag container
		$("#tagmap_tag_container").hide("fast");
		
		// Set the image
		$("#tagmap_image_buffer_container").hide();
		var sceneImageBuffer = document.getElementById("tagmap_scene_buffer_image");
		sceneImageBuffer.src = this.TagMapImages + sceneData["image"];
		sceneImageBuffer.onload = tagmapviewer.OnSceneBufferLoaded;
		
		this.CurrentScene = id;
		
		// Make the scene thumbnail selected
		for(var scene_id in this.Views[this.CurrentView]["scenes"])
		{
			document.getElementById("tagmap_scene_" + scene_id).className = "";
		}
		document.getElementById("tagmap_scene_" + id).className = "selected";
		
		// Show the loading bar
		this.ShowLoading();
	}
	
	this.UpdateSceneTags = function()
	{
		var obj = new AjaxObject(this);
		obj.Parameters.push("action=get_tags");
		obj.Parameters.push("id=" + this.CurrentScene);
		obj.Callback = this.UpdateSceneTagsCallback;
		
		this.Conn.DoAjax(obj);
	}
	
	this.ValueExistsInArray = function(value, array)
	{
		for(var i = 0; i < array.length; i++)
		{
			if(array[i] == value)
			{
				return true;
			}
		}
		return false;
	}
	
	this.UpdateSceneTagsCallback = function(response)
	{
		var view_id = this.Owner.CurrentView;
		var scene_id = this.Owner.CurrentScene;
		var width = 565;
		var height = 424;
		
		var tagData = new Array();
		var tagCode = "";
		var tagContainer = document.getElementById("tagmap_tag_container");
		
		this.FadeInTagsPending = new Array();
		
		for(var i = 0; i < response.childNodes.length; i++)
		{
			var current 	= response.childNodes[i];
			var id 			= current.childNodes[0].firstChild.nodeValue;
			var name 		= current.childNodes[1].firstChild.nodeValue;
			var special 	= current.childNodes[2].firstChild.nodeValue;
			var url 		= current.childNodes[3].firstChild.nodeValue;
			var materials 	= current.childNodes[4].firstChild.nodeValue;
			var fabrication = current.childNodes[5].firstChild.nodeValue;
			var x 			= current.childNodes[6].firstChild.nodeValue;
			var y 			= current.childNodes[7].firstChild.nodeValue;
			
			tagData[id] = new Array();
			tagData[id]["id"] = id;
			tagData[id]["name"] = name;
			tagData[id]["special"] = special;
			tagData[id]["url"] = url;
			tagData[id]["materials"] = materials;
			tagData[id]["fabrication"] = fabrication;
			tagData[id]["x"] = x;
			tagData[id]["y"] = y;
			
			tagCode += "<div id=\"tag_" + id + "\" class=\"tag_initial\" style=\"top:" + ((y / 100) * height) + "px; left:" + ((x / 100) * width) + "px;\" onclick=\"tagmapviewer.OnTagClick(" + id + ")\" onmouseout=\"tagmapviewer.OnTagOut(" + id + ")\" onmouseover=\"tagmapviewer.OnTagOver(" + id + ")\"></div>";
			
			this.Owner.FadeInTagsPending.push(id);
		}
		
		this.Owner.Views[view_id]["scenes"][scene_id]["tags"] = tagData;
		tagContainer.innerHTML = tagCode;
		
		this.Owner.UpdateCurrentSceneSponsors(tagData);
		
		//show the tag container
		$("#tagmap_tag_container").show();
		
		this.Owner.FadeInTags();
	}
	
	this.UpdateCurrentSceneSponsors = function(tagData)
	{
		this.CurrentSceneSponsors = new Array();
		
		for(var id in tagData)
		{
			var material_ids = tagData[id]["materials"].split(SPLIT_STRING);
			var fab_ids = tagData[id]["fabrication"].split(SPLIT_STRING);
			
			for(var p = 0; p < material_ids.length; p++)
			{
				var currID = material_ids[p];
				if(currID == "")
				{
					continue;
				}
				if(this.ValueExistsInArray(currID, this.CurrentSceneSponsors) == false)
				{
					this.CurrentSceneSponsors.push(currID);
				}
				if(this.ValueExistsInArray(id, this.Sponsors[currID]["tags"]) == false)
				{
					this.Sponsors[currID]["tags"].push(id);
				}
			}
			
			for(var p = 0; p < fab_ids.length; p++)
			{
				var currID = fab_ids[p];
				if(currID == "")
				{
					continue;
				}
				if(this.ValueExistsInArray(currID, this.CurrentSceneSponsors) == false)
				{
					this.CurrentSceneSponsors.push(currID);
				}
				if(this.ValueExistsInArray(id, this.Sponsors[currID]["tags"]) == false)
				{
					this.Sponsors[currID]["tags"].push(id);
				}
			}
		}
		
		this.CurrentSceneSponsors.sort(this.SponsorsSortCompare);
		
		var sponsorsListCode = "<ul>";
		
		for(var i = 0; i < this.CurrentSceneSponsors.length; i++)
		{
			var id = this.CurrentSceneSponsors[i];
			var data = this.Sponsors[id];
			
			sponsorsListCode += "<li>";
			sponsorsListCode += "<a href=\"#\" id=\"sponsor_list_item_" + id + "\" onmouseover=\"tagmapviewer.OnSponsorHover(" + id + ")\" onmouseout=\"tagmapviewer.OnSponsorOut(" + id + ")\">";
			sponsorsListCode += data["name"];
			sponsorsListCode += "</a>";
			sponsorsListCode += "</li>";
		}
		
		sponsorsListCode += "</ul>";
		
		var sponsor_listing = document.getElementById("tagmap_sponsor_listing");
		sponsor_listing.innerHTML = sponsorsListCode;
		
		this.ScrollSponsorsToTop();
		
		if(sponsor_listing.offsetHeight > 196)
		{
			$("#tagmap_sponsor_scrolling").show();
		}
		else
		{
			$("#tagmap_sponsor_scrolling").hide();
		}
	}
	
	this.SponsorsSortCompare = function(a, b)
	{
		a = parseInt(a);
		b = parseInt(b);
		if(tagmapviewer.Sponsors[a]["name"] > tagmapviewer.Sponsors[b]["name"])
		{
			return 1;
		}
		else if(tagmapviewer.Sponsors[a]["name"] < tagmapviewer.Sponsors[b]["name"])
		{
			return -1;
		}
		else
		{
			return 0;
		}
	}
	
	this.FadeInTags = function()
	{
		if(tagmapviewer.FadeInTagsPending.length > 0)
		{
			var id = tagmapviewer.FadeInTagsPending.pop();
			$("#tag_" + id).show("fast");
			setTimeout(tagmapviewer.FadeInTags, 60);
		}
		else
		{
			tagmapviewer.HideLoading();
		}
	}
	
	this.OnSceneBufferLoaded = function()
	{
		var owner = this;
		$("#tagmap_image_buffer_container").fadeIn("fast", tagmapviewer.OnSceneBufferDoneFading);
	}
	
	this.OnSceneBufferDoneFading = function()
	{
		var sceneImageBuffer = document.getElementById("tagmap_scene_buffer_image");
		var sceneImage = document.getElementById("tagmap_scene_image");
		
		sceneImage.src = sceneImageBuffer.src;
		sceneImage.onload = tagmapviewer.OnSceneImageLoaded;
		
		// Image loaded, now load tags
		tagmapviewer.UpdateSceneTags();
	}
	
	this.OnSceneImageLoaded = function()
	{
		$("#tagmap_image_buffer_container").hide();
	}
	
	this.OnSponsorHover = function(id)
	{
		var tags = tagmapviewer.Sponsors[id]["tags"];
		
		for(var i = 0; i < tags.length; i++)
		{
			var tag = document.getElementById("tag_" + tags[i]);
			if(tag != null)
			{
				tag.className = "tag_highlight";
			}
		}
	}
	
	this.OnSponsorOut = function(id)
	{
		var tags = tagmapviewer.Sponsors[id]["tags"];
		
		for(var i = 0; i < tags.length; i++)
		{
			var tag = document.getElementById("tag_" + tags[i]);
			if(tag != null)
			{
				tag.className = "tag";
			}
		}
	}
	
	this.ScrollHelper = function(direction)
	{
		var sponsor_listing = document.getElementById("tagmap_sponsor_listing_container");
		sponsor_listing.scrollTop += direction;
	}
	
	this.ScrollSponsorsUp = function()
	{
		this.ScrollTimerID = setInterval("tagmapviewer.ScrollHelper(-2)", 1);
	}
	
	this.ScrollSponsorsDown = function()
	{
		this.ScrollTimerID = setInterval("tagmapviewer.ScrollHelper(2)", 1);
	}
	
	this.StopScrollingSponsors = function()
	{
		clearInterval(this.ScrollTimerID);
	}
	
	this.ScrollSponsorsToBottom = function()
	{
		var sponsor_listing = document.getElementById("tagmap_sponsor_listing_container");
		sponsor_listing.scrollTop = sponsor_listing.scrollHeight;
	}
	
	this.ScrollSponsorsToTop = function()
	{
		var sponsor_listing = document.getElementById("tagmap_sponsor_listing_container");
		sponsor_listing.scrollTop = 0;
	}
	
	this.OnTagOver = function(id)
	{
		clearTimeout(this.HoverOutTimerID);
		
		for(var i = 0; i < this.CurrentSceneSponsors.length; i++)
		{
			var sponsor_id = this.CurrentSceneSponsors[i];
			document.getElementById("sponsor_list_item_" + sponsor_id).className = "";
		}
	
		// Set the tag's style to hover
		var tag = document.getElementById("tag_" + id);
		tag.className = "tag_hover";
		
		var tagData = this.Views[this.CurrentView]["scenes"][this.CurrentScene]["tags"][id];
		var height = 424;
		var width = 565;
	
		document.getElementById("tag_info_name").innerHTML = tagData["name"];
		document.getElementById("tag_info_special").innerHTML = tagData["special"];
		document.getElementById("tag_info_url").innerHTML = "<a href=\"" + tagData["url"] + "\">" + tagData["url"] + "</a>";
		
		if(tagData["materials"] != "")
		{
			var material_ids = tagData["materials"].split(SPLIT_STRING);
			var material_sponsors = "";
			for(var i = 0; i < material_ids.length; i++)
			{
				if(i > 0)
				{
					material_sponsors += "<br/>";
				}
				material_sponsors += this.Sponsors[material_ids[i]]["name"];
				
				// highlight the sponsor
				document.getElementById("sponsor_list_item_" + material_ids[i]).className = "selected";
			}
			document.getElementById("tag_info_materials").style.display = "block";
			document.getElementById("tag_info_materials_title").style.display = "block";
			
			document.getElementById("tag_info_materials").innerHTML = material_sponsors;
		}
		else
		{
			document.getElementById("tag_info_materials").style.display = "none";
			document.getElementById("tag_info_materials_title").style.display = "none";
		}
		
		if(tagData["fabrication"] != "")
		{
			var fab_ids = tagData["fabrication"].split(SPLIT_STRING);
			var fab_sponsors = "";
			for(var i = 0; i < fab_ids.length; i++)
			{
				if(i > 0)
				{
					fab_sponsors += "<br/>";
				}
				fab_sponsors += this.Sponsors[fab_ids[i]]["name"];
				
				// highlight the sponsor
				document.getElementById("sponsor_list_item_" + fab_ids[i]).className = "selected";
			}
			
			document.getElementById("tag_info_fabrication").style.display = "block";
			document.getElementById("tag_info_fabrication_title").style.display = "block";
			
			document.getElementById("tag_info_fabrication").innerHTML = fab_sponsors;
		}
		else
		{
			document.getElementById("tag_info_fabrication").style.display = "none";
			document.getElementById("tag_info_fabrication_title").style.display = "none";
		}
		
		var tagmap_tag_container = document.getElementById("tagmap_tag_container");
		var left_sidebar = document.getElementById("left_sidebar");
		
		var tag_info = document.getElementById("tag_info");
		tag_info.style.left = (((tagData["x"] / 100) * width) + 20 + 170) + "px";
		tag_info.style.top = (((tagData["y"] / 100) * height) + 20 + 155) + "px";
		
		// Resize and position the tag dealie before showing it.
		
		tag_info.style.display = "block";
		var info_x = tag_info.offsetLeft;
		var info_y = tag_info.offsetTop;
		var info_width = tag_info.offsetWidth;
		var info_height = tag_info.offsetHeight;
		tag_info.style.display = "none";
		
		var tagX = ((tagData["x"] / 100) * width);
		var tagY = ((tagData["y"] / 100) * height);
		var tagWidth = 20;
		var tagHeight = 20;
		
		if((info_x + info_width - tagmap_tag_container.offsetLeft) > 565)
		{
			// have to flip taginfo over the x axis
			info_x = tagX - info_width - 5 + tagmap_tag_container.offsetLeft;
		}
		
		if((info_y + info_height - tagmap_tag_container.offsetTop) > 424)
		{
			// flip the taginfo over the y axis
			info_y = tagY - info_height - 5 + tagmap_tag_container.offsetTop;
		}
		
		// Regather info
		tag_info.style.left = (info_x) + "px";
		tag_info.style.top = (info_y) + "px";
		tag_info.style.display = "block";
		info_x = tag_info.offsetLeft;
		info_y = tag_info.offsetTop;
		info_width = tag_info.offsetWidth;
		info_height = tag_info.offsetHeight;
		tag_info.style.display = "none";
		
		if((info_x - tagmap_tag_container.offsetLeft) < 0 || (info_y - tagmap_tag_container.offsetTop) < 0)
		{
			// S...S...S...S...A...A...A...F...F...E...E...T...Y...
			info_x = tagX + 25 + tagmap_tag_container.offsetLeft;
			info_y = tagY + 25 + tagmap_tag_container.offsetTop;
			info_width = 250;
			
			if(tagX > info_width)
			{
				info_x = tagX - info_width + tagmap_tag_container.offsetLeft;
			}
			
			// Regather info
			tag_info.style.left = (info_x) + "px";
			tag_info.style.top = (info_y) + "px";
			tag_info.style.width = (info_width) + "px";
			tag_info.style.display = "block";
			info_x = tag_info.offsetLeft;
			info_y = tag_info.offsetTop;
			info_width = tag_info.offsetWidth;
			info_height = tag_info.offsetHeight;
			tag_info.style.display = "none";
		}
		
		$("#tag_info").fadeIn("fast");
	}
	
	this.OnTagOut = function(id)
	{
		// Set the tag's style to regular 
		var tag = document.getElementById("tag_" + id);
		tag.className = "tag";
		
		// Start the hover out timer
		this.HoverOutTimerID = setTimeout(this.CloseHoverBox, 1000);
	}
	
	this.OnHoverBoxOver = function()
	{
		clearTimeout(this.HoverOutTimerID);
	}
	
	this.OnHoverBoxOut = function()
	{
		this.HoverOutTimerID = setTimeout(this.CloseHoverBox, 1000);
	}
	
	this.CloseHoverBox = function()
	{
		this.HoverOutTimerID = -1;
		$("#tag_info").fadeOut("fast");

		for(var i = 0; i < tagmapviewer.CurrentSceneSponsors.length; i++)
		{
			var sponsor_id = tagmapviewer.CurrentSceneSponsors[i];
			document.getElementById("sponsor_list_item_" + sponsor_id).className = "";
		}
	}
	
	this.OnTagClick = function(id)
	{
		var url = this.Views[this.CurrentView]["scenes"][this.CurrentScene]["tags"][id]["url"];
		if(url != "")
		{
			window.open(url);
		}
	}
	
	this.ShowLoading = function()
	{
		$("#tagmap_loading_container").slideDown("fast");
	}
	
	this.HideLoading = function()
	{
		$("#tagmap_loading_container").slideUp("fast");
	}
}
