﻿NewsFeed = {}
NewsFeed.FeedAspx = "";
NewsFeed.FeedUriAlgemeen = null;
NewsFeed.FeedUriCatagory = null;

NewsFeed._firstFeedUri = null;
NewsFeed._secondFeedUri = null;

NewsFeed.Lines = 3;
NewsFeed.CssBlock = "newsfeedBlock";
NewsFeed.CssLine = "newsfeedLine";
NewsFeed.CssLink = "newsfeedLink";
NewsFeed.CssUl = "newsfeedUl";
NewsFeed.CssLi = "newsfeedLi";

NewsFeed.MoveSpeed = 1;
NewsFeed.MoveShortTimout = 40;
NewsFeed.MoveLongTimout = 4000;

NewsFeed._Helper = {}

// Div controls added to the page
NewsFeed._Helper.Control = null;
NewsFeed._Helper.InnerDiv = null;
NewsFeed._Helper.WrapperDiv = null;

// Requesthelper for fetching the feed
NewsFeed._Helper.XMLHttpRequest = null;

// XML Info to read the xml and fetch the items, text and links
NewsFeed._Helper.XmlInfo = {}
NewsFeed._Helper.XmlInfo.ItemNode = "item"
NewsFeed._Helper.XmlInfo.TitleNode = "title"
NewsFeed._Helper.XmlInfo.LinkNode = "link"

// Flags for determining if a feed is loaded or not
NewsFeed._Helper.LoadedAlgemeen = false;
NewsFeed._Helper.LoadedCatagory = false;

// All the feeditems for both feeds are stored here
NewsFeed._Helper.NewsFeedItemsAlgemeen = new Array();
NewsFeed._Helper.NewsFeedItemsCatagory = new Array();

// Helper vars for remembering what the last item added
// and wich one needs to be added next
NewsFeed._Helper.feedToggle = false;
NewsFeed._Helper.IndexAlgemeen = 0;
NewsFeed._Helper.IndexCatagory = 0;

// Controls to help with the annimation
// tipicly there is 1 more then the number of lines
NewsFeed._Helper.Controls = new Array();
NewsFeed._Helper.ControlIndex = 0;

// When moving the controls, these values are helper values
NewsFeed._Helper.Move = {}
NewsFeed._Helper.Move.OrriginalHeight = 0;
NewsFeed._Helper.Move.NewHeight = 0;
NewsFeed._Helper.Move.StartIndex = 0;
NewsFeed._Helper.Move.Top = 0;


var _h = NewsFeed._Helper;

_h.NextIndex = function(index, array)
{
	/// <summary>Gets the next index for an array wrapped</summary>
	/// <param name="index" type="int">Current index</param>
	/// <param name="array" type="array">Array to get the next index for</param>
	/// <returns type="int">The new index value</returns>

	index++;
	if (index >= array.length)
		index = 0;
	return index;
}

_h.NextFeedItem = function()
{
	/// <summary>Gets the next feed item</summary>
	/// <returns type="FeedItem">The next feeditem</returns>

	// toggle the feed, switching from Algemeen to Catagory
	_h.feedToggle = !_h.feedToggle;

	// Determine if the feed items exists and if not toggle again
	if (_h.feedToggle == true && _h.NewsFeedItemsAlgemeen == 0)
	{
		_h.feedToggle = !_h.feedToggle;
	} else if (_h.feedToggle == false && _h.NewsFeedItemsCatagory == 0)
	{
		_h.feedToggle = !_h.feedToggle;
	}

	// Fetch the item depending on the toggle value, take it from Algemeen or Catagory
	var item;
	if (_h.feedToggle == true)
	{
		_h.IndexAlgemeen = _h.NextIndex(_h.IndexAlgemeen, _h.NewsFeedItemsAlgemeen);
		item = _h.NewsFeedItemsAlgemeen[_h.IndexAlgemeen];
	} else
	{
		_h.IndexCatagory = _h.NextIndex(_h.IndexCatagory, _h.NewsFeedItemsCatagory);
		item = _h.NewsFeedItemsCatagory[_h.IndexCatagory];
	}

	// return a typed value
	var result = new Object();
	result.Text = item.Text;
	result.Link = item.Link;
	return result;
}

/* Feed animation */
_h.StartFeedAnimation = function()
{
	// Add NewsFeed.Lines + 2 elements to the div
	var divCount;
	var rand_no;
	var randIndex;

	// Determine a random startindex for Algemeen
	rand_no = Math.random();
	if (_h.NewsFeedItemsAlgemeen.length > 0)
	{
		randIndex = rand_no * _h.NewsFeedItemsAlgemeen.length;
		_h.IndexAlgemeen = Math.floor(randIndex);
	}

	// Determine a random startindex for Catagory
	rand_no = Math.random();
	if (_h.NewsFeedItemsCatagory.length > 0)
	{
		randIndex = rand_no * _h.NewsFeedItemsCatagory.length;
		_h.IndexCatagory = Math.floor(randIndex);
	}

	// Make sure the controlnidex is set
	_h.ControlIndex = 0;

	// Append subcontrols to support the moving interface
	// Append 1 more control then the number of lines, so that
	// A new control can move into view, while 1 moves out of view
	for (divCount = 0; divCount < NewsFeed.Lines + 1; divCount++)
	{
		var div = document.createElement("div");
		_h.Controls[_h.Controls.length] = div;

		if (_h.ControlIndex < NewsFeed.Lines)
		{
			// Fill the control with the feed, for it is visible
			_h.FillDiv(div);
			_h.InnerDiv.appendChild(div);
			_h.ControlIndex++;
		}
	}

	// centrate the control	
	_h.WrapperDiv.style.top = ((_h.Control.offsetHeight - _h.WrapperDiv.offsetHeight) / 2) + "px";
	

	// start the moving after the timeout
	window.setTimeout("_h.NextStep();", NewsFeed.MoveLongTimout);
}

_h.FillDiv = function(div)
{
	/// <summary>Fills a div with a new feeditem</summary>
	/// <param name="div" type="div">Div to fill</param>
	/// <returns type="Object">Default value</returns>

	var item = _h.NextFeedItem();
	div.className = NewsFeed.CssLine;
	div.innerHTML = "<ul class=\"" + NewsFeed.CssUl + "\"><li class=\"" + NewsFeed.CssLi + "\"><a href=\"" + item.Link + "\" class=\"" + NewsFeed.CssLink + "\" >" + item.Text + "</a></li></ul>";
}

_h.NextStep = function()
{
	/// <summary>Moves to the next feed item</summary>
	/// <returns type="Object">Default value</returns>

	var _move = _h.Move;

	// Determine the first control visible
	_move.StartIndex = _h.ControlIndex - NewsFeed.Lines;
	if (_move.StartIndex < 0)
		_move.StartIndex = _h.Controls.length + _move.StartIndex;

	var tmp = _move.StartIndex;
	var cnt = 0;

	// Determine the orriginal height of the item controls combined
	_move.OrriginalHeight = 0;
	for (cnt = 0; cnt < NewsFeed.Lines; cnt++)
	{
		_move.OrriginalHeight += _h.Controls[tmp].offsetHeight;
		tmp = _h.NextIndex(tmp, _h.Controls);
	}

	// append a (cached) control with new data
	var div = _h.Controls[_h.ControlIndex];
	_h.FillDiv(div);

	// Append it to the innder div
	_h.InnerDiv.appendChild(div);

	// make sure the size of the innerdiv is correct
	_h.InnerDiv.style.height = _move.OrriginalHeight + "px";

	// determine the height that the InnerDiv should have after the move
	_move.NewHeight = _move.OrriginalHeight - _h.Controls[_move.StartIndex].offsetHeight + _h.Controls[_h.ControlIndex].offsetHeight

	// reset move.top info for no move is done yet
	_move.Top = 0;

	// Set the next control index for next time around
	_h.ControlIndex = _h.NextIndex(_h.ControlIndex, _h.Controls);

	// Start the moving animation
	window.setTimeout("_h.MoveStep();", NewsFeed.MoveShortTimout);
}

_h.GetInt = function(value)
{
	/// <summary>Get an int from the value</summary>
	/// <param name="value" type="Object">value to parse as int</param>
	/// <returns type="int">The parse value, default 0</returns>

	var result = 0;
	if (value)
	{
		result = parseInt(value);
		if (result == NaN)
			result = 0;
	}
	return result;
}

_h.MoveStep = function()
{
	/// <summary>Animate the control</summary>
	/// <returns type="Object">Default value</returns>

	var _m = _h.Move;

	// Determine the control that will move out of view
	var moveOutControl = _h.Controls[NewsFeed._Helper.Move.StartIndex];

	// Determine the height difference between the old and new height of the control
	var diffHeight = _m.NewHeight - _m.OrriginalHeight;

	// If original > new diff = negative
	// top also is negative	
	if (diffHeight <= 0)
	{

		if (diffHeight - (_m.Top - (NewsFeed.MoveSpeed * 2)) < 0)
		{
			// Make the control smaller, moving the top out of the way.
			// 2ce as fast for 2 actions are done here.
			_m.Top = _m.Top - (NewsFeed.MoveSpeed * 2);
			_h.InnerDiv.style.top = _m.Top + "px";
			_h.WrapperDiv.style.height = (_h.Move.OrriginalHeight + _m.Top) + "px";
		}
		else
		{
			// move the control out of view
			_m.Top = _m.Top - NewsFeed.MoveSpeed;
			_h.InnerDiv.style.top = _m.Top + "px";
			_h.WrapperDiv.style.height = (_h.Move.OrriginalHeight + diffHeight) + "px";
		}

		// Center the control
		_h.WrapperDiv.style.top = ((_h.WrapperDiv.parentNode.offsetHeight - _h.WrapperDiv.offsetHeight) / 2 -5) + "px";

		if (_m.Top < -moveOutControl.offsetHeight)
		{
			// finish the move, setting the controls to the final state
			_h.WrapperDiv.style.height = _m.NewHeight + "px";
			_h.WrapperDiv.style.top = ((_h.Control.offsetHeight - _h.WrapperDiv.offsetHeight) / 2 -5) + "px";
			// removig the control that moved out of sight
			_h.InnerDiv.removeChild(moveOutControl);
			_h.InnerDiv.style.top = "0px";

			// Starting the long wait for the next move
			window.setTimeout("_h.NextStep();", NewsFeed.MoveLongTimout);
		}
		else
		{
			// next step
			window.setTimeout("_h.MoveStep();", NewsFeed.MoveShortTimout);
		}
	}
	else if (diffHeight > 0)
	{

		if (moveOutControl.offsetHeight >= -_m.Top)
		{
			// move the controls
			_m.Top = _m.Top - NewsFeed.MoveSpeed;
			_h.InnerDiv.style.top = _m.Top + "px";
		}
		else
		{
			// move and resize the controls
			_m.Top = _m.Top - (NewsFeed.MoveSpeed * 2);
			_h.InnerDiv.style.top = (-moveOutControl.offsetHeight) + "px";
			_h.WrapperDiv.style.height = (_m.OrriginalHeight + (-_m.Top - moveOutControl.offsetHeight)) + "px";
		}

		_h.WrapperDiv.style.top = ((_h.Control.offsetHeight - _h.WrapperDiv.offsetHeight) / 2) + "px";

		var height = _h.GetInt(_h.WrapperDiv.style.height);
		if (height >= _m.NewHeight)
		{
			// finish up
			_h.WrapperDiv.style.height = _m.NewHeight + "px";
			_h.WrapperDiv.style.top = ((_h.Control.offsetHeight - _h.WrapperDiv.offsetHeight) / 2) + "px";
			_h.InnerDiv.removeChild(moveOutControl);
			_h.InnerDiv.style.top = "0px";

			// Start next loop
			window.setTimeout("_h.NextStep();", NewsFeed.MoveLongTimout);
		}
		else
		{
			// nextStep
			window.setTimeout("_h.MoveStep();", NewsFeed.MoveShortTimout);
		}
	}
}

_h.ProcessReqChange = function(handler)
{
	/// <summary>Handle the load status of the document</summary>
	/// <param name="handler" type="Object">handler for when all is done</param>
	/// <returns type="Object">Default value</returns>

	if (_h.XMLHttpRequest
	&& _h.XMLHttpRequest.readyState == 4
	&& (_h.XMLHttpRequest.status == 200 || _h.XMLHttpRequest.status == 304))
	{
		handler(_h.XMLHttpRequest.responseXML);
	}
}

_h.LoadXMLDoc = function(url, handler)
{
	/// <summary>Does the acual loading of an xml document from the requested url</summary>
	/// <param name="url" type="Object">Url to load the feed from</param>
	/// <param name="handler" type="Object">Handler to use when done loading</param>
	/// <returns type="Object">Default value</returns>

	// Determine the requesting object
	if (window.XMLHttpRequest)
	{
		try { _h.XMLHttpRequest = new XMLHttpRequest(); } catch (e) { _h.XMLHttpRequest = false; }
	}
	else if (window.ActiveXObject)
	{
		try { _h.XMLHttpRequest = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e)
		{
			try { _h.XMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { _h.XMLHttpRequest = false; }
		}
	}

	try
	{
		// start the request	
		if (_h.XMLHttpRequest)
		{
			_h.XMLHttpRequest.onreadystatechange = function() { _h.ProcessReqChange(handler); };
			if ("" + NewsFeed.FeedAspx == "")
			{
				_h.XMLHttpRequest.open("GET", url, true);
				_h.XMLHttpRequest.send("");
			} else
			{

				_h.XMLHttpRequest.open("POST", NewsFeed.FeedAspx, true);
				_h.XMLHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				_h.XMLHttpRequest.send("feed=" + escape(url));
			}
		}
	} catch (e)
	{
		// Somehting went wrong with loading the value.
		_h.XMLHttpRequest = null;
	}
}

_h.AddNewsFeedItem = function(text, link)
{
	/// <summary>Adds an item to the ticker list</summary>
	/// <param name="text" type="string">Text of the ticker item</param>
	/// <param name="adres" type="string">Url of the ticker item</param>
	/// <returns type="Object">Default value</returns>

	var item = new Object();
	item.Text = text;
	item.Link = link;

	if (_h.LoadedAlgemeen == false)
		_h.NewsFeedItemsAlgemeen[_h.NewsFeedItemsAlgemeen.length] = item;
	else
		_h.NewsFeedItemsCatagory[_h.NewsFeedItemsCatagory.length] = item;
}




_h.GetItem = function(feedItem, tagName)
{
	/// <summary>Gets the value of a subnode from the feedItem, this is done by tagname</summary>
	/// <param name="feedItem" type="Object">Feeditem to parse</param>
	/// <param name="name" type="string">Name of the tag to get the value from</param>
	/// <returns type="string">The requested value</returns>

	// read all tagnames for the requested tagname
	var title = feedItem.getElementsByTagName(tagName);

	var result = "";
	// Only get the first item if there are any
	if (title && title.length > 0)
	{
		title = title.item(0);
		if (title)
		{
			// depending on the browser one of these should work
			if (title.text)
			{
				result = title.text;
			} else
			{
				result = title.textContent;
			}
		}
	}
	return result;
}


_h.ParseFeedList = function(loadedXml)
{
	/// <summary>Event handler for loadingXml, this will parse the document</summary>
	/// <param name="dom" type="Object">Event arguments</param>
	/// <returns type="Object">Default value</returns>


	if (loadedXml)
	{
		// Get the ticker object

		// load all items
		var feedItems = loadedXml.getElementsByTagName(_h.XmlInfo.ItemNode);
		if (feedItems && feedItems.length > 0)
		{

			for (var i = 0; i < feedItems.length; i++)
			{
				var feedItem = feedItems.item(i);
				var title = _h.GetItem(feedItem, _h.XmlInfo.TitleNode);
				var link = _h.GetItem(feedItem, _h.XmlInfo.LinkNode);

				_h.AddNewsFeedItem(title, link);
			}

			if (_h.LoadedAlgemeen == false)
			{
				_h.LoadedAlgemeen = true;
				if (NewsFeed._secondFeedUri != null)
					_h.LoadXMLDoc(NewsFeed._secondFeedUri, _h.ParseFeedList);
				else
					_h.StartFeedAnimation();
			}
			else if (_h.LoadedCatagory == false)
			{
				_h.LoadedCatagory = true;
				_h.StartFeedAnimation();
			}
		}
	}
}

_h.GetFeedList = function()
{
	/// <summary>Load the xml document</summary>
	/// <returns type="Object">Default value</returns>

	NewsFeed._firstFeedUri = null;
	NewsFeed._secondFeedUri = null;
	if (NewsFeed.FeedUriAlgemeen != null)
	{
		NewsFeed._firstFeedUri = NewsFeed.FeedUriAlgemeen;
	}

	if (NewsFeed.FeedUriCatagory != null)
	{
		if (NewsFeed._firstFeedUri == null)
		{
			NewsFeed._firstFeedUri = NewsFeed.FeedUriCatagory;
		}
		else
		{
			NewsFeed._secondFeedUri = NewsFeed.FeedUriCatagory
		}
	}


	if (NewsFeed._firstFeedUri != null)
		_h.LoadXMLDoc(NewsFeed._firstFeedUri, _h.ParseFeedList);

}


_h.InitTicker = function()
{
	/// <summary>Initialises the ticker</summary>
	/// <returns type="Object">Default value</returns>

	// Reset some values so on postback there are no wierd things happoning

	// Validate if the ticker div exists
	var creator = document.createElement("div");
	var div = document.createElement("div");
	div.className = NewsFeed.CssBlock;
	div.id = "NewsFeedGeneratedControl";
	creator.appendChild(div);
	document.write(creator.innerHTML);

	_h.InnerDiv = document.createElement("div");
	_h.InnerDiv.id = "innerDiv";
	_h.InnerDiv.style.position = "relative";

	_h.WrapperDiv = document.createElement("div");
	_h.WrapperDiv.appendChild(_h.InnerDiv);
	_h.WrapperDiv.id = "wrapperDiv";
	_h.WrapperDiv.style.overflow = "hidden";
	_h.WrapperDiv.style.position = "relative";

	_h.Control = document.getElementById(div.id);
	_h.Control.appendChild(_h.WrapperDiv);

	if (_h.Control)
	{
		// Load the feed and start it
		_h.GetFeedList();
	}
}

NewsFeed.Create = function()
{
	/// <summary>Creates the newsfeed</summary>
	/// <returns type="Object">Default value</returns>

	_h.InitTicker();
}

