import {Observable as O} from 'rx';

import {preventDefault} from '../../lib/utils';

const svgEventPosition = (evt) => {
  const svg = evt.target.ownerSVGElement || evt.target;
  const pt = svg.createSVGPoint();
  pt.x = evt.clientX;
  pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
};

export default (DOM) => {
  const mouseUp$ = O
    .fromEvent(document, 'mouseup')
    .do(preventDefault);
  const mouseMove$ = O
    .fromEvent(document, 'mousemove')
    .do(preventDefault);
  const mousedown$ = DOM
    .select('.graphics-root')
    .events('mousedown')
    .do(preventDefault)
    .map(svgEventPosition);

  const drag$ = mousedown$
    .flatMap((start) =>
      mouseMove$
      .map(svgEventPosition)
      .distinctUntilChanged()
      .map((target) => ({
        x: target.x - start.x,
        y: target.y - start.y,
      })
      ).takeUntil(mouseUp$)
    );

  return {
    zoom$:
      DOM
        .select('.graphics-root')
        .events('wheel')
        .do(preventDefault)
        .map((evt) => {
          const pivot = svgEventPosition(evt);
          const wheel = evt.deltaY / -40;
          const factor = Math.pow(1 + Math.abs(wheel) / 2 , wheel > 0 ? 1 : -1);

          return {
            factor,
            pivot,
          };
        }),
    pan$: drag$,
  };
};

@@ -104,24 +104,30 @@
 ition = (evt
+, svg_
 ) =%3E %7B%0A  con
@@ -134,16 +134,24 @@
 st svg =
+ svg_ %7C%7C
  evt.tar
@@ -634,32 +634,123 @@
    .map(
-svgEventPosition
+(evt) =%3E (%7B%0A      start: svgEventPosition(evt),%0A      svg: evt.target.ownerSVGElement %7C%7C evt.target,%0A    %7D)
 );%0A%0A  co
@@ -786,21 +786,28 @@
 latMap((
+%7B
 start
+, svg%7D
 ) =%3E%0A   
@@ -831,16 +831,25 @@
    .map(
+(evt) =%3E 
 svgEvent
@@ -856,16 +856,26 @@
 Position
+(evt, svg)
 )%0A      

fix panning outside svg element