import {selection} from "d3-selection";
// TODO import {timer} from "d3-timer";
import transition_ease from "./ease";

var root = [null],
    maxId = 0;

export function Transition(nodes, parents, name, id) {
  var key = name ? "__transition_" + name + "__" : "__transition__";
  this._nodes = nodes;
  this._parents = parents;
  this._name = name;
  this._id = id || (id = ++maxId);
  this.each(function() {
    var lock = this[key] || (this[key] = new Lock);
    if (lock.scheduled(id)) return;
    // TODO start a timer
  });
}

function transition() {
  return new Transition([[document.documentElement]], root);
}

function subtransition(method) {
  return function() {
    var selection = method.apply(this, arguments);
    return new Transition(selection._nodes, selection._parents, this._name, this._id);
  };
}

export var _selection = selection.prototype;

Transition.prototype = transition.prototype = {
  select: subtransition(_selection.select),
  selectAll: subtransition(_selection.selectAll),
  filter: subtransition(_selection.filter),
  call: _selection.call,
  nodes: _selection.nodes,
  node: _selection.node,
  size: _selection.size,
  empty: _selection.empty,
  each: _selection.each,
  // TODO each("event"), or on("event")?
  // TODO attr
  // TODO attrTween
  // TODO style
  // TODO styleTween
  // TODO text
  // TODO tween
  // TODO remove
  // TODO delay
  // TODO duration
  ease: transition_ease
};

function Lock() {
  this.active = null;
  this.pending = [];
}

Lock.prototype = {
  scheduled: function(id) {
    if (this.active && this.active.id === id) return true;
    var pending = this.pending, i = pending.length;
    while (--i >= 0) if (pending[i].id === id) return true;
    return false;
  }
};

export default transition;

@@ -818,20 +818,12 @@
 %0A%7D%0A%0A
-export 
 var 
-_
 sele
@@ -827,16 +827,26 @@
 election
+_prototype
  = selec
@@ -926,33 +926,32 @@
 : subtransition(
-_
 selection.select
@@ -939,24 +939,34 @@
 on(selection
+_prototype
 .select),%0A  
@@ -982,33 +982,32 @@
 : subtransition(
-_
 selection.select
@@ -999,16 +999,26 @@
 election
+_prototype
 .selectA
@@ -1046,17 +1046,16 @@
 nsition(
-_
 selectio
@@ -1055,16 +1055,26 @@
 election
+_prototype
 .filter)
@@ -1083,17 +1083,16 @@
   call: 
-_
 selectio
@@ -1092,16 +1092,26 @@
 election
+_prototype
 .call,%0A 
@@ -1118,17 +1118,16 @@
  nodes: 
-_
 selectio
@@ -1123,24 +1123,34 @@
 s: selection
+_prototype
 .nodes,%0A  no
@@ -1153,17 +1153,16 @@
   node: 
-_
 selectio
@@ -1162,16 +1162,26 @@
 election
+_prototype
 .node,%0A 
@@ -1187,17 +1187,16 @@
   size: 
-_
 selectio
@@ -1196,16 +1196,26 @@
 election
+_prototype
 .size,%0A 
@@ -1222,17 +1222,16 @@
  empty: 
-_
 selectio
@@ -1231,16 +1231,26 @@
 election
+_prototype
 .empty,%0A
@@ -1257,17 +1257,16 @@
   each: 
-_
 selectio
@@ -1266,16 +1266,26 @@
 election
+_prototype
 .each,%0A 

Rename for clarity.