## usage:
## <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
## ${comment.comment_block(comment)}
##
<%namespace name="base" file="/base/base.mako"/>

<%!
    from rhodecode.lib import html_filters
%>


<%def name="comment_block(comment, inline=False, active_pattern_entries=None, is_new=False)">

    <%
      from rhodecode.model.comment import CommentsModel
      comment_model = CommentsModel()

      comment_ver = comment.get_index_version(getattr(c, 'versions', []))
      latest_ver = len(getattr(c, 'versions', []))
      visible_for_user = True
      if comment.draft:
        visible_for_user = comment.user_id == c.rhodecode_user.user_id
    %>

  % if inline:
      <% outdated_at_ver = comment.outdated_at_version(c.at_version_num) %>
  % else:
      <% outdated_at_ver = comment.older_than_version(c.at_version_num) %>
  % endif

  % if visible_for_user:
  <div class="comment
             ${'comment-inline' if inline else 'comment-general'}
             ${'comment-outdated' if outdated_at_ver else 'comment-current'}"
       id="comment-${comment.comment_id}"
       line="${comment.line_no}"
       data-comment-id="${comment.comment_id}"
       data-comment-type="${comment.comment_type}"
       data-comment-draft=${h.str_json(comment.draft)}
       data-comment-renderer="${comment.renderer}"
       data-comment-text="${comment.text | html_filters.base64,n}"
       data-comment-f-path="${comment.f_path}"
       data-comment-line-no="${comment.line_no}"
       data-comment-inline=${h.str_json(inline)}
       style="${'display: none;' if outdated_at_ver else ''}">

      <div class="meta">
          <div class="comment-type-label">
               % if comment.draft:
               <div class="tooltip comment-draft" title="${_('Draft comments are only visible to the author until submitted')}.">
                DRAFT
               </div>
               % elif is_new:
               <div class="tooltip comment-new" title="${_('This comment was added while you browsed this page')}.">
                NEW
               </div>
               % endif

              <div class="comment-label ${comment.comment_type or 'note'}" id="comment-label-${comment.comment_id}">

              ## TODO COMMENT
              % if comment.comment_type == 'todo':
                  % if comment.resolved:
                      <div class="resolved tooltip" title="${_('Resolved by comment #{}').format(comment.resolved.comment_id)}">
                          <i class="icon-flag-filled"></i>
                          <a href="#comment-${comment.resolved.comment_id}">${comment.comment_type}</a>
                      </div>
                  % else:
                      <div class="resolved tooltip" style="display: none">
                          <span>${comment.comment_type}</span>
                      </div>
                      <div class="resolve tooltip" onclick="return Rhodecode.comments.createResolutionComment(${comment.comment_id});" title="${_('Click to create resolution comment.')}">
                        <i class="icon-flag-filled"></i>
                        ${comment.comment_type}
                      </div>
                  % endif
              ## NOTE COMMENT
              % else:
                  ## RESOLVED NOTE
                  % if comment.resolved_comment:
                    <div class="tooltip" title="${_('This comment resolves TODO #{}').format(comment.resolved_comment.comment_id)}">
                        fix
                        <a href="#comment-${comment.resolved_comment.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${comment.resolved_comment.comment_id}'), 0, ${h.str_json(comment.resolved_comment.outdated)})">
                            <span style="text-decoration: line-through">#${comment.resolved_comment.comment_id}</span>
                        </a>
                    </div>
                  ## STATUS CHANGE NOTE
                  % elif not comment.is_inline and comment.status_change:
                    <%
                        if comment.pull_request:
                            status_change_title = 'Status of review for pull request !{}'.format(comment.pull_request.pull_request_id)
                        else:
                            status_change_title = 'Status of review for commit {}'.format(h.short_id(comment.commit_id))
                    %>

                    <i class="icon-circle review-status-${comment.review_status}"></i>
                    <div class="changeset-status-lbl tooltip" title="${status_change_title}">
                         ${comment.review_status_lbl}
                    </div>
                  % else:
                    <div>
                        <i class="icon-comment"></i>
                        ${(comment.comment_type or 'note')}
                    </div>
                  % endif
              % endif

              </div>
          </div>
          ## NOTE 0 and .. => because we disable it for now until UI ready
          % if 0 and comment.status_change:
          <div class="pull-left">
              <span  class="tag authortag tooltip" title="${_('Status from pull request.')}">
                  <a href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id)}">
                      ${'!{}'.format(comment.pull_request.pull_request_id)}
                  </a>
              </span>
          </div>
          % endif
          ## Since only author can see drafts, we don't show it
          % if not comment.draft:
          <div class="author ${'author-inline' if inline else 'author-general'}">
              ${base.gravatar_with_user(comment.author.email, 16, tooltip=True)}
          </div>
          % endif

          <div class="date">
              ${h.age_component(comment.modified_at, time_is_local=True)}
          </div>

          % if comment.pull_request and comment.pull_request.author.user_id == comment.author.user_id:
            <span class="tag authortag tooltip" title="${_('Pull request author')}">
            ${_('author')}
            </span>
          % endif

          <%
          comment_version_selector = 'comment_versions_{}'.format(comment.comment_id)
          %>

          % if comment.history:
              <div class="date">

                 <input id="${comment_version_selector}" name="${comment_version_selector}"
                        type="hidden"
                        data-last-version="${comment.history[-1].version}">

                 <script type="text/javascript">

                    var preLoadVersionData = [
                       % for comment_history in comment.history:
                            {
                                id: ${comment_history.comment_history_id},
                                text: 'v${comment_history.version}',
                                action: function () {
                                    Rhodecode.comments.showVersion(
                                        "${comment.comment_id}",
                                        "${comment_history.comment_history_id}"
                                    )
                                },
                                comment_version: "${comment_history.version}",
                                comment_author_username: "${comment_history.author.username}",
                                comment_author_gravatar: "${h.gravatar_url(comment_history.author.email, 16, request=request)}",
                                comment_created_on: '${h.age_component(comment_history.created_on, time_is_local=True)}',
                            },
                       % endfor
                        ]
                    initVersionSelector("#${comment_version_selector}", {results: preLoadVersionData});

                  </script>

              </div>
          % else:
              <div class="date" style="display: none">
                <input id="${comment_version_selector}" name="${comment_version_selector}"
                       type="hidden"
                       data-last-version="0">
              </div>
          %endif

          <div class="comment-links-block">

            % if inline:
                    <a class="pr-version-inline" href="${request.current_route_path(_query=dict(version=comment.pull_request_version_id), _anchor='comment-{}'.format(comment.comment_id))}">
                    % if outdated_at_ver:
                        <strong class="comment-outdated-label">outdated</strong> <code class="tooltip pr-version-num" title="${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}">${'v{}'.format(comment_ver)}</code>
                        <code class="action-divider">|</code>
                    % elif comment_ver:
                        <code class="tooltip pr-version-num" title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}">${'v{}'.format(comment_ver)}</code>
                        <code class="action-divider">|</code>
                    % endif
                    </a>
            % else:
                % if comment_ver:

                      % if comment.outdated:
                        <a class="pr-version"
                           href="?version=${comment.pull_request_version_id}#comment-${comment.comment_id}"
                        >
                            ${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}
                        </a>
                        <code class="action-divider">|</code>
                      % else:
                        <a class="tooltip pr-version"
                           title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}"
                           href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id, version=comment.pull_request_version_id)}"
                        >
                            <code class="pr-version-num">${'v{}'.format(comment_ver)}</code>
                        </a>
                        <code class="action-divider">|</code>
                      % endif

                % endif
            % endif

            <details class="details-reset details-inline-block">
              <summary class="noselect"><i class="icon-options cursor-pointer"></i></summary>
              <details-menu class="details-dropdown">

                <div class="dropdown-item">
                    ${_('Comment')} #${comment.comment_id}
                    <span class="pull-right icon-clipboard clipboard-action" data-clipboard-text="${comment_model.get_url(comment,request, permalink=True, anchor='comment-{}'.format(comment.comment_id))}" title="${_('Copy permalink')}"></span>
                </div>

                ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
                ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
                %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
                   ## permissions to delete
                   %if comment.immutable is False and (c.is_super_admin or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id):
                       <div class="dropdown-divider"></div>
                       <div class="dropdown-item">
                        <a onclick="return Rhodecode.comments.editComment(this, '${comment.line_no}', '${comment.f_path}');" class="btn btn-link btn-sm edit-comment">${_('Edit')}</a>
                       </div>
                       <div class="dropdown-item">
                        <a onclick="return Rhodecode.comments.deleteComment(this);" class="btn btn-link btn-sm btn-danger delete-comment">${_('Delete')}</a>
                       </div>
                       ## Only available in EE edition
                       % if comment.draft and c.rhodecode_edition_id == 'EE':
                       <div class="dropdown-item">
                        <a onclick="return Rhodecode.comments.finalizeDrafts([${comment.comment_id}]);" class="btn btn-link btn-sm finalize-draft-comment">${_('Submit draft')}</a>
                       </div>
                       % endif
                   %else:
                      <div class="dropdown-divider"></div>
                      <div class="dropdown-item">
                        <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
                      </div>
                      <div class="dropdown-item">
                        <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
                      </div>
                   %endif
                %else:
                    <div class="dropdown-divider"></div>
                    <div class="dropdown-item">
                      <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
                    </div>
                    <div class="dropdown-item">
                      <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
                    </div>
                %endif
              </details-menu>
            </details>

            <code class="action-divider">|</code>
            % if outdated_at_ver:
                <a onclick="return Rhodecode.comments.prevOutdatedComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous outdated comment')}"> <i class="icon-angle-left"></i> </a>
                <a onclick="return Rhodecode.comments.nextOutdatedComment(this);" class="tooltip next-comment" title="${_('Jump to the next outdated comment')}"> <i class="icon-angle-right"></i></a>
            % else:
                <a onclick="return Rhodecode.comments.prevComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous comment')}"> <i class="icon-angle-left"></i></a>
                <a onclick="return Rhodecode.comments.nextComment(this);" class="tooltip next-comment" title="${_('Jump to the next comment')}"> <i class="icon-angle-right"></i></a>
            % endif

          </div>
      </div>
      <div class="text">
          ${h.render(comment.text, renderer=comment.renderer, mentions=True, repo_name=getattr(c, 'repo_name', None), active_pattern_entries=active_pattern_entries)}
      </div>

  </div>
  % endif
</%def>

## generate main comments
<%def name="generate_comments(comments, include_pull_request=False, is_pull_request=False)">
  <%
    active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
  %>

  <div class="general-comments" id="comments">
    %for comment in comments:
        <div id="comment-tr-${comment.comment_id}">
          ## only render comments that are not from pull request, or from
          ## pull request and a status change
          %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
          ${comment_block(comment, active_pattern_entries=active_pattern_entries)}
          %endif
        </div>
    %endfor
    ## to anchor ajax comments
    <div id="injected_page_comments"></div>
  </div>
</%def>


<%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">

<div class="comments">
    <%
      if is_pull_request:
        placeholder = _('Leave a comment on this Pull Request.')
      elif is_compare:
        placeholder = _('Leave a comment on {} commits in this range.').format(len(form_extras))
      else:
        placeholder = _('Leave a comment on this Commit.')
    %>

    % if c.rhodecode_user.username != h.DEFAULT_USER:
    <div class="js-template" id="cb-comment-general-form-template">
        ## template generated for injection
        ${comment_form(form_type='general', review_statuses=c.commit_statuses, form_extras=form_extras)}
    </div>

    <div id="cb-comment-general-form-placeholder" class="comment-form ac">
        ## inject form here
    </div>
    <script type="text/javascript">
        var resolvesCommentId = null;
        var generalCommentForm = Rhodecode.comments.createGeneralComment(
            'general', "${placeholder}", resolvesCommentId);

        // set custom success callback on rangeCommit
        % if is_compare:
            generalCommentForm.setHandleFormSubmit(function(o) {
                var self = generalCommentForm;

                var text = self.cm.getValue();
                var status = self.getCommentStatus();
                var commentType = self.getCommentType();
                var isDraft = self.getDraftState();

                if (text === "" && !status) {
                    return;
                }

                // we can pick which commits we want to make the comment by
                // selecting them via click on preview pane, this will alter the hidden inputs
                var cherryPicked = $('#changeset_compare_view_content .compare_select.hl').length > 0;

                var commitIds = [];
                $('#changeset_compare_view_content .compare_select').each(function(el) {
                    var commitId = this.id.replace('row-', '');
                    if ($(this).hasClass('hl') || !cherryPicked) {
                        $("input[data-commit-id='{0}']".format(commitId)).val(commitId);
                        commitIds.push(commitId);
                    } else {
                        $("input[data-commit-id='{0}']".format(commitId)).val('')
                    }
                });

                self.setActionButtonsDisabled(true);
                self.cm.setOption("readOnly", true);
                var postData = {
                    'text': text,
                    'changeset_status': status,
                    'comment_type': commentType,
                    'draft': isDraft,
                    'commit_ids': commitIds,
                    'csrf_token': CSRF_TOKEN
                };

                var submitSuccessCallback = function(o) {
                    location.reload(true);
                };
                var submitFailCallback = function(){
                    self.resetCommentFormState(text)
                };
                self.submitAjaxPOST(
                    self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
            });
        % endif

    </script>
    % else:
    ## form state when not logged in
    <div class="comment-form ac">

        <div class="comment-area">
            <div class="comment-area-header">
                <ul class="nav-links clearfix">
                    <li class="active">
                        <a class="disabled" href="#edit-btn" disabled="disabled" onclick="return false">${_('Write')}</a>
                    </li>
                    <li class="">
                        <a class="disabled" href="#preview-btn" disabled="disabled" onclick="return false">${_('Preview')}</a>
                    </li>
                </ul>
            </div>

            <div class="comment-area-write" style="display: block;">
                <div id="edit-container">
                    <div style="padding: 20px 0px 0px 0;">
                      ${_('You need to be logged in to leave comments.')}
                      <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
                    </div>
                </div>
                <div id="preview-container" class="clearfix" style="display: none;">
                    <div id="preview-box" class="preview-box"></div>
                </div>
            </div>

            <div class="comment-area-footer">
                <div class="toolbar">
                    <div class="toolbar-text">
                    </div>
                </div>
            </div>
        </div>

        <div class="comment-footer">
        </div>

    </div>
    % endif

    <script type="text/javascript">
        bindToggleButtons();
    </script>
</div>
</%def>


<%def name="comment_form(form_type, form_id='', lineno_id='{1}', review_statuses=None, form_extras=None)">

  ## comment injected based on assumption that user is logged in
  <form ${('id="{}"'.format(form_id) if form_id else '') |n} action="#" method="GET">

    <div class="comment-area">
        <div class="comment-area-header">
            <div class="pull-left">
                <ul class="nav-links clearfix">
                    <li class="active">
                        <a href="#edit-btn" tabindex="-1" id="edit-btn_${lineno_id}">${_('Write')}</a>
                    </li>
                    <li class="">
                        <a href="#preview-btn" tabindex="-1" id="preview-btn_${lineno_id}">${_('Preview')}</a>
                    </li>
                </ul>
            </div>
            <div class="pull-right">
                <span class="comment-area-text">${_('Mark as')}:</span>
                <select class="comment-type" id="comment_type_${lineno_id}" name="comment_type">
                    % for val in c.visual.comment_types:
                        <option value="${val}">${val.upper()}</option>
                    % endfor
                </select>
            </div>
        </div>

        <div class="comment-area-write" style="display: block;">
            <div id="edit-container_${lineno_id}" style="margin-top: -1px">
                <textarea id="text_${lineno_id}" name="text" class="comment-block-ta ac-input"></textarea>
            </div>
            <div id="preview-container_${lineno_id}" class="clearfix" style="display: none;">
                <div id="preview-box_${lineno_id}" class="preview-box"></div>
            </div>
        </div>

        <div class="comment-area-footer comment-attachment-uploader">
            <div class="toolbar">

                <div class="comment-attachment-text">
                    <div class="dropzone-text">
                        ${_("Drag'n Drop files here or")} <span class="link pick-attachment">${_('Choose your files')}</span>.<br>
                    </div>
                    <div class="dropzone-upload" style="display:none">
                        <i class="icon-spin animate-spin"></i> ${_('uploading...')}
                    </div>
                </div>

                ## comments dropzone template, empty on purpose
                <div style="display: none" class="comment-attachment-uploader-template">
                    <div class="dz-file-preview" style="margin: 0">
                        <div class="dz-error-message"></div>
                    </div>
                </div>

            </div>
        </div>
    </div>

    <div class="comment-footer">

        ## inject extra inputs into the form
        % if form_extras and isinstance(form_extras, (list, tuple)):
            <div id="comment_form_extras">
                % for form_ex_el in form_extras:
                    ${form_ex_el|n}
                % endfor
            </div>
        % endif

        <div class="action-buttons">
            % if form_type != 'inline':
                <div class="action-buttons-extra"></div>
            % endif

            <input class="btn btn-success comment-button-input submit-comment-action" id="save_${lineno_id}" name="save" type="submit" value="${_('Add comment')}" data-is-draft=false onclick="$(this).addClass('submitter')">

            % if form_type == 'inline':
                % if c.rhodecode_edition_id == 'EE':
                    ## Disable the button for CE, the "real" validation is in the backend code anyway
                    <input class="btn btn-draft comment-button-input submit-draft-action" id="save_draft_${lineno_id}" name="save_draft" type="submit" value="${_('Add draft')}" data-is-draft=true onclick="$(this).addClass('submitter')">
                % else:
                    <input class="btn btn-draft comment-button-input submit-draft-action disabled" disabled="disabled" type="submit"  value="${_('Add draft')}" onclick="return false;" title="Draft comments only available in EE edition of RhodeCode">
                % endif
            % endif

            % if review_statuses:
            <div class="comment-status-box">
              <select id="change_status_${lineno_id}" name="changeset_status">
                  <option></option> ## Placeholder
                  % for status, lbl in review_statuses:
                  <option value="${status}" data-status="${status}">${lbl}</option>
                      %if is_pull_request and change_status and status in ('approved', 'rejected'):
                          <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
                      %endif
                  % endfor
              </select>
            </div>
            % endif

            ## inline for has a file, and line-number together with cancel hide button.
            % if form_type == 'inline':
                <input type="hidden" name="f_path" value="{0}">
                <input type="hidden" name="line" value="${lineno_id}">
                <span style="opacity: 0.7" class="cursor-pointer cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
                ${_('dismiss')}
                </span>
            % endif
        </div>

        <div class="toolbar-text">
            <% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
            <span>${_('{} is supported.').format(renderer_url)|n}

            <i class="icon-info-circled tooltip-hovercard"
               data-hovercard-alt="ALT"
               data-hovercard-url="javascript:commentHelp('${c.visual.default_renderer.upper()}')"
               data-comment-json-b64='${h.b64(h.str_json({}))}'></i>
            </span>
        </div>
    </div>

  </form>

</%def>