<%
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 *   
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
%>

<link rel="stylesheet" href="/apps/mailarchiveserver/styles.css"/>
<script type="text/javascript" src="/apps/mailarchiveserver/util.js"></script>
<% 
	var threadNodesNumber = 3

	var startPage = "/mailarchiveserver/archive.html"
	var homePage = "/mailarchiveserver.html?noredirect"

	function dateComparator (a, b) {
	if (a.date > b.date)
		return 1;
	else if (a.date < b.date)
		return -1;
	else
		return 0;
	}

	function OrderedRenderer (comparator, renderOptions) {
		this.list = []
		this.addMsg = function (msg) {
			var obj = new Object();
			obj.path = msg.getPath();
			obj.date = new Date(msg["Date"]);
			this.list.push(obj);
		}
		this.sort = function () {
			this.list.sort(comparator);
		}
		this.render = function () {
			while (this.list.length > 0) {
				 sling.include(this.list.pop().path, renderOptions); 
			}
		}
	}
	
%>
