/**
 * @jsx React.DOM
 */

function Vector(x, y) {
  this.x = x;
  this.y = y;
}

// TODO: we could pool these in the future maybe
function vector(x, y) {
  return new Vector(x, y);
}

function SwipingEvent(offset, time) {
  this.offset = offset;
  this.time = time;
}

function swipingEvent(offset, time) {
  return new SwipingEvent(offset, time);
}

function SwipedEvent(velocity) {
  this.velocity = velocity;
}

function swipedEvent(velocity) {
  return new SwipedEvent(velocity);
}

// TODO: should we do it with distance instead?
var MIN_SWIPE_TIME = 250;

var SwipeTarget = React.createClass({
  getInitialState: function() {
    return {
      lastTouchPos: null,
      lastTouchVelocity: null,
      lastTouchTime: null,
      touchStartTime: null,
    };
  },

  handleTouchStart: function(e) {
    var touch = e.targetTouches[0];
    var time = Date.now();

    if (this.props.onStartGesturing) {
      this.props.onStartGesturing();
    }

    this.setState({
      lastTouchPos: vector(touch.screenX, touch.screenY),
      lastTouchVelocity: vector(0, 0),
      lastTouchTime: time,
      touchStartTime: time
    });
    return false;
  },

  handleTouchMove: function(e) {
    var touch = e.targetTouches[0];
    var time = Date.now();
    var timeDelta = time - this.state.lastTouchTime;
    var offsetX = touch.screenX - this.state.lastTouchPos.x;
    var offsetY = touch.screenY - this.state.lastTouchPos.y;

    if (this.props.onSwiping) {
      this.props.onSwiping(swipingEvent(vector(offsetX, offsetY), timeDelta));
    }

    // reuse the last obj for less GCs, even though
    // mutating state is bad form in React.
    var lastTouchVelocity = this.state.lastTouchVelocity;
    lastTouchVelocity.x = offsetX / timeDelta;
    lastTouchVelocity.y = offsetY /  timeDelta;

    var lastTouchPos = this.state.lastTouchPos;
    lastTouchPos.x = touch.screenX;
    lastTouchPos.y = touch.screenY;

    this.setState({
      lastTouchPos: lastTouchPos,
      lastTouchVelocity: lastTouchVelocity,
      lastTouchTime: time
    });

    return false;
  },

  handleTouchEnd: function(e) {
    var swiping = Date.now() - this.state.touchStartTime > MIN_SWIPE_TIME;

    if (this.props.onStopGesturing) {
      this.props.onStopGesturing(swiping);
    }

    // TODO: these velocity calcs could be better? Is there an issue if
    // you hold for a long time?
    if (this.props.onSwiped && swiping) {
      this.props.onSwiped(swipedEvent(this.state.lastTouchVelocity));
    }
    return false;
  },

  render: function() {
    return this.transferPropsTo(
      <div
          onTouchStart={this.handleTouchStart}
          onTouchEnd={this.handleTouchEnd}
          onTouchMove={this.handleTouchMove}>
        {this.props.children}
      </div>
    );
  }
});

React.initializeTouchEvents(true);

window.SwipeTarget = SwipeTarget;
@@ -485,55 +485,176 @@
 %0A%7D%0A%0A
-// TODO: should we do it with distance instead?
+function isDistanceGreaterThan(v1, v2, d) %7B%0A  // http://jsperf.com/pow-vs-mul%0A  var xd = (v2.x - v1.x);%0A  var yd = (v2.y - v1.y);%0A  return xd * xd + yd * yd %3E d * d;%0A%7D%0A
 %0Avar
@@ -668,18 +668,20 @@
 IPE_
-TIM
+DISTANC
 E = 2
-50
 ;%0A%0Av
@@ -862,27 +862,25 @@
 uchStart
-Time
+Pos
 : null
-,
 %0A    %7D;%0A
@@ -958,35 +958,8 @@
 %5B0%5D;
-%0A    var time = Date.now();
 %0A%0A  
@@ -1177,20 +1177,26 @@
 chTime: 
-time
+Date.now()
 ,%0A      
@@ -1205,26 +1205,57 @@
 uchStart
-Time: time
+Pos: vector(touch.screenX, touch.screenY)
 %0A    %7D);
@@ -2251,20 +2251,67 @@
 g = 
-Date.now() -
+isDistanceGreaterThan(%0A      this.state.lastTouchPos,%0A     
  thi
@@ -2332,14 +2332,18 @@
 tart
-Time %3E
+Pos,%0A     
  MIN
@@ -2353,12 +2353,22 @@
 IPE_
-TIME
+DISTANCE%0A    )
 ;%0A%0A 

use distance to determine swiping