<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<% 
/*
 * 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>
<%
load("header.esp");
load("constants.esp");

// SLING-1540 - currentNode might not be present
if(typeof(currentNode) == 'undefined') {
    currentNode = null;
}    

function render(attachmentNode) {
  if(attachmentNode.getNode("jcr:content").getProperty("jcr:mimeType").getString().substring(0,5) == "image") {
    %><p><img src="<%=attachmentNode%>"></p><%
  } else {	
    %><p><a href="<%=attachmentNode%>">Download <%=attachmentNode.getName()%></a></p><%
  }    
}

function renderMedia(postNode, mediaFolderName) {
	if(postNode.hasNode(mediaFolderName)) {
		%><h3><%= mediaFolderName %></h3><%
		if(currentNode) {
		  var nodes = currentNode.getNode(mediaFolderName).getNodes();
		  for(i in nodes) {
	       render(nodes[i]);
		  }
        }
	}
}
%>
	<body>
		<div class="title">
		  <div class="logo">
		    <a href="http://sling.apache.org">
		      <img border="0" src="/apps/espblog/sling-logo.png"/>
		    </a>
		  </div>
		</div>
		
		<div class="menu">
			<%
			load("menu.esp");
			%>
       </div>
       
       <div class="main">
			<h1><%= BLOG_TITLE %></h1>
			<div id="postbody">	
				<h2><%=(currentNode && currentNode.title) ? currentNode.title : ""%></h2>	
				<p><%=(currentNode && currentNode.posttext) ? currentNode.posttext : ""%></p>
				
				<%
				if(currentNode && currentNode.hasNode("comments")) {
				    %><h3>Comments</h3><%
					comments = currentNode.getNode("comments").getNodes()
					for (a in comments) {
						comment = comments[a]
						if(comment.commenttext){
					%>
					
					<div>
					<%=comment.commenter ? comment.commenter : "an anonymous coward"%> said:
					<p><%=comment.commenttext%></p>	
					</div>
				
				<%
						}
					}
				}
				%>
						
				<% if(currentNode && currentNode.title) { %>							
			    <h3>Comment on this post</h3>
				<form class="hform" method="POST" action="<%=currentNode%>/comments/*">
                    <p>
                        Note that you need to <a href="?sling:authRequestLogin=1">login</a> 
                        before commenting on this post.
                    </p> 
					<p><label>Your name</label><input type="text" size="80" name="commenter"/></p>
					<p><label>Your comment</label>
					<textarea name="commenttext" cols="40"></textarea></p>
					<input name=":redirect" type="hidden" value="<%=currentNode%>.view.html"/> 
					<input type="submit" value="Submit" class="button"/>
				</form>
				<% } %>
			</div>
			<div id="resources">
                <% if(currentNode) { %>                            
				    <% renderMedia(currentNode, "attachments"); %>
				    <% renderMedia(currentNode, "thumbnails"); %>
                <% } %>
			</div>
		</div>			
	</body>
</html>
