<!--
  This in an HTML Import-able file that contains the JS and HTML Templates for
  the login.

  To use this file import it:

    <link href="/res/imp/login.html" rel="import" />

  There is nothing to instantiate, on load the #login element will be found and
  populated with the users login status.

  Methods:
    checkLogin(): Used by single-page apps to for the calculation of a new
                  a new login url and check the login status. Not
                  nessary if each page is rendered by the server as this
                  will be called in the ready function. This function is
                  asynchronous.
-->
<script type="text/javascript" charset="utf-8">
(function(){
  // A Promise that will be resolved with the users current login status.
  //
  // The resolution object looks like:
  //
  //   {
  //     "Email": "fred@example.com",
  //     "LoginURL": "https://..."
  //   }
  //
  // The Email will be the empty string if the user is not logged in.
  sk.Login = new Promise(function(resolve, reject) {
    sk.get('/loginstatus/').then(JSON.parse).then(resolve).catch(function(reason){
        reject("Problem reaching /loginstatus/ "+reason);
    });
  });

})();
</script>

<!--
  The <login-sk> custom element.

  Uses sk.Login promise to display the current login status and provides
  login/logout links.

  The color of the text in the login-sk element can be controlled by
  the --login-sk-color custom CSS attribute.
-->

<dom-module id="login-sk">
  <style type="text/css" media="screen">
    @media (max-width: 500px) {
      #email {
        display: none;
      }
    }

    #logInOut {
      margin-left: 10px;
    }

    #email,
    #logInOut {
      font-size: 15px;
    }

    span,
    a[href] {
      color: var(--login-sk-color, lightgray)
    }
  </style>
  <template>
    <span id=email>{{email}}</span>
    <a id=logInOut href=""></a>
  </template>
</dom-module>

<script>
  Polymer({
    is: "login-sk",

    properties: {
      email: {
        type: String,
        value: '',
        notify: true,
      },
      login_data: {
        type: Object,
        notify: true,
      },
    },

    ready: function() {
      this._handleStatusCheck(sk.Login);
    },

    checkLogin: function() {
      // TODO(stephana): This should be merged with sk.Login above.
      // sk.Login should not be used as a global variable, see
      // dependency in comments-sk.html.
      var p = new Promise(function(resolve, reject) {
        sk.get('/loginstatus/').then(JSON.parse).then(resolve).catch(function(reason){
          reject("Problem reaching /loginstatus/ "+reason);
        });
      });
      this._handleStatusCheck(p);
    },

    _handleStatusCheck: function(promise) {
      promise.then(function(status) {
        this.email = status['Email'];
        this.data = status['Data'];
        if (this.email == '') {
          this.$.logInOut.href = status['LoginURL'];
          this.$.logInOut.innerText = 'Login';
        } else {
          this.$.logInOut.href = "/logout/?redirect=" + encodeURIComponent(document.location);
          this.$.logInOut.innerText = 'Logout';
        }
      }.bind(this));
    }
  });
</script>
