<%
/*
 * 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.
 */
%>

<html>

<head>
<% load("../head.esp"); %>
<title>Search mail archive</title>
</head>

<body>
	<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>

	<div class="content">
<%
	var phrase = request.getParameter("q")
	if (phrase) {
		var service = sling.getService(Packages.org.apache.sling.mailarchiveserver.api.SearchService) 
		var resIter = service.find(phrase)
		var renderer = new OrderedRenderer(dateComparator, "forceResourceType=mailarchiveserver/message,replaceSelectors=preview")
		while (resIter.hasNext()) {
			var resource = resIter.next()
			var node = resource.adaptTo(Packages.javax.jcr.Node)
			renderer.addMsg(node)
		}
		out.print("Found " + renderer.list.length + " messages <br>")
		renderer.sort()
		renderer.render()
	}
%>
	</div>
</body>

</html>
