// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed 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.
{namespace gitiles autoescape="strict"}

/**
 * Common header for Gitiles.
 *
 * @param title title for this page. Always suffixed with repository name and a
 *     sitewide title.
 * @param? repositoryName repository name for this page, if applicable.
 * @param? menuEntries optional list of menu entries with "text" and optional
 *     "url" keys.
 * @param? customVariant variant name for custom styling.
 * @param breadcrumbs navigation breadcrumbs for this page.
 * @param? css optional list of CSS URLs to include.
 * @param? containerClass optional class to append to the main container.
 */
{template .header stricthtml="false"}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>
    {$title}
    {if $repositoryName}
      {sp}- {$repositoryName}
    {/if}
    {sp}- {msg desc="name of the application"}{gitiles.SITE_TITLE}{/msg}
  </title>

  <link rel="stylesheet" type="text/css" href="{gitiles.BASE_CSS_URL}">
  {if $css and length($css)}
    {foreach $url in $css}
      <link rel="stylesheet" type="text/css" href="{$url}">
    {/foreach}
  {/if}
  {delcall gitiles.customHeadTagPart variant="$customVariant ?: ''" /}

</head>
<body class="Site">
  <header class="Site-header">
    <div class="Header">
      {delcall gitiles.customHeader variant="$customVariant ?: ''" /}

      {if $menuEntries and length($menuEntries)}
        <div class="Header-menu">
        {foreach $entry in $menuEntries}
          {sp}
          {if $entry.url}
            <a class="Header-menuItem" href="{$entry.url}">{$entry.text}</a>
          {else}
            <span class="Header-menuItem Header-menuItem--noAction">{$entry.text}</span>
          {/if}
        {/foreach}
        {sp}
        </div>
      {/if}
    </div>
  </header>

  <div class="Site-content">
    <div class="Container {if $containerClass}{$containerClass}{/if}">
      {if $breadcrumbs and length($breadcrumbs)}
        <div class="Breadcrumbs">
          {foreach $entry in $breadcrumbs}
            {if not isFirst($entry)}{sp}/{sp}{/if}
            {if not isLast($entry)}
              <a class="Breadcrumbs-crumb" href="{$entry.url}">{$entry.text}</a>
            {else}
              <span class="Breadcrumbs-crumb">{$entry.text}</span>
            {/if}
          {/foreach}
        </div>
      {/if}
{/template}

/**
 * Default (empty) custom head tag part
 *
 * This can be used to include per-project CSS/JS by
 * providing custom variants.
 */
{deltemplate gitiles.customHeadTagPart}
  <!-- default customHeadTagPart -->
{/deltemplate}

/**
 * Default custom header implementation for Gitiles.
 */
{deltemplate gitiles.customHeader}
<!-- default customHeader -->
<div class="Header-title">
  {msg desc="short name of the application"}{gitiles.SITE_TITLE}{/msg}
</div>
{/deltemplate}

/**
 * Footer 'powered by' element
 *
 * Please call this in custom variants as well.
 */
{template .footerPoweredBy}
<span class="Footer-poweredBy">
  Powered by <a href="https://gerrit.googlesource.com/gitiles/">Gitiles</a>
</span>
{/template}

/**
 * Footer format badge
 *
 * You can use this in custom footers as well.
 */
{template .footerFormatBadge}
<span class="Footer-formats">
  <a class="u-monospace Footer-formatsItem" href="?format=TEXT">{msg desc="text format"}txt{/msg}</a>
    {sp}
  <a class="u-monospace Footer-formatsItem" href="?format=JSON">{msg desc="JSON format"}json{/msg}</a>
</span>
{/template}

/**
 * Default Footer
 */
{deltemplate gitiles.customFooter}
<!-- default customFooter -->
<footer class="Site-footer">
  <div class="Footer">
   {call gitiles.footerPoweredBy /}
   {call gitiles.footerFormatBadge /}
  </div>
</footer>
{/deltemplate}

/**
 * Main footer.
 *
 * The footer tag part can be customized by creating a customFooter
 * variant template.
 *
 * @param? customVariant variant name for custom styling.
 */
{template .footer stricthtml="false"}
    </div> <!-- Container -->
  </div> <!-- Site-content -->
  {delcall gitiles.customFooter variant="$customVariant ?: ''" /}
</body>
</html>
{/template}

/**
 * Placeholder for streaming rendering.
 *
 * Insert this in a template to use with
 * Renderer#renderStreaming(HttpServletResponse, String).
 */
{template .streamingPlaceholder}
<br id="STREAMED_OUTPUT_BLOCK">
{/template}
