<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <link data-require="animate.css@1.0.0" data-semver="1.0.0" rel="stylesheet" href="//raw.github.com/daneden/animate.css/master/animate.min.css" />
    <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script src="http://code.angularjs.org/1.2.16/angular.js"></script>
    <script src="http://code.angularjs.org/1.2.16/angular-touch.js"></script>
    <script src="http://code.angularjs.org/1.2.16/angular-animate.js"></script>
    <script src="item-swipe.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div class="container">
      <p>Turn on "Emulate touch events" for best effect</p>
      <a target="_blank" href="https://github.com/FavishInc/swipe-to-remove">Fork me on github</a>
      <button ng-click="resetThings()">Reset things</button>
      <div class="animate-repeat" ng-repeat="thing in things">
        <div class="test" item-swipe="" on-remove="removeThing(thing)">
          {{thing.name}} swipe me right.
        </div>
      </div>
    </div>
  </body>

</html>
var app = angular.module('plunker', ['itemSwipe', 'ngAnimate']);

app.controller('MainCtrl', function ($scope, Things) {
    $scope.removeThing = function(thing){
      $scope.things.splice($scope.things.indexOf(thing), 1);
    };
    $scope.resetThings = function(){
      $scope.things = Things();
    };
    $scope.resetThings();
  });

app.value('Things', function () {
    return [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}];
  });
body {
  background: #D5D5D5;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #333;
}

.container {
  zoom: 1;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

.swiper {
  width: 100%;
  height: 70px;
  background: whitesmoke;
  margin: 4px 12px;
  zoom: 1;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position: relative;
  display: block;
  overflow: hidden;
  text-overflow: clip;
  white-space:nowrap;
}

.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}

.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:40px;
}

'use strict';

angular.module('itemSwipe', ['ngTouch'])
  .directive('itemSwipe', ['$swipe', '$document', '$window', '$timeout',
    function($swipe, $document, $window, $timeout) {
      return {
        transclude: true,
        template: '<div class="item-swipe-wrapper" style="position: relative">' +
                    '<div class="swiper" ng-style="swiperStyle" ng-transclude style="position: relative"></div>' +
                    '<div class="undo-div" ng-style="undoStyle" ng-click="proceed = false">Undo</div>' +
                  '</div>',
        link: {
          post: function postLink(scope, iElement, iAttrs, controller) {
            var startCoords, threeD, $swiper;
            $swiper = angular.element('.swiper', iElement);
            scope.proceed = false;
            scope.undoStyle = {
              opacity: 0,
              width: '100%',
              position: 'absolute',
              left: '70%',
              top: '0',
            };

            function fullSwipe(coords){
              return coords.x - startCoords.x > $swiper.width()*(1/3) ? true : false;
            }

            function cssPrefix(property, value){
              var vendors = ['', '-o-','-moz-','-ms-','-khtml-','-webkit-'];
              var styles = {};
              for (var i = vendors.length - 1; i >= 0; i--) {
                styles[vendors[i] + property] = value;
              }
              return styles;
            }

            function updateElementPosition(pos){
              if('threeD' in iAttrs){
                $swiper.css(cssPrefix('transform', 'translate(' + pos + 'px)'));
              }else{
                $swiper.css('left', pos);
              }
            }

            scope.$watch('proceed', function(val){
              if(val){
                scope.undoStyle.opacity = 1;
                scope.eliminateItem = $timeout(function() {
                  scope.proceed = false;
                  return scope.$eval(iAttrs.onRemove);
                }, 1220);
              }else{
                scope.undoStyle.opacity = 0;
                $timeout.cancel(scope.eliminateItem);
                updateElementPosition(0);
              }
            });

            $swipe.bind($swiper, {
              'start': function(coords) {
                startCoords = coords;
                scope.swiperStyle = {opacity: 0.5};
                scope.$apply();
              },
              'cancel': function() {
                scope.swiperStyle = cssPrefix('transition', 'all 0.2s ease-in-out');
                scope.swiperStyle.opacity = 1;
                scope.$apply();
              },
              'move': function(coords) {
                updateElementPosition(coords.x - startCoords.x);
              },
              'end': function(endCoords) {
                if (fullSwipe(endCoords)) {
                  scope.proceed = true;
                  updateElementPosition($document.width());
                }else {
                  scope.proceed = false;
                  updateElementPosition(0);
                }
                scope.swiperStyle = cssPrefix('transition', 'all 0.2s ease-in-out');
                scope.swiperStyle.opacity = 1;
                scope.$apply();
              }
            });
          }
        }
      };
    }]);