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

/**
 * Detailed listing of a commit.
 *
 * @param author map with "name", "email", and "time" keys for the commit author.
 * @param committer map with "name", "email", and "time" keys for the committer.
 * @param sha commit SHA-1.
 * @param tree tree SHA-1.
 * @param treeUrl tree URL.
 * @param parents list of parent objects with the following keys:
 *     sha: SHA-1.
 *     url: URL to view the parent commit.
 *     diffUrl: URL to display diffs relative to this parent.
 *     blameUrl: optional URL to display blame of a file at this parent.
 * @param message list of commit message parts, where each part contains:
 *     text: raw text of the part.
 *     url: optional URL that should be linked to from the part.
 * @param diffTree list of changed tree entries with the following keys:
 *     changeType: string matching an org.eclipse.jgit.diff.DiffEntry.ChangeType
 *         constant.
 *     path: (new) path of the tree entry.
 *     oldPath: old path, only for renames and copies.
 *     url: URL to a detail page for the tree entry.
 *     diffUrl: URL to a diff page for the tree entry's diff in this commit.
 * @param logUrl URL to a log page starting at this commit.
 * @param archiveUrl URL to a download link of this commit as an archive.
 * @param archiveType type of the archive to download.
 */
{template .commitDetail}
<div class="u-monospace Metadata">
  <table>
    <tr>
      <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
      <td>
        {$sha}
      </td>
      <td>
        <span>
          [<a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>]
        </span>
        {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
      </td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</th>
      <td>{call .person_ data="$author" /}</td>
      <td>{$author.time}</td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
      <td>{call .person_ data="$committer" /}</td>
      <td>{$committer.time}</td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for tree SHA entry"}tree{/msg}</th>
      <td><a href="{$treeUrl}">{$tree}</a></td>
    </tr>
    {foreach $parent in $parents}
      <tr>
        <th class="Metadata-title">{msg desc="Header for parent SHA"}parent{/msg}</th>
        <td>
          <a href="{$parent.url}">{$parent.sha}</a>
          {sp}<span>
            [<a href="{$parent.diffUrl}">{msg desc="text for the parent diff link"}diff{/msg}</a>]
            {if isNonnull($parent.blameUrl)}
              {sp}[<a href="{$parent.blameUrl}">{msg desc="text for the parent blame link"}blame{/msg}</a>]
            {/if}
          </span>
        </td>
      </tr>
    {/foreach}
  </table>
</div>
{call .message_}
  {param className: 'u-pre u-monospace MetadataMessage' /}
  {param message: $message /}
{/call}

{if $diffTree and length($diffTree)}
  <ul class="DiffTree">
    {foreach $entry in $diffTree}
      <li>
        <a href="{$entry.url}">{$entry.path}</a>
        {switch $entry.changeType}
          {case 'ADD'}
            <span class="DiffTree-action DiffTree-action--add">
              {msg desc="Text for a new tree entry"}
                [Added - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'MODIFY'}
            <span class="DiffTree-action DiffTree-action--modify">
              {msg desc="Text for a modified tree entry"}
                [<a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'DELETE'}
            <span class="DiffTree-action DiffTree-action--delete">
              {msg desc="Text for a deleted tree entry"}
                [Deleted - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'RENAME'}
            <span class="DiffTree-action DiffTree-action--rename">
              {msg desc="Text for a renamed tree entry"}
                [Renamed from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'COPY'}
            <span class="DiffTree-action DiffTree-action--copy">
              {msg desc="Text for a copied tree entry"}
                [Copied from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {default}
        {/switch}
      </li>
    {/foreach}
  </ul>
  <div class="DiffSummary">
    {if length($diffTree) == 1}
      {msg desc="1 file changed"}1 file changed{/msg}
    {else}
      {msg desc="number of files changed"}{length($diffTree)} files changed{/msg}
    {/if}
  </div>
{/if}

{/template}

/**
 * Detailed listing of a tree.
 *
 * @param sha SHA of this path's tree.
 * @param? logUrl optional URL to a log for this path.
 * @param? archiveUrl optional URL to a download link of this tree as an archive.
 * @param? archiveType type of the archive to download, if archiveUrl is set.
 * @param entries list of entries with the following keys:
 *     type: entry type, matching one of the constant names defined in
 *         org.eclipse.jgit.lib.FileMode.
 *     name: tree entry name.
 *     url: URL to link to.
 *     targetName: name of a symlink target, required only if type == 'SYMLINK'.
 *     targetUrl: optional url of a symlink target, required only if
 *         type == 'SYMLINK'.
 * @param? readmePath optional path of the selected README.md file.
 * @param? readmeHtml optional rendered README.md contents.
 */
{template .treeDetail}
<div class="TreeDetail">
  <div class="u-sha1 u-monospace TreeDetail-sha1">
    {msg desc="SHA-1 for the path's tree"}tree: {$sha}{/msg}
    {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a path"}path history{/msg}</a>]{/if}
    {if $archiveUrl}
      {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
    {/if}
  </div>

  {if length($entries)}
    <ol class="FileList">
      {foreach $entry in $entries}
        <li class="FileList-item{sp}
              {switch $entry.type}
                {case 'TREE'}FileList-item--gitTree
                {case 'SYMLINK'}FileList-item--symlink
                {case 'REGULAR_FILE'}FileList-item--regularFile
                {case 'EXECUTABLE_FILE'}FileList-item--executableFile
                {case 'GITLINK'}gitlink
                {default}regular-file
              {/switch}
              " title="
              {switch $entry.type}
                {case 'TREE'}{msg desc="Alt text for tree icon"}Tree{/msg}
                {case 'SYMLINK'}{msg desc="Alt text for symlink icon"}Symlink{/msg}
                {case 'REGULAR_FILE'}{msg desc="Alt text for regular file icon"}Regular file{/msg}
                {case 'EXECUTABLE_FILE'}
                  {msg desc="Alt text for executable file icon"}Executable file{/msg}
                {case 'GITLINK'}
                  {msg desc="Alt text for git submodule link icon"}Git submodule link{/msg}
                {default}{msg desc="Alt text for other file icon"}Other{/msg}
              {/switch}
              {sp}- {$entry.name}">
          <a class="FileList-itemLink" href="{$entry.url}">{$entry.name}</a>
          {if $entry.type == 'SYMLINK'}
            {sp}&#x21e8;{sp}
            {if $entry.targetUrl}
              <a href="{$entry.targetUrl}">{$entry.targetName}</a>
            {else}
              {$entry.targetName}
            {/if}
          {/if}
          // TODO(dborowitz): Something reasonable for gitlinks.
        </li>
      {/foreach}
    </ol>
  {else}
    <p>{msg desc="Informational text for when a tree is empty"}This tree is empty.{/msg}</p>
  {/if}

  {if $readmeHtml}
    <div class="InlineReadme">
      <div class="InlineReadme-path">{$readmePath}</div>
      <div class="doc">{$readmeHtml}</div>
    </div>
  {/if}
</div>
{/template}

/**
 * Common header for a blob shared between detail, blame, etc. views.
 *
 * @param sha SHA of this file's blob.
 * @param? fileUrl optional URL to a detail view of this file.
 * @param? logUrl optional URL to a log for this file.
 * @param? blameUrl optional URL to a blame for this file.
 * @param? docUrl optional URL to view rendered file.
 */
{template .blobHeader}
<div class="u-sha1 u-monospace BlobSha1">
  {msg desc="SHA-1 for the file's blob"}blob: {$sha}{/msg}
  {if $fileUrl}{sp}[<a href="{$fileUrl}">{msg desc="detail view of a file"}file{/msg}</a>]{/if}
  {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a file"}log{/msg}</a>]{/if}
  {if $blameUrl}{sp}[<a href="{$blameUrl}">{msg desc="blame for a file"}blame{/msg}</a>]{/if}
  {if $docUrl}{sp}[<a href="{$docUrl}">{msg desc="view rendered file"}view{/msg}</a>]{/if}
</div>
{/template}

/**
 * Detailed listing of a blob.
 *
 * @param sha SHA of this file's blob.
 * @param? logUrl optional URL to a log for this file.
 * @param? blameUrl optional URL to a blame for this file.
 * @param lines lines (may be empty), or null for a binary file. Each line
 *     is a list of entries with "classes" and "text" fields for pretty-printed
 *     spans.
 * @param? size for binary files only, size in bytes.
 */
{template .blobDetail}
  {call .blobHeader data="all" /}

  {if $lines != null}
    {if $lines}
      <table class="FileContents">
        {foreach $line in $lines}
          {let $n: index($line) + 1 /}
          <tr class="u-pre u-monospace FileContents-line">
            <td class="u-lineNum u-noSelect FileContents-lineNum"
                data-line-number="{$n}" onclick="window.location.hash='#{$n}'"></td>
            <td class="FileContents-lineContents" id="{$n}">
              {foreach $span in $line}
                <span class="{$span.classes}">{$span.text}</span>
              {/foreach}
            </td>
          </tr>
        {/foreach}
      </table>
    {else}
      <div class="FileContents-empty">Empty file</div>
    {/if}
  {else}
    <div class="FileContents-binary">
      {msg desc="size of binary file in bytes"}{$size}-byte binary file{/msg}
    </div>
  {/if}
{/template}

/**
 * Detailed listing of an annotated tag.
 *
 * @param sha SHA of this tag.
 * @param? tagger optional map with "name", "email", and "time" keys for the
 *     tagger.
 * @param object SHA of the object this tag points to.
 * @param message tag message.
 */
{template .tagDetail}
<div class="u-monospace Metadata">
  <table>
    <tr>
      <th class="Metadata-title">{msg desc="Header for tag SHA entry"}tag{/msg}</th>
      <td class="sha">{$sha}</td>
      <td>{sp}</td>
    </tr>
    {if $tagger}
      <tr>
        <th class="Metadata-title">{msg desc="Header for tagger"}tagger{/msg}</th>
        <td>{call .person_ data="$tagger" /}</td>
        <td>{$tagger.time}</td>
      </tr>
    {/if}
    <tr>
      <th class="Metadata-title">{msg desc="Header for tagged object SHA"}object{/msg}</th>
      <td class="sha">{$object}</td>
      <td>{sp}</td>
    </tr>
  </table>
</div>
{if $message and length($message)}
  {call .message_}
    {param className: 'u-pre u-monospace MetadataMessage' /}
    {param message: $message /}
  {/call}
{/if}
{/template}

/**
 * Line about a git person identity.
 *
 * @param name name.
 * @param email email.
 */
{template .person_}
{$name}{if $email} &lt;{$email}&gt;{/if}
{/template}

/**
 * Preformatted message, possibly containing hyperlinks.
 *
 * @param className CSS class name for <pre> block.
 * @param message list of message parts, where each part contains:
 *     text: raw text of the part.
 *     url: optional URL that should be linked to from the part.
 */
{template .message_ visibility="private"}
<pre class="{$className}">
  {foreach $part in $message}
    {if $part.url}<a href="{$part.url}">{$part.text}</a>{else}{$part.text}{/if}
  {/foreach}
</pre>
{/template}
