<!DOCTYPE html>
<html>

  <head>
    <base href="http://polygit.org/polymer+:master/components/">
    <link href="polymer/polymer.html" rel="import">
    <link href="neon-animation/neon-animation-runner-behavior.html" rel="import">
    <link href="neon-animation/animations/fade-in-animation.html" rel="import">
    <link href="neon-animation/animations/fade-out-animation.html" rel="import">
  </head>

  <body>
    <x-test></x-test>
    <dom-module id="x-test">
      <template>
        <template is="dom-repeat" items="[[_debouncedItems]]" on-dom-change="_onRepeaterChange">
          <x-item item="[[item]]"></x-item>
        </template>
        <button type="button" on-tap="_onAdd">Add item</button>
        <button type="button" on-tap="_onRemove">Remove item</button>
      </template>
      <script>
        Polymer({
          is: 'x-test',
          properties: {
            items: {
              type: Array,
              value: [
                { text: 'foo' },
                { text: 'bar' }
              ]
            },
            delay: {
              type: Number,
              value: 500
            },
            _debouncedItems: {
              type: Array
            },
            _toEnter: {
              type: Array,
              value: function() {
                return [];
              }
            }
          },
          observers: [
            '_onItemsChanged(items.*)'
          ],
          _onRemove: function(e) {
            this.splice('items', this.items.length - 1, 1);
          },
          _onAdd: function() {
            this.push('items', {
              text: 'test'
            });
          },
          _onRepeaterChange: function(e) {
            this._toEnter.forEach(function(idx) {
              var el = this.$$(':nth-child(' + (idx + 1) + ')');
              
              if(el) {
                el.playAnimation('entry');
              }
            }.bind(this));
            
            this.splice('_toEnter', 0, this._toEnter.length);
          },
          _onItemsChanged: function(change) {
            if(!change) {
              return;
            }
            
            var newPath = change.path.replace(/^items/, '_debouncedItems');
            
            if(change.path !== 'items.splices') {
              this.notifyPath(newPath, change.value);
              return;
            }
            
            var splices = change.value.indexSplices;
            
            splices.forEach(function(splice) {
              var el,
                  i,
                  idx;

              for(i = 0; i < splice.removed.length; i++) {
                idx = splice.index + i;
                el = this.$$(':nth-child(' + (idx + 1) + ')');
                if(el) {
                  el.playAnimation('exit');
                }
              }
              
              for(i = 0; i < splice.addedCount; i++) {
                idx = splice.index + i;
                this.push('_toEnter', idx);
              }
            }.bind(this));
            
            this.async(function() {
              this.notifyPath(newPath, change.value);
            }.bind(this), this.delay);
          }
        });
      </script>
    </dom-module>
    <dom-module id="x-item">
      <template>
        <style>
          :host {
            display: block;
            background: hotpink;
            padding: 12px 6px;
            border: 2px solid red;
          }
        </style>
        <div>[[item.text]]</div>
      </template>
      <script>
        Polymer({
          is: 'x-item',
          behaviors: [
            Polymer.NeonAnimationRunnerBehavior
          ],
          properties: {
            item: {
              type: Object
            },
            animationConfig: {
              value: function() {
                return {
                  entry: {
                    name: 'fade-in-animation',
                    node: this
                  },
                  exit: {
                    name: 'fade-out-animation',
                    node: this,
                    timing: {
                      duration: 500
                    }
                  }
                };
              }
            }
          }
        });
      </script>
    </dom-module>
  </body>
</html>