<!--
Copyright (C) 2015 The Android Open Source Project

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.
-->

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="gr-request.html">

<dom-module id="gr-change-star">
  <template>
    <style>
      :host {
        display: inline-block;
        overflow: hidden;
      }
      .starButton {
        background-color: transparent;
        border-color: transparent;
        cursor: pointer;
        font-size: 1.1em;
        width: 1.2em;
        height: 1.2em;
        outline: none;
      }
      .starButton svg {
        fill: #aab8c2;
        width: 1em;
        height: 1em;
      }
      .starButton-active svg {
        fill: #ffac33;
      }
    </style>
    <button class$="[[_computeStarClass(change.starred)]]" on-tap="_handleStarTap">
      <!-- Public Domain image from the Noun Project: https://thenounproject.com/search/?q=star&i=25969 -->
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><path d="M26.439,95.601c-5.608,2.949-9.286,0.276-8.216-5.968l4.5-26.237L3.662,44.816c-4.537-4.423-3.132-8.746,3.137-9.657  l26.343-3.829L44.923,7.46c2.804-5.682,7.35-5.682,10.154,0l11.78,23.87l26.343,3.829c6.27,0.911,7.674,5.234,3.138,9.657  L77.277,63.397l4.501,26.237c1.07,6.244-2.608,8.916-8.216,5.968L50,83.215L26.439,95.601z"></path></svg>
    </button>
  </template>
  <script>
  (function() {
    'use strict';

    Polymer({
      is: 'gr-change-star',

      properties: {
        change: {
          type: Object,
          notify: true,
        },

        _xhrPromise: Object,  // Used for testing.
      },

      _computeStarClass: function(starred) {
        var classes = ['starButton'];
        if (starred) {
          classes.push('starButton-active');
        }
        return classes.join(' ');
      },

      _handleStarTap: function() {
        var method = this.change.starred ? 'DELETE' : 'PUT';
        this.set('change.starred', !this.change.starred);
        this._send(method, this._restEndpoint()).catch(function(err) {
          this.set('change.starred', !this.change.starred);
          alert('Change couldn’t be starred. Check the console and contact ' +
              'the PolyGerrit team for assistance.');
          throw err;
        }.bind(this));
      },

      _send: function(method, url) {
        var xhr = document.createElement('gr-request');
        this._xhrPromise = xhr.send({
          method: method,
          url: url,
        });
        return this._xhrPromise;
      },

      _restEndpoint: function() {
        return '/accounts/self/starred.changes/' + this.change._number;
      },

    });
  })();
  </script>
</dom-module>
