# Source: src/js/views/SignInView.js

    /*global define */

    define(['jquery', 'underscore', 'backbone', 'text!templates/login.html',
            'text!templates/alert.html', 'text!templates/loginButtons.html',
            'text!templates/loginOptions.html', 'text!templates/login-ldap.html'],
      function($, _, Backbone, LoginTemplate, AlertTemplate, LoginButtonsTemplate, LoginOptionsTemplate, LdapLoginTemplate) {
      'use strict';

      /**
      * @class SignInView
      * @classcategory Views
      * @extends Backbone.View
      * @screenshot views/SignInView.png
      */
      var SignInView = Backbone.View.extend(
        /** @lends SignInView.prototype */{

        template: _.template(LoginTemplate),
        alertTemplate: _.template(AlertTemplate),
        buttonsTemplate: _.template(LoginButtonsTemplate),
        loginOptionsTemplate: _.template(LoginOptionsTemplate),
        ldapTemplate: _.template(LdapLoginTemplate),

        tagName: "div",
        className: "sign-in-btns",

        ldapError: false,

        /* Set to true to only show the LDAP login form */
        ldapOnly: false,

        /* Set to true if this SignInView is the only thing on the page */
        fullPage: false,

        /* Set to true if this SignInView is in a modal window */
        inPlace: false,

        /**
        * Set a query string that will be added to the redirect URL
        * when the user has logged-in and is returned back to MetacatUI.
        * This can be useful to return back to MetacatUI with additional information
        * about the state of the app when the user left to sign in.
        * @type {string}
        * @example
        * // This example may tell the view that the register citation modal was open when Sign In was clicked
        * "registerCitation=true"
        * @default ""
        * @since 2.15.0
        */
        redirectQueryString: "",

        /*A message to display at the top of the view */
        topMessage: "",

        initialize: function(options){
          if(typeof options !== "undefined"){
            this.inPlace = options.inPlace;
            this.topMessage = options.topMessage;
            this.fullPage = options.fullPage;
            this.closeButtons = options.closeButtons === false? false : true;
          }
        },

        render: function(){
          //Don't render a SignIn view if there are no Sign In URLs configured
          if(!MetacatUI.appModel.get("signInUrlOrcid"))
            return this;

          var view = this;

          if(this.inPlace){
            this.$el.addClass("hidden modal");
            this.$el.attr("data-backdrop", "static");

            //Add a message to the top, if supplied
            if(typeof this.topMessage == "string")
              this.$el.prepend('<p class="center container">' + this.topMessage + '</p>');
            else if(typeof this.topMessage == "object")
              this.$el.prepend(this.topMessage);

            //Copy/paste the contents of the sign-in popup
            var signInBtns = $.parseHTML($("#signinPopup").html().trim()),
              signInBtnsContainer = $(document.createElement("div")).addClass("center container").html(signInBtns);

            signInBtnsContainer.find("a.signin").each(function(i, a){
              var url = $(a).attr("href");

              var redirectUrl = decodeURIComponent(url.substring( url.indexOf("target=")+7 ));

              var urlWithoutHttp = redirectUrl.substring( redirectUrl.indexOf("://") +  3 );
              var routeName = urlWithoutHttp.substring( urlWithoutHttp.indexOf("/") + 1 );

              if( !routeName ){
                redirectUrl = redirectUrl + "signinsuccess";
              }
              else if( _.contains(MetacatUI.uiRouter.getRouteNames(), MetacatUI.uiRouter.getRouteName(routeName)) ){
                redirectUrl = redirectUrl.substring(0, redirectUrl.indexOf(routeName)) + "signinsuccess";
              }

              url = url.substring(0, url.indexOf("target=")+7) + encodeURIComponent(redirectUrl);
              $(a).attr("href", url);
            });

            signInBtnsContainer.find("h1, h2").remove();

            this.$el.append(signInBtnsContainer);

            //Remove the accordion widget from the ldap login so it gets displayed as a popup window instead
            if( this.$("#signinLdap").length ){
              this.$("[href='" + "#signinLdap']").addClass("signin");
              this.$(".accordion").removeClass("accordion");
            }

            this.$el.prepend($(document.createElement("div")).addClass("container").prepend(
                $(document.createElement("a")).text("Close").addClass("close").prepend(
                $(document.createElement("i")).addClass("icon icon-on-left icon-remove"))));

            //Listen for clicks
            this.$("a.signin").on("click", function(e){
              //Get the link URL and change the target to a special route
              e.preventDefault();

              var link = e.target;
              if(link.nodeName != "A") link = $(link).parents("a");

              var url = $(link).attr("href");

              //Open up a new small window with this URL to allow the user to login
              window.open(url, "Login", "height=600,width=700");

              //Listen for successful sign-in
              window.listenForSignIn = setInterval(function(){
                MetacatUI.appUserModel.checkToken(function(data){
                  $(".modal.sign-in-btns").modal("hide");
                  clearInterval(window.listenForSignIn);

                  if(MetacatUI.appUserModel.get("checked"))
                    MetacatUI.appUserModel.trigger("change:checked");
                  else
                    MetacatUI.appUserModel.set("checked", true);
                });
              }, 750);
            });

            if( this.closeButtons ){
              this.$("a.close").on("click", function(e){
                view.$el.modal("hide");
              });
            }
            else{
              this.$(".close").remove();

              //Create a sign out link
              var divider     = document.createElement("hr"),
                  signOutLink = $(document.createElement("a"))
                                  .addClass("error underline")
                                  .text("Sign Out");

              //Add the Sign Out link to the view
              this.$(".modal-body").append(divider, signOutLink);

              //If we're on the EML211EditorView, then show a warning message that unsaved changes will be lost
              if( MetacatUI.appView.currentView && MetacatUI.appView.currentView.type == "EML211Editor" ){
                signOutLink.after( $(document.createElement("p"))
                  .addClass("error")
                  .text("   Warning! - All your unsaved changes will be lost."));
              }

              //When the sign out link is clicked, we can just refresh the page.
              signOutLink.on("click", function(e){
                window.location.reload();
              });

            }
          }
          else{

            //If it's a full-page sign-in view, then empty it first
            if(this.el == MetacatUI.appView.el || this.fullPage){
              this.$el.empty();
              var container = document.createElement("div");
              container.className = "container login";

              if( this.ldapOnly ){

                var redirectUrl = window.location.origin + window.location.pathname;
                redirectUrl = redirectUrl.substring(0, redirectUrl.lastIndexOf("/"));
                redirectUrl + "/signinSuccessLdap";

                $(container).append(this.ldapTemplate({
                  redirectUrl:  redirectUrl
                }));
                this.$el.append(container);

                //Hide all the other page elements so it's just the login form
                $("#Navbar, #HeaderContainer, #Footer").hide();
              }
              else{
                $(container).append(this.buttonsTemplate({
                  signInUrl: MetacatUI.appModel.get('signInUrlOrcid') + this.getRedirectURL()
                }));
                this.$el.append(container);
              }

            }
            else{

              if( this.ldapOnly ){

                var redirectUrl = MetacatUI.root + "/signinSuccessLdap";

                this.$el.append(this.ldapTemplate({
                  redirectUrl: redirectUrl
                }));

              }
              else{
                let signInUrl = MetacatUI.appModel.get('signInUrlOrcid') + this.getRedirectURL();

                this.$el.append(this.buttonsTemplate({
                  signInUrl: signInUrl
                }));
              }

            }

            //Insert the sign in popup screen once
            if(!$("#signinPopup").length){
              var target = this.getRedirectURL();
              var signInUrl = MetacatUI.appModel.get('signInUrl')? MetacatUI.appModel.get('signInUrl') + target : null;
              var signInUrlOrcid = MetacatUI.appModel.get('signInUrlOrcid') ? MetacatUI.appModel.get('signInUrlOrcid') + target : null;
              var signInUrlLdap = MetacatUI.appModel.get('signInUrlLdap') ? MetacatUI.appModel.get('signInUrlLdap') + target : null,
                  redirectUrl = (window.location.href.indexOf("signinldaperror") > -1) ?
                      window.location.href.replace("signinldaperror", "") : window.location.href;

              $("body").append(this.template({
                signInUrl:  signInUrl,
                signInUrlOrcid:  signInUrlOrcid,
                signInUrlLdap:  signInUrlLdap,
                ldapLoginForm: this.ldapTemplate({
                  redirectUrl: redirectUrl
                }),
                currentUrl: window.location.href,
                loginOptions: this.loginOptionsTemplate({ signInUrl: signInUrl }).trim(),
                collapseLdap: !MetacatUI.appUserModel.get("errorLogin"),
                redirectUrl: redirectUrl
              }));

              this.setUpPopup();
            }

            //If there is an error message in the URL, it means authentication has failed
            if(this.ldapError){
              MetacatUI.appUserModel.failedLdapLogin();
              this.failedLdapLogin();
            };
          }

          return this;
        },

        /*
         * This function is executed when LDAP authentication fails in the DataONE portal
         */
        failedLdapLogin: function(){
          //Insert an error message
          this.$("form").before(this.alertTemplate({
            classes: "alert-error",
            msg: "Incorrect username or password. Please try again."
          }));

          //If this is a full-page sign-in view, then take the form and insert it into the page
          if(this.$el.attr("id") == "Content" && !$("#Content form").length)
            $("#Content").html( $("#signinLdap").html() );
          //Else, just show the login in the modal window
          else if(!this.ldapOnly){
            $("#signinPopup").modal("show");
          }

          //Show the LDAP login form
          $('#signinLdap').removeClass("collapse").css("height", "auto");
        },

        setUpPopup: function(){
          var view = this;

          //Initialize the modal elements
          $("#signupPopup, #signinPopup").modal({
            show: false,
            shown: function(){

              //Update the sign-in URLs so we are redirected back to the previous page after authentication
              if( MetacatUI.appModel.get("enableCILogonSignIn") ){
                $("a.update-sign-in-url").attr("href", MetacatUI.appModel.get("signInUrl") + encodeURIComponent(window.location.href));
              }
              $("a.update-orcid-sign-in-url").attr("href", MetacatUI.appModel.get("signInUrlOrcid") + encodeURIComponent(window.location.href));

            }
          });
        },

        /**
        * Constructs and returns a string of the URL that the user should return to when they are done signing in.
        * This URL is sent to the DataONE portal service during login, via the `target` URL attribute. The DataONE
        * portal will redirect the user back to the `target` URL when sign in is complete.
        * @returns {string}
        */
        getRedirectURL: function(){
          let redirectURL = window.location.href;

          if( this.redirectQueryString && this.redirectQueryString.length ){
            let currentQueryString = window.location.search;

            //If there is a current query string in the window.location, concatenate the
            // new query string properly
            if( currentQueryString.length ){

              //Exclude the "?" character from the query string, if it is there already
              if( this.redirectQueryString.charAt(0) == "?" ){
                this.redirectQueryString = this.redirectQueryString.substring(1)
              }

              //Add the new query string parameters
              redirectURL += "&" + this.redirectQueryString;

            }
            else{
              redirectURL += "?" + this.redirectQueryString;
            }
          }

          return redirectURL;
        },

        onClose: function(){
          this.$el.empty();

          if(window.listenForSignIn)  clearInterval(window.listenForSignIn);
        }
      });
      return SignInView;

    });