<?xjs
load("sbbsdefs.js");
load(cwd+"functions.js");
var messages_start = system.timer;
var total_time=0;
var sub_code=http_request.query.sub_code[0];
var msg_number=NaN;
if(http_request.query.msg_number!=undefined)
	msg_number=parseInt(http_request.query.msg_number[0]);
var msgs_per_request = 50;	// TODO - make this configurable (cookie?)
var msg_count=msgs_per_request;
if(http_request.query.msg_count!=undefined) {
	if(http_request.query.msg_count[0]=='all')
		msg_count=Infinity;
	else
		msg_count=parseInt(http_request.query.msg_count[0]);
}
var msg_offset=0;
if(http_request.query.msg_offset!=undefined)
	msg_offset=parseInt(http_request.query.msg_offset[0]);

// Load the index
var moderated=msg_area.sub[sub_code].is_moderated;

var headers=new Object();
var start=system.timer;
var msgbase=new MsgBase(sub_code);
var top_level=new Array();
if(msg_area.sub[sub_code].index!=-1)
	msgbase.open();

if(msgbase.total_msgs==0) {
	?><div class="no_messages">No messages in this sub</div><?xjs
	exit(0);
}
var hdr=msgbase.get_msg_header(true, msgbase.total_msgs-1,false);
var last_mod=new Date();
var last_mod_time=file_date(xjs_filename);
if(hdr.when_imported_time > last_mod_time)
	last_mod_time=hdr.when_imported_time;
if(file_date(cwd+'message_display.xjs') > last_mod_time)
	last_mod_time = file_date(cwd+'message_display.xjs');
last_mod.setTime(last_mod_time*1000);
if(http_request.header['If-Modified-Since'] != undefined) {
	if(last_mod <= new Date(http_request.header['If-Modified-Since'])) {
		http_reply.status="304 Not Modified";
		exit(0);
	}
}

/* First, read ALL headers that may be affect this display */
if(isNaN(msg_number)) {
	for(i=0; i<msgbase.total_msgs; i++) {
		var hdr=msgbase.get_msg_header(true, i, false /* Big speedup */);
		if(hdr==null)
			continue;
		if(moderated && (hdr.attr & MSG_VALIDATED) == 0)
			continue;
		if(hdr.attr & (MSG_PRIVATE|MSG_DELETE))
			continue;
		headers[hdr.number]=hdr;
		if(hdr.thread_back==0)
			top_level.push(hdr.number);
		else {
			/* Handle deleted top level message threads */
			if((hdr.thread_back < hdr.number) && headers[hdr.thread_back]==undefined)
				top_level.push(hdr.number);
		}
	}
}
else {
	var top_msg=msg_number;
	var hdr=msgbase.get_msg_header(msg_number, false /* Big speedup */);
	var these_headers=new Object();
	var last_good_message=msg_number;

	msg_number=hdr.thread_first;

	/* Depth-first traversal of replies */
	while(msg_number && msg_number!=top_msg) {
		hdr=headers[msg_number];
		if(hdr==undefined) {
			hdr=msgbase.get_msg_header(msg_number, false /* Big speedup */);
			if(hdr==null) {
				msg_number=last_good_message;
				these_headers[msg_number]=1;
				continue;
			}
			last_good_message=msg_number;
			if(moderated && (hdr.attr & MSG_VALIDATED) == 0)
				continue;
			if(hdr.attr & (MSG_PRIVATE|MSG_DELETE))
				continue;
			headers[hdr.number]=hdr;
		}
		if(these_headers[msg_number]==undefined) {
			these_headers[msg_number]=1;
			if(hdr.thread_back==top_msg)
				top_level.push(hdr.number);
			if(hdr.thread_first) {
				msg_number=hdr.thread_first;
				continue;
			}
		}
		if(hdr.thread_next && these_headers[msg_number]==undefined)
			msg_number=hdr.thread_next;
		else
			msg_number=hdr.thread_back;
	}
}

/* Now, do a reply count and new flag for every header */
var reply_count=new Object();
var new_stats=new Object();
for(i in top_level) {
	var moved_back=false;
	var top_msg=top_level[i];
	reply_count[top_msg]=0;
	new_stats[top_msg]=new Object();
	if(headers[top_msg].number > msg_area.sub[sub_code].scan_ptr)
		new_stats[top_msg].is_new=true;
	else
		new_stats[top_msg].is_new=false;
	new_stats[top_msg].inherit_new=false;
	new_stats[top_msg].newest_reply=0;
	new_stats[top_msg].date_sort=headers[top_msg].when_written_time;
	var parents=new Array();
	parents.push(top_msg);
	if(headers[top_msg].when_imported_time > last_mod_time)
		last_mod_time=headers[top_msg].when_imported_time;
	var last_good_message=top_msg;
	var last_next=0;

	msg_number=headers[top_msg].thread_first;
	while(msg_number && msg_number != top_msg) {
		var hdr=headers[msg_number];
		if(hdr==undefined) {
			msg_number=last_good_message;
			moved_back=true;
			continue;
		}
		last_good_message=msg_number;
		if(!moved_back) {
			/* This is a new thinger... update stuff based on it */
			reply_count[msg_number]=0;
			new_stats[msg_number]=new Object();
			if(headers[msg_number].number > msg_area.sub[sub_code].scan_ptr)
				new_stats[msg_number].is_new=true;
			else
				new_stats[msg_number].is_new=false;
			new_stats[msg_number].inherit_new=false;
			new_stats[msg_number].newest_reply=0;
			new_stats[msg_number].date_sort=headers[msg_number].when_written_time;

			for(i in parents) {
				var inner_top_msg=parents[i];
				reply_count[inner_top_msg]++;
				if(hdr.when_written_time > new_stats[inner_top_msg].newest_reply)
					new_stats[inner_top_msg].newest_reply = hdr.when_written_time;
				if(hdr.when_written_time > new_stats[inner_top_msg].date_sort)
					new_stats[inner_top_msg].date_sort = hdr.when_written_time;
				if(hdr.number > msg_area.sub[sub_code].scan_ptr)
					new_stats[inner_top_msg].inherit_new=true;
			}

			if(hdr.when_imported_time > last_mod_time)
				last_mod_time=hdr.when_imported_time;

			if(hdr.thread_first) {
				parents.push(msg_number);
				msg_number=hdr.thread_first;
				continue;
			}
		}
		if(hdr.thread_next && hdr.thread_next != last_next) {
			last_next=hdr.thread_next;
			msg_number=hdr.thread_next;
			moved_back=false;
			continue;
		}

		msg_number=hdr.thread_back;
		parents.pop();
		moved_back=true;
	}
}

// If the If-Modified-Since is greater or equal to last import time, we're done!
last_mod.setTime(last_mod_time*1000);
if(http_request.header['If-Modified-Since'] != undefined) {
	if(last_mod <= new Date(http_request.header['If-Modified-Since'])) {
		http_reply.status="304 Not Modified";
		exit(0);
	}
}
http_reply.header['Last-Modified']=strftime("%a, %d %b %Y %H:%M:%S GMT",last_mod.getTime()/1000);

top_level=top_level.sort(function(a,b) {
	return(new_stats[b].date_sort - new_stats[a].date_sort);
});

// Output messages... 
for(i=msg_offset; i<top_level.length; i++) {
	if(msg_count<=0) {
		write('<div class="load_more_messages"><a href="javascript:load_more_messages(\''+sub_code+'\','+i+','+msgs_per_request+')">Load more messages</a> - <a href="javascript:load_more_messages(\''+sub_code+'\','+i+',\'all\')">Load all messages</a></a>');
		break;
	}
	msg_number=top_level[i];
	/* This xjs_load() is recursive!  Whee! */
	xjs_load('message_display.xjs');
	msg_count--;
}
// Close the message base
msgbase.close();
?>
