var pageSize = 10;

function MediaTracker() {
	var req, done;
	// branch for native XMLHttpRequest object
	if (window.XMLHttpRequest) {
		try {
			req = new XMLHttpRequest();
		} catch(e) {
			req = false;
		}
	// branch for IE/Windows ActiveX version
	} else if (window.ActiveXObject) {
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				req = false;
			}
		}
	}

	this.get = function(url, callback) {
		if (!req) return false;
		done = false;

		req.onreadystatechange = function() {
			if (req.readyState == 4 && req.status == 200 && !done) {
				done = true;
				callback(req);
			}
		}
		req.open("GET", url, true);
		req.send("");
	}
}

function Message() {
	this.gravatar = null;
	this.author = null;
	this.date = null;
	this.time = null;
	this.messageNum = null;
	this.body = null;
}

function Page() {
	this.messages = new Array();
	this.display = null;
	this.tbody = null;

	this.addMessage = function(message) {
		this.messages.push(message);
	}
}

function Topic(line) {
	line = line.replace(/\\\^/g, '\\carrot');
	var fields = line.split('\^');
	this.num = fields[0];
	this.time = fields[1];
	this.subject = fields[2].replace(/\\carrot/g, '^');
	this.replyCount = parseInt(fields[3]);
	this.author = fields[4].replace(/\\carrot/g, '^');
	this.lastPoster = fields[5].replace(/\\carrot/g, '^');
	this.lastPostDate = fields[6];

	this.pages = new Array();
}

function Board() {
	this.forums = new Array();
	this.display = null;
	this.tr = null;

	this.addYForum = function(name, id) {
		var dir = 'forums/' + id + '/';
		var home = 'http://games.groups.yahoo.com/group/' + id + '/';
		var post = home + 'post';
		var reply = home + 'post?act=reply&messageNum=';
		this.addForum(name, dir, home, post, reply);
	}

	this.addForum = function(name, dir, home, post, reply) {
		var forum = new Forum(name, dir, home, post, reply);
		this.forums.push(forum);
		if (currentForum == null) {
			currentForum = forum;
			viewForum();

			this.display = document.getElementById('forum_menu');
			this.tr = el('tr');
			this.display.appendChild(el('table', 'align=center,class=fmenu', el('tbody', null, this.tr)));
		}

		this.tr.appendChild(el('td', null, createButton(name, 'viewForum('+this.forums.length+')')));
	}
}

var board = new Board();

function Forum(name, dir, homeUrl, postUrl, replyUrl) {
	this.name = name;
	this.dir = dir;
	this.homeUrl = homeUrl;
	this.postUrl = postUrl;
	this.replyUrl = replyUrl;

	this.topics = new Array();
	this.recentTopic = null;
	this.display = document.createElement('div');
	this.tbody = null;

	var headerTable = el('table', 'class=info_bar');
	this.display.appendChild(headerTable);
	var headerBody = el('tbody');
	headerTable.appendChild(headerBody);
	var headerRow = el('tr');
	headerBody.appendChild(headerRow);
	headerRow.appendChild(el('td', null, createButton('refresh', "viewForum()")));
	headerRow.appendChild(el('td', 'align=right', createButton('new topic', "location.href = '"+ this.postUrl +"';")));

	var table = el('table', 'class=ti content');
	this.display.appendChild(table);

	var thead = el('thead');
	table.appendChild(thead);
	var headtr = el('tr', 'class=header_row');
	thead.appendChild(headtr);
	headtr.appendChild(el('th', 'class=topic_col', tx('Topic')));
	headtr.appendChild(el('th', 'class=replies_col', tx('Replies')));
	headtr.appendChild(el('th', 'class=author_col', tx('Author')));
	headtr.appendChild(el('th', 'class=last_post_col', tx('Last post')));

	var tbody = el('tbody', 'id=index_tbody');
	table.appendChild(tbody);

	var footerTable = el('table', 'class=info_bar');
	this.display.appendChild(footerTable);
	var footerBody = el('tbody');
	footerTable.appendChild(footerBody);
	var footerRow = el('tr');
	footerBody.appendChild(footerRow);
	footerRow.appendChild(el('td', null, createButton('search for older messages', "location.href = '"+ this.homeUrl +"';")));

	this.tbody = tbody;
}

function splitLines(text) {
	var outLines = new Array();
	var lines = text.split('\n');
	for (var i = 0; i < lines.length; i++) {
		var line = lines[i];
		if (!(line.length == 0 && i == lines.length-1))
			outLines.push(line);
	}
	return outLines;
}

function doRefreshForum(req) {
	var lines = splitLines(req.responseText);
	var tbody = currentForum.tbody;
	for (var i = 0; i < lines.length; i++) {
		var topic = new Topic(lines[i]);
		currentForum.recentTopic = topic;
		currentForum.topics[topic.num] = topic;

		var row = document.getElementById('itopic_'+topic.num);
		if (row) tbody.removeChild(row);

		row = el('tr', 'id=itopic_'+topic.num+',class=item_row');
		row.appendChild(createTopicCell(topic, 'subject_col shade1'));
		row.appendChild(createCell(topic.replyCount, 'replies_col shade2'));
		row.appendChild(createCell(topic.author, 'author_col shade1'));
		var lastPostCell = el('td', 'class=last_post_col shade2');
		lastPostCell.appendChild(tx(topic.lastPostDate));
		lastPostCell.appendChild(el('br'));
		lastPostCell.appendChild(tx(topic.lastPoster));
		row.appendChild(lastPostCell);
		//row.appendChild(createCell(topic.lastPoster, 'last_post_col shade2'));
		tbody.insertBefore(row, tbody.firstChild);
	}
}

function createTopicCell(topic, klass) {
	var cell = el('td', 'class='+klass);

	var subjectDiv = el('div', 'class=topic');
	cell.appendChild(subjectDiv);

	var anchor = el('a', 'href=javascript:viewTopic('+topic.num+')', tx(topic.subject));
	subjectDiv.appendChild(anchor);

	if (parseInt(topic.replyCount/pageSize) > 0) {
		var postCount = topic.replyCount + 1;

		var pagesDiv = document.createElement('div');
		cell.appendChild(pagesDiv);

		pagesDiv.appendChild(document.createTextNode('Pages:'));
		for (var i = 1; i <= postCount; i += pageSize) {
			var page = parseInt((i-1)/pageSize)+1;
			pagesDiv.appendChild(tx(' '));
			var pageAnchor = el('a');
			pageAnchor.setAttribute('href', 'javascript:viewTopic('+topic.num+','+page+');');
			pageAnchor.appendChild(tx(page));
			pagesDiv.appendChild(pageAnchor);
		}
	}
	return cell;
}

function createCell(text, klass) {
	return el('td', 'class='+klass, tx(text));
}

function viewForum(forumNum) {
	if (forumNum) {
		currentForum = board.forums[forumNum - 1];
	}

	// switch displays
	showDisplay(currentForum.display);

	var tracker = new MediaTracker();
	var url = currentForum.dir + 'ie.cgi';
	if (currentForum.recentTopic)
		url += '?s='+currentForum.recentTopic.time;
	tracker.get(url, doRefreshForum);
}

var currentForum = null;
var currentTopic = null;
var currentPage = null;
function viewTopic(topicNum, pageNum) {
	if (!pageNum) pageNum = 1;

	var topic = currentForum.topics[topicNum];
	if (!topic) alert('topic not found!');

	var lastPageNum = parseInt(topic.replyCount / pageSize) + 1;
	var page = topic.pages[pageNum];

	// create page if it does not exist
	if (!page) {
		page = new Page();
		topic.pages[pageNum] = page;

		var display = document.createElement('div');
		page.display = display;

		var headerTable = el('table', 'class=info_bar');
		display.appendChild(headerTable);
		var headerBody = el('tbody');
		headerTable.appendChild(headerBody);
		var headerRow = el('tr');
		headerBody.appendChild(headerRow);
		headerRow.appendChild(el('td', 'width=150', createButton('return to index', "viewForum()")));
		headerRow.appendChild(el('td', null, el('span', 'class=subject_header', tx('Topic: '+topic.subject))));
		var indexCell = el('td', 'align=right');
		headerRow.appendChild(indexCell);
		var indexSpan = createIndexSpan(topic);
		indexCell.appendChild(indexSpan);

		var table = el('table', "class=mi content");
		display.appendChild(table);

		var thead = el('thead');
		table.appendChild(thead);
		var headtr = el('tr', 'class=header_row');
		thead.appendChild(headtr);
		headtr.appendChild(el('th', 'class=author_col', tx('Author')));
		headtr.appendChild(el('th', 'class=message_col', tx('Message')));

		var tbody = el('tbody');
		table.appendChild(tbody);

		var footerTable = el('table', 'class=info_bar');
		display.appendChild(footerTable);
		var footerBody = el('tbody');
		footerTable.appendChild(footerBody);
		var footerRow = el('tr');
		footerBody.appendChild(footerRow);
		footerRow.appendChild(el('td', 'width=150', createButton('return to index', "viewForum()")));
		if (pageNum == lastPageNum)
		{
			var footerCheckCell = el('td', null, createButton('check for new messages', "viewTopic("+topic.num+","+pageNum+")"));
			footerRow.appendChild(footerCheckCell);
		}
		var footerIndexCell = el('td', 'align=right');
		footerRow.appendChild(footerIndexCell);
		var footerIndexSpan = createIndexSpan(topic);
		footerIndexCell.appendChild(footerIndexSpan);

		page.tbody = tbody;
	}

	currentTopic = topic;
	currentPage = page;

	// switch displays
	showDisplay(page.display);

	// if the page is not full, or this is the last page, request a refresh
	var messages = page.messages;
	if (messages.length < pageSize || pageNum == lastPageNum)
	{
		var tracker = new MediaTracker();
		var url = currentForum.dir+'te.cgi?t='+topic.num+'&p='+pageNum+'&s='+(messages.length-1);
		tracker.get(url, doRefreshTopic);
	}
}

function showDisplay(display) {
	var forumBox = document.getElementById('forumbox');
	if (forumBox.firstChild) forumBox.removeChild(forumBox.firstChild);
	forumBox.appendChild(display);
}

function createButton(label, action) {
	var but = el('span', "class=button", tx(label));
	but.onclick = function(e) { eval(action); }
	if (but.captureEvents) but.captureEvents(Event.CLICK);
	//but.setAttribute('onclick', action);
	return but;
}

function doRefreshTopic(req) {
	var lines = splitLines(req.responseText);
	var tbody = currentPage.tbody;

	var phase = false;

	var i = 0;
	while (i < lines.length) {
		var message = new Message();
		// read header
		var lineCount = 0;
		for (; i < lines.length && lines[i].length > 0; i++) {
			var reg = /^([^:]*): (.*)$/;
			var bits = reg.exec(lines[i]);
			if (bits) {
				var field = bits[1];
				var value = bits[2];

				if (field == "Gravatar") message.gravatar = value;
				else if (field == "Author") message.author = value;
				else if (field == "Date") message.date = value;
				else if (field == "Time") message.time = value;
				else if (field == "MessageNum") message.messageNum = value;
				else if (field == "Lines") lineCount = value;
			}
		}

		i++;

		// read body
		message.body = '';
		for (var j = 0; (j < lineCount) && (i < lines.length); ) {
			message.body += lines[i] + '\n';
			i++;
			j++;
		}
		message.body = message.body.replace(/@[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)*/g, '@...');
		message.body = message.body.replace(/</g, '  lt;').replace(/>/g, '  gt;');
		message.body = message.body.replace(/(http:\/\/)?([\w-]+(\.[\w-]+)+[\.,a-zA-Z0-9_\-\/\?=%+&~:#]+)/g, '<a href="http://$2">$1$2</a>');
		message.body = message.body.replace(/([\.,])<\/a>/g, '</a>$1');
		message.body = message.body.replace(/href="([^"]+)([\.,])"/g, 'href="$1"');
		message.body = message.body.replace(/(\s+)([RLUDFBrludfbMESxyz]2?'?( ?[RLUDFBrludfbMESxyz]2?'?)+)(\s)/g,
				'$1<a href="javascript:animcube(&#34;$2&#34;);">$2</a>$4');
		message.body = message.body.replace(/  lt;/g, '&lt;').replace(/  gt/g, '&gt;');

		// add message
		currentPage.addMessage(message);
		//var gravUrl = "http://www.gravatar.com/avatar.php?gravatar_id="+message.gravatar+"&amp;default=http%3A%2F%2Foosan.ryanheise.com%2Fforums%2Favatar.gif&amp;size=80";
		var gravUrl = "http://www.gravatar.com/avatar.php?gravatar_id="+message.gravatar+"&amp;size=80";
		var shade = phase ? 'shade2' : 'shade1';

		var row = el('tr');
		tbody.appendChild(row);

		var authorCell = el('td', 'class=author_cell '+shade+',valign=top');
		row.appendChild(authorCell);
		var img = el('img');
		img.setAttribute('src', gravUrl);
		authorCell.appendChild(el('div','class=avatar',img));
		authorCell.appendChild(el('div','class=author',tx(message.author)));

		var bodyCell = el('td', 'class=body '+shade);
		row.appendChild(bodyCell);
		// Must use innerHTML to get <pre> to work correctly in IE
		var textEl = el('div');
		bodyCell.appendChild(textEl);
		textEl.innerHTML = 'Posted: '+message.date+'<pre>'+message.body+'</pre>';
		//pre.appendChild(tx(message.body));
		if (message.messageNum) {
			var replyUrl = currentForum.replyUrl + message.messageNum;
			var buttons = el('div', 'class=buttons', createButton('reply', "location.href = '"+ replyUrl +"';"));
			bodyCell.appendChild(buttons);
		}

		// flip phase
		phase = !phase;
	}
}

function el(type, attributes, content) {
	var element = document.createElement(type);
	if (attributes) {
		var attrs = attributes.split(',');
		for (var i = 0; i < attrs.length; i++)
		{
			var fields = attrs[i].split('=');
			if (fields[0] == 'class')
				element.className = fields[1];
			else if (fields[0] == 'onclick')
			{
				element.onclick = function(e) { eval(fields[1]); };
				if (element.captureEvents) element.captureEvents(Event.CLICK);
			}
			else
				element.setAttribute(fields[0], fields[1]);
		}
	}
	if (content) {
		element.appendChild(content);
	}
	return element;
}

function tx(text)
{
	return document.createTextNode(text);
}

function createIndexSpan(topic) {
	var indexSpan = el('span', 'class=bit');

	indexSpan.appendChild(tx('pages:'));
	var postCount = topic.replyCount + 1;
	for (var i = 1; i <= postCount; i += pageSize) {
		var targetPage = parseInt((i-1)/pageSize)+1;
		indexSpan.appendChild(tx(' '));
		var pageAnchor = document.createElement('a');
		pageAnchor.setAttribute('href', 'javascript:viewTopic('+topic.num+','+targetPage+');');
		pageAnchor.appendChild(tx(targetPage));
		indexSpan.appendChild(pageAnchor);
	}
	return indexSpan;
}

function animcube(seq)
{
	var cubeWin = window.open("", "AnimCube","status=1,width=350,height=350");
	cubeWin.document.write('<p><b>'+seq+'</b></p>');
	var applet = '';
	applet += '<applet code="AnimCube.class" archive="AnimCube.jar" width="150" height="150">';
	applet += '<param name="move" value="'+seq+'">';
	applet += '<param name="bgcolor" value="ffffff">';
	applet += '</applet>';
	cubeWin.document.write(applet);
}


document.write('<div class="board"><div id="forum_menu"></div><div id="forumbox"></div></div>');
