/// <summary>
/// Constructs a new controller to manage
/// marking articles as read or unread
/// </summary>
function ReadStatusController()
{
	this.flushTimeoutMilliseconds = 1000;
	
	this.firstSetTime = null;
	this.pendingRead = new Array();
	this.pendingUnread = new Array();
	this.readStatusByArticle = new Array();
	this.setExistingStatus = setExistingStatus;
	this.isSet = isSet;
	this.setRead = setRead;
	this.wantsFlush = wantsFlush;
	this.flush = flush;
}

/// <summary>
/// Immediately visually marks the specified Article
/// as read or unread. Only after the controller is flushed
/// are the changes persisted.
/// </summary>
function setRead(id, isRead)
{
	var readStatusButton = document.getElementById('ReadStatusButton_' + id);
	if (readStatusButton == null)
		return;

	// Record when our first unflushed status is assigned
	if (this.firstSetTime == null)
		this.firstSetTime = new Date();
	
	// Remove the pending entry for this Article if
	// we already have one
	var existingIndex;

	existingIndex = this.pendingRead.indexOf(id);
	if (existingIndex != -1)
		this.pendingRead.splice(existingIndex, 1);
	
	existingIndex = this.pendingUnread.indexOf(id);
	if (existingIndex != -1)
		this.pendingUnread.splice(existingIndex, 1);

	// Queue our status change request
	if (isRead)
		this.pendingRead[this.pendingRead.length] = id;
	else
		this.pendingUnread[this.pendingUnread.length] = id;

	// Mark this article as being intentionally read/unread
	this.readStatusByArticle[id] = isRead;

	// Update the GUI immediately
	readStatusButton.className = isRead ? 'Read' : 'Unread';

	var articleHeader = document.getElementById('ArticleHeader_' + id);
	articleHeader.className = isRead ? "Header HeaderRead" : "Header HeaderUnread";
}

/// <summary>
/// Internally marks the current read status
/// for an Article for the controller
/// </summary>
function setExistingStatus(id, isRead)
{
	this.readStatusByArticle[id] = isRead;
}

/// <summary>
/// Whether we have a status (read or unread) explicitly set for this session
/// </summary>
function isSet(id)
{
	return this.readStatusByArticle[id] != undefined;
}

/// <summary>
/// Returns True if the controller wants to flush its status contents
/// </summary>
function wantsFlush()
{
	if (this.firstSetTime == null)
		return false;

	var elapsedMilliseconds = (new Date().getTime()) - this.firstSetTime.getTime();

	return elapsedMilliseconds >= this.flushTimeoutMilliseconds;
}

/// <summary>
/// Flushes the read/unread status settings to the website
/// </summary>
function flush()
{
	if (this.pendingRead.length > 0)
		ViewArticles.SetArticleRead(this.pendingRead, true, function() { });

	if (this.pendingUnread.length > 0)
		ViewArticles.SetArticleRead(this.pendingUnread, false, function() { });
	
	this.pendingRead.clear();
	this.pendingUnread.clear();
	
	this.firstSetTime = null;
}