<%
/*
 * 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.
 */
%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="en" lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <%
      //allow the caller to override the title by
      //  specifying request attributes.
      var title = request.getAttribute("page.title");
      if (title == null) {
         title = resource.path;
      }
      
      var userDisplayName = null;
      if (request.getUserPrincipal() != null && !"anonymous".equals(request.getRemoteUser())) {
          var userResource = request.getResourceResolver().getResource("/system/userManager/user/" + request.getRemoteUser());
          var valueMap = userResource.adaptTo(Packages.org.apache.sling.api.resource.ValueMap);
          userDisplayName = valueMap.get("displayName", request.getRemoteUser());
      }
      
      var currentPage = request.contextPath + resource.path + ".html";
      var logoutTarget = request.getAttribute("logout.target");
      if (logoutTarget == null) {
          logoutTarget = currentPage;
      }
      var rb = request.getResourceBundle("org.apache.sling.usermgr.Resources", null);
    %>
    <title><%= Packages.java.text.MessageFormat.format(rb.getString("page.template.title"), title) %></title>
    
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/themes/cupertino/jquery-ui.css" type="text/css"/>
    <link rel="stylesheet" href="<%= request.getContextPath() %>/css/usermanager/usermanager.min.css" type="text/css"/>
</head>
<%
//flush the buffer early so the browser can start start fetching the stylesheets and scripts in parallel
// while the rest of the page is being rendered below.
response.flushBuffer();
%>
<body>
    <div id="menu_login" class="ui-widget ui-widget-content ui-corner-all">
      <% if (userDisplayName != null) { %>        
      <strong id="menu_username"><%=userDisplayName%></strong> | <a href="<%=request.contextPath%>/system/sling/logout?resource=<%=logoutTarget%>" id="do_logout"><%=rb.getString("link.logout")%></a>
      <% } else { %>
      <a href="<%=request.contextPath%>/system/sling/selector/login?resource=<%=currentPage%>" id="do_login"><%=rb.getString("link.login")%></a>
      <% } %>
    </div>
    
    <div class="title">
        <div class="logo">
            <a href="http://sling.apache.org">
                <img alt='<%=rb.getString("logo.alt")%>' src="<%=request.getContextPath()%>/images/sling-logo.png"/>
            </a>
        </div>
    </div>
    
    <div class="menu">
    <% 
        var template = request.getAttribute("sidebar.template");
        if (template != null) {
           var options = request.getAttribute("sidebar.template.options");
           if (options == null) {
              sling.include(template);
           } else {
              sling.include(template, options);
           }
        } 
    %>
    </div>          

    <div id="content" class="main">
        <noscript>
            <div class="ui-widget" style="margin-bottom: 10px;">
                <div style="padding: 0pt 0.7em;" class="ui-state-error ui-corner-all"> 
                    <p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span> 
                    <%=rb.getString("msg.noscript")%></p>
                </div>
            </div>
        </noscript>
    
    <% 
        var template = request.getAttribute("body.template");
        if (template != null) {
           var options = request.getAttribute("body.template.options");
           if (options == null) {
              sling.include(template);
           } else {
              sling.include(template, options);
           }
        } 
    %>
    </div>

    <%-- scripts moved to the bottom to help the page load faster --%>    
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.min.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js"></script>
    <script type="text/javascript" src="<%= request.getContextPath() %>/js/usermanager/usermanager.min.js"></script>
    <script type="text/javascript">UserManager.contextPath = "<%=request.contextPath%>";</script>
</body>
</html>