// 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}

/**
 * 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 |blessStringAsTrustedResourceUrlForLegacy}">
  {if $css and length($css)}
    {for $url in $css}
      <link rel="stylesheet" type="text/css" href="{$url |blessStringAsTrustedResourceUrlForLegacy}">
    {/for}
  {/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">
        {for $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}
        {/for}
        {sp}
        </div>
      {/if}
    </div>
  </header>

  <div class="Site-content">
    <div class="Container {if $containerClass}{$containerClass}{/if}">
      {if $breadcrumbs and length($breadcrumbs)}
        <div class="Breadcrumbs">
          {for $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}
          {/for}
        </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.
 */
{deltemplate gitiles.footerPoweredBy}
<span class="Footer-poweredBy">
  Powered by <a href="https://gerrit.googlesource.com/gitiles/">Gitiles</a>
</span>
{/deltemplate}

/**
 * Footer format badge
 *
 * You can use this in custom footers as well.
 */
{deltemplate gitiles.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>
{/deltemplate}

/**
 * Default Footer
 */
{deltemplate gitiles.customFooter}
<!-- default customFooter -->
<footer class="Site-footer">
  <div class="Footer">
   {delcall gitiles.footerPoweredBy /}
   {delcall 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}
