<%inherit file="/base/base.mako"/>
<%namespace name="dt" file="/data_table/_dt_elements.mako"/>

<%def name="title()">
    ${c.repo_name} ${_('New pull request')}
</%def>

<%def name="breadcrumbs_links()"></%def>

<%def name="menu_bar_nav()">
    ${self.menu_items(active='repositories')}
</%def>

<%def name="menu_bar_subnav()">
    ${self.repo_menu(active='showpullrequest')}
</%def>

<%def name="main()">
<div class="box">
    ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}

        <div class="box">

            <div class="summary-details block-left">

                <div class="form" style="padding-top: 10px">

                    <div class="fields" >

                        ## COMMIT FLOW
                        <div class="field">
                            <div class="label label-textarea">
                                <label for="commit_flow">${_('Commit flow')}:</label>
                            </div>

                            <div class="content">
                                <div class="flex-container">
                                    <div style="width: 45%;">
                                        <div class="panel panel-default source-panel">
                                            <div class="panel-heading">
                                                <h3 class="panel-title">${_('Source repository')}</h3>
                                            </div>
                                            <div class="panel-body">
                                                <div style="display:none">${c.rhodecode_db_repo.description}</div>
                                                ${h.hidden('source_repo')}
                                                ${h.hidden('source_ref')}

                                                <div id="pr_open_message"></div>
                                            </div>
                                        </div>
                                    </div>

                                    <div style="width: 90px; text-align: center; padding-top: 30px">
                                    <div>
                                        <i class="icon-right" style="font-size: 2.2em"></i>
                                    </div>
                                    <div style="position: relative; top: 10px">
                                    <span class="tag tag">
                                        <span id="switch_base"></span>
                                    </span>
                                    </div>

                                </div>

                                    <div style="width: 45%;">

                                    <div class="panel panel-default target-panel">
                                        <div class="panel-heading">
                                            <h3 class="panel-title">${_('Target repository')}</h3>
                                        </div>
                                        <div class="panel-body">
                                          <div style="display:none" id="target_repo_desc"></div>
                                          ${h.hidden('target_repo')}
                                          ${h.hidden('target_ref')}
                                          <span id="target_ref_loading" style="display: none">
                                              ${_('Loading refs...')}
                                          </span>
                                        </div>
                                    </div>

                                </div>
                                </div>

                            </div>

                        </div>

                        ## TITLE
                        <div class="field">
                            <div class="label">
                                <label for="pullrequest_title">${_('Title')}:</label>
                            </div>
                            <div class="input">
                                ${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
                            </div>
                            <p class="help-block">
                                Start the title with WIP: to prevent accidental merge of Work In Progress pull request before it's ready.
                            </p>
                        </div>

                        ## DESC
                        <div class="field">
                            <div class="label label-textarea">
                                <label for="pullrequest_desc">${_('Description')}:</label>
                            </div>
                            <div class="textarea text-area">
                                <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}">
                                ${dt.markup_form('pullrequest_desc')}
                            </div>
                        </div>

                        ## REVIEWERS
                        <div class="field">
                            <div class="label label-textarea">
                                <label for="pullrequest_reviewers">${_('Reviewers / Observers')}:</label>
                            </div>
                            <div class="content">
                                ## REVIEW RULES
                                <div id="review_rules" style="display: none" class="reviewers-title">
                                    <div class="pr-details-title">
                                        ${_('Reviewer rules')}
                                    </div>
                                    <div class="pr-reviewer-rules">
                                        ## review rules will be appended here, by default reviewers logic
                                    </div>
                                </div>

                                ## REVIEWERS / OBSERVERS
                                <div class="reviewers-title">

                                    <ul class="nav-links clearfix">

                                        ## TAB1 MANDATORY REVIEWERS
                                        <li class="active">
                                            <a id="reviewers-btn" href="#showReviewers" tabindex="-1">
                                                Reviewers
                                                <span id="reviewers-cnt" data-count="0" class="menulink-counter">0</span>
                                            </a>
                                        </li>

                                        ## TAB2 OBSERVERS
                                        <li class="">
                                            <a id="observers-btn" href="#showObservers" tabindex="-1">
                                                Observers
                                                <span id="observers-cnt"  data-count="0" class="menulink-counter">0</span>
                                            </a>
                                        </li>

                                    </ul>

                                    ## TAB1 MANDATORY REVIEWERS
                                    <div id="reviewers-container">
                                        <span class="calculate-reviewers">
                                            <h4>${_('loading...')}</h4>
                                        </span>

                                        <div id="reviewers" class="pr-details-content reviewers">
                                            ## members goes here, filled via JS based on initial selection !
                                            <input type="hidden" name="__start__" value="review_members:sequence">
                                            <table id="review_members" class="group_members">
                                            ## This content is loaded via JS and ReviewersPanel, an sets reviewer_entry class on each element
                                            </table>
                                            <input type="hidden" name="__end__" value="review_members:sequence">

                                            <div id="add_reviewer_input" class='ac'>
                                                <div class="reviewer_ac">
                                                    ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
                                                    <div id="reviewers_container"></div>
                                                </div>
                                            </div>

                                        </div>
                                    </div>

                                    ## TAB2 OBSERVERS
                                    <div id="observers-container" style="display: none">
                                        <span class="calculate-reviewers">
                                            <h4>${_('loading...')}</h4>
                                        </span>
                                        % if c.rhodecode_edition_id == 'EE':
                                        <div id="observers" class="pr-details-content observers">
                                            ## members goes here, filled via JS based on initial selection !
                                            <input type="hidden" name="__start__" value="observer_members:sequence">
                                            <table id="observer_members" class="group_members">
                                            ## This content is loaded via JS and ReviewersPanel, an sets reviewer_entry class on each element
                                            </table>
                                            <input type="hidden" name="__end__" value="observer_members:sequence">

                                            <div id="add_observer_input" class='ac'>
                                                <div class="observer_ac">
                                                    ${h.text('observer', class_='ac-input', placeholder=_('Add observer or observer group'))}
                                                    <div id="observers_container"></div>
                                                </div>
                                            </div>
                                        </div>
                                        % else:
                                            <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4>
                                            <p>
                                                Pull request observers allows adding users who don't need to leave mandatory votes, but need to be aware about certain changes.
                                            </p>
                                        % endif
                                    </div>

                                </div>

                            </div>
                        </div>

                        ## SUBMIT
                        <div class="field">
                            <div class="label label-textarea">
                                <label for="pullrequest_submit"></label>
                            </div>
                            <div class="input">
                                <div class="pr-submit-button">
                                    <input id="pr_submit" class="btn" name="save" type="submit" value="${_('Submit Pull Request')}">
                                </div>
                            </div>
                            % if c.rhodecode_edition_id == 'EE':
                            <div class="pull-request-settings">
                                ${h.checkbox('close_branch_before_merging',
                                checked=c.repo_close_branch_before_merging, value=True)}
                                <label for="close_branch_before_merging">
                                    % if c.rhodecode_db_repo.repo_type == 'hg':
                                        ${h.literal(_('Close branch before merging'))}
                                    % elif c.rhodecode_db_repo.repo_type == 'git':
                                        ${h.literal(_('Delete branch after merging'))}
                                    % endif
                                </label>
                            </div>
                            % endif
                        </div>
                    </div>
                </div>
            </div>

        </div>

    ${h.end_form()}
</div>

<script type="text/javascript">
 $(function(){
   var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
   var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
   var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
   var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
   var prTargetBranchPrepopulate = ${'true' if c.default_repo_data['pr_target_branch_prepopulate'] else 'false'};

   var $pullRequestForm = $('#pull_request_form');
   var $pullRequestSubmit = $('#pr_submit', $pullRequestForm);
   var $sourceRepo = $('#source_repo', $pullRequestForm);
   var $targetRepo = $('#target_repo', $pullRequestForm);
   var $sourceRef = $('#source_ref', $pullRequestForm);
   var $targetRef = $('#target_ref', $pullRequestForm);

   var sourceRepo = function() { return $sourceRepo.eq(0).val() };
   var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };

   var targetRepo = function() { return $targetRepo.eq(0).val() };
   var targetRef = function() { return $targetRef.eq(0).val().split(':') };

   var calculateContainerWidth = function() {
       var maxWidth = 0;
       var repoSelect2Containers = ['#source_repo', '#target_repo'];
       $.each(repoSelect2Containers, function(idx, value) {
           $(value).select2('container').width('auto');
           var curWidth = $(value).select2('container').width();
           if (maxWidth <= curWidth) {
               maxWidth = curWidth;
           }
           $.each(repoSelect2Containers, function(idx, value) {
               $(value).select2('container').width(maxWidth + 10);
           });
       });
   };

   var initRefSelection = function(selectedRef) {
       return function(element, callback) {
           // translate our select2 id into a text, it's a mapping to show
           // simple label when selecting by internal ID.
           var id, refData;
           if (selectedRef === undefined || selectedRef === null) {
             id = element.val();
             refData = element.val().split(':');

             if (refData.length !== 3){
                 refData = ["", "", ""]
             }
           } else {
             id = selectedRef;
             refData = selectedRef.split(':');
           }

           var text = refData[1];
           if (refData[0] === 'rev') {
               text = text.substring(0, 12);
           }

           var data = {id: id, text: text};
           callback(data);
       };
   };

   var formatRefSelection = function(data, container, escapeMarkup) {
       var prefix = '';
       var refData = data.id.split(':');
       if (refData[0] === 'branch') {
           prefix = '<i class="icon-branch"></i>';
       }
       else if (refData[0] === 'book') {
           prefix = '<i class="icon-bookmark"></i>';
       }
       else if (refData[0] === 'tag') {
           prefix = '<i class="icon-tag"></i>';
       }

       return prefix + escapeMarkup(truncateMiddle(data.text, 35));
   };

   // custom code mirror
   var codeMirrorInstance = $('#pullrequest_desc').get(0).MarkupForm.cm;

   var diffDataHandler = function(data) {
       if (data['error'] !== undefined) {
           var noCommitsMsg = '<span class="alert-text-error">{0}</span>'.format(data['error']);
           prButtonLock(true, noCommitsMsg, 'compare');
           //make both panels equal
           $('.target-panel').height($('.source-panel').height())
           return false
       }

       var commitElements = data['commits'];
       var files = data['files'];
       var added = data['stats'][0]
       var deleted = data['stats'][1]
       var commonAncestorId = data['ancestor'];
       var _sourceRefType = sourceRef()[0];
       var _sourceRefName = sourceRef()[1];
       var prTitleAndDesc = getTitleAndDescription(_sourceRefType, _sourceRefName, commitElements, 5);

       var title = prTitleAndDesc[0];
       var proposedDescription = prTitleAndDesc[1];

       var useGeneratedTitle = (
            $('#pullrequest_title').hasClass('autogenerated-title') ||
            $('#pullrequest_title').val() === "");

       if (title && useGeneratedTitle) {
           // use generated title if we haven't specified our own
           $('#pullrequest_title').val(title);
           $('#pullrequest_title').addClass('autogenerated-title');

       }

       var useGeneratedDescription = (
           !codeMirrorInstance._userDefinedValue ||
            codeMirrorInstance.getValue() === "");

       if (proposedDescription && useGeneratedDescription) {
            // set proposed content, if we haven't defined our own,
            // or we don't have description written
            codeMirrorInstance._userDefinedValue = false; // reset state
            codeMirrorInstance.setValue(proposedDescription);
       }

       // refresh our codeMirror so events kicks in and it's change aware
       codeMirrorInstance.refresh();

       var url_data = {
           'repo_name': targetRepo(),
           'target_repo': sourceRepo(),
           'source_ref': targetRef()[2],
           'source_ref_type': 'rev',
           'target_ref': sourceRef()[2],
           'target_ref_type': 'rev',
           'merge': true,
           '_': Date.now() // bypass browser caching
       }; // gather the source/target ref and repo here
       var url = pyroutes.url('repo_compare', url_data);

       var msg = '<input id="common_ancestor" type="hidden" name="common_ancestor" value="{0}">'.format(commonAncestorId);
       msg += '<input type="hidden" name="__start__" value="revisions:sequence">'


       $.each(commitElements, function(idx, value) {
           var commit_id = value["commit_id"]
           msg += '<input type="hidden" name="revisions" value="{0}">'.format(commit_id);
       });

       msg += '<input type="hidden" name="__end__" value="revisions:sequence">'
       msg += _ngettext(
           'Compare summary: <strong>{0} commit</strong>',
           'Compare summary: <strong>{0} commits</strong>',
           commitElements.length).format(commitElements.length)

       msg += '';
       msg += _ngettext(
           '<strong>, and {0} file</strong> changed.',
           '<strong>, and {0} files</strong> changed.',
           files.length).format(files.length)

       msg += '\n Diff: <span class="op-added">{0} lines inserted</span>, <span class="op-deleted">{1} lines deleted </span>.'.format(added, deleted)

       msg += '\n <a class="" id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);

       if (commitElements.length) {
           var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
           prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
       }
       else {
           var noCommitsMsg = '<span class="alert-text-warning">{0}</span>'.format(
               _gettext('There are no commits to merge.'));
           prButtonLock(true, noCommitsMsg, 'compare');
       }

       //make both panels equal
       $('.target-panel').height($('.source-panel').height());
       return true
   };

   reviewersController = new ReviewersController();
   reviewersController.diffDataHandler = diffDataHandler;

   function truncateSelection(item) {
       if (item.text !== undefined) {
           return truncateMiddle(item.text, 35);
       }
       return item;
   }

   function truncateResult(item) {
       if (item.text !== undefined) {
           return truncateMiddle(item.text, 60);
       }
       return item;
   }

   var queryTargetRepo = function(self, query) {
       // cache ALL results if query is empty
       var cacheKey = query.term || '__';
       var cachedData = self.cachedDataSource[cacheKey];

       if (cachedData) {
           query.callback({results: cachedData.results});
       } else {
           $.ajax({
               url: pyroutes.url('pullrequest_repo_targets', {'repo_name': templateContext.repo_name}),
               data: {query: query.term},
               dataType: 'json',
               type: 'GET',
               success: function(data) {
                   self.cachedDataSource[cacheKey] = data;
                   query.callback({results: data.results});
               },
               error: function(jqXHR, textStatus, errorThrown) {
                var prefix = "Error while fetching entries.\n"
                var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix);
                ajaxErrorSwal(message);
               }
           });
       }
   };

   var queryTargetRefs = function(initialData, query) {
       var data = {results: []};
       // filter initialData
       $.each(initialData, function() {
           var section = this.text;
           var children = [];
           $.each(this.children, function() {
               if (query.term.length === 0 ||
                   this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
                   children.push({'id': this.id, 'text': this.text})
               }
           });
           data.results.push({'text': section, 'children': children})
       });
       query.callback({results: data.results});
   };

   var Select2Box = function(element, overrides) {
     var globalDefaults = {
         dropdownAutoWidth: true,
         containerCssClass: "drop-menu",
         dropdownCssClass: "drop-menu-dropdown",
         formatSelection: truncateSelection,
         formatResult: truncateResult
     };

     var initSelect2 = function(defaultOptions) {
       var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
       element.select2(options);
     };

     return {
       initRef: function() {
         var defaultOptions = {
           minimumResultsForSearch: 5,
           formatSelection: formatRefSelection
         };

         initSelect2(defaultOptions);
       },

       initRepo: function(defaultValue, readOnly) {
         var defaultOptions = {
           initSelection : function (element, callback) {
             var data = {id: defaultValue, text: defaultValue};
             callback(data);
           }
         };

         initSelect2(defaultOptions);

         element.select2('val', defaultSourceRepo);
         if (readOnly === true) {
           element.select2('readonly', true);
         }
       }
     };
   };

   var initTargetRefs = function(refsData, selectedRef) {

     Select2Box($targetRef, {
         placeholder: "${_('Select commit reference')}",
       query: function(query) {
         queryTargetRefs(refsData, query);
       },
       initSelection : initRefSelection(selectedRef)
     }).initRef();

     if (!(selectedRef === undefined)) {
         $targetRef.select2('val', selectedRef);
     }
   };

   var targetRepoChanged = function(repoData) {
       // generate new DESC of target repo displayed next to select

       $('#target_repo_desc').html(repoData['description']);

       var prLink = pyroutes.url('pullrequest_new', {'repo_name': repoData['name']});
       var title = _gettext('Switch target repository with the source.')
       $('#switch_base').html("<a class=\"tooltip\" title=\"{0}\" href=\"{1}\">Switch sides</a>".format(title, prLink))

       // generate dynamic select2 for refs.
       // Only pre-populate target branch if the setting allows it
       var selectedRef = prTargetBranchPrepopulate ? repoData['refs']['selected_ref'] : null;
       initTargetRefs(repoData['refs']['select2_refs'], selectedRef);

   };

   var sourceRefSelect2 = Select2Box($sourceRef, {
       placeholder: "${_('Select commit reference')}",
       query: function(query) {
         var initialData = defaultSourceRepoData['refs']['select2_refs'];
         queryTargetRefs(initialData, query)
       },
       initSelection: initRefSelection()
   });

   var sourceRepoSelect2 = Select2Box($sourceRepo, {
     query: function(query) {}
   });

   var targetRepoSelect2 = Select2Box($targetRepo, {
     cachedDataSource: {},
     query: $.debounce(250, function(query) {
       queryTargetRepo(this, query);
     }),
     formatResult: formatRepoResult
   });

   sourceRefSelect2.initRef();

   sourceRepoSelect2.initRepo(defaultSourceRepo, true);

   targetRepoSelect2.initRepo(defaultTargetRepo, false);

   $sourceRef.on('change', function(e){
     reviewersController.loadDefaultReviewers(
         sourceRepo(), sourceRef(), targetRepo(), targetRef());
   });

   $targetRef.on('change', function(e){
     reviewersController.loadDefaultReviewers(
         sourceRepo(), sourceRef(), targetRepo(), targetRef());
   });

   $targetRepo.on('change', function(e){
       var repoName = $(this).val();
       calculateContainerWidth();
       $targetRef.select2('destroy');
       $('#target_ref_loading').show();

       $.ajax({
           url: pyroutes.url('pullrequest_repo_refs',
             {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
           data: {},
           dataType: 'json',
           type: 'GET',
           success: function(data) {
               $('#target_ref_loading').hide();
               targetRepoChanged(data);
           },
           error: function(jqXHR, textStatus, errorThrown) {
                var prefix = "Error while fetching entries.\n"
                var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix);
                ajaxErrorSwal(message);
           }
       })

   });

   $pullRequestForm.on('submit', function(e){
       // Flush changes into textarea
       codeMirrorInstance.save();
       prButtonLock(true, null, 'all');
       $pullRequestSubmit.val(_gettext('Please wait creating pull request...'));
   });

   prButtonLock(true, "${_('Please select source and target')}", 'all');

   // auto-load on init, the target refs select2
   calculateContainerWidth();
   targetRepoChanged(defaultTargetRepoData);

   $('#pullrequest_title').on('keyup', function(e){
       $(this).removeClass('autogenerated-title');
   });

   % if c.default_source_ref:
   // in case we have a pre-selected value, use it now
   $sourceRef.select2('val', '${c.default_source_ref}');


   // default reviewers / observers
   reviewersController.loadDefaultReviewers(
       sourceRepo(), sourceRef(), targetRepo(), targetRef());
   % endif

   ReviewerAutoComplete('#user', reviewersController);
   ObserverAutoComplete('#observer', reviewersController);

   // TODO, move this to another handler

   var $reviewersBtn = $('#reviewers-btn');
   var $reviewersContainer = $('#reviewers-container');

   var $observersBtn = $('#observers-btn')
   var $observersContainer = $('#observers-container');

   $reviewersBtn.on('click', function (e) {

       $observersContainer.hide();
       $reviewersContainer.show();

       $observersBtn.parent().removeClass('active');
       $reviewersBtn.parent().addClass('active');
       e.preventDefault();

   })

   $observersBtn.on('click', function (e) {

       $reviewersContainer.hide();
       $observersContainer.show();

       $reviewersBtn.parent().removeClass('active');
       $observersBtn.parent().addClass('active');
       e.preventDefault();

   })

 });
</script>

</%def>
