'use babel';

let BREAKPOINT_CLASS = 'breakpoint';

export default {
  breakpoints: [],
  init(debuggerInstance, state) {
    this.debugger = debuggerInstance;
    this.breakpoints = state;
    this.gutters = [];

    atom.workspace.observeTextEditors((textEditor) => {
      let gutter = textEditor.addGutter({name: 'polybug'});
      let element = document.createElement('div');
      element.className = 'polybug-gutter';
      let path = textEditor.getPath();
      //TODO: do it in proper way
      let lineHeight = textEditor.getLineHeightInPixels() || Math.floor(atom.config.get('editor.fontSize') * atom.config.get('editor.lineHeight'));
      let applyBreakpoint = (breakpoint) => {
        let screenLine = textEditor.bufferPositionForScreenPosition([breakpoint.line, 0]).row;
        let breakpointElement = document.createElement('div');
        breakpointElement.className = BREAKPOINT_CLASS;
        breakpointElement.style.top = ((screenLine - 1) * lineHeight + (lineHeight - 10) / 2) + 'px';
        breakpointElement.style.left = ((element.clientWidth - 10) / 2) + 'px';
        breakpointElement.dataset.breakpoint = breakpoint.line;
        element.appendChild(breakpointElement);

        breakpointElement.polybugBreakpoint = breakpoint;
        this.addBreakpoint(breakpoint);
      };

      element.onclick = (event) => {
        if (event.target.classList.contains(BREAKPOINT_CLASS)) {
          let breakpoint = event.target.polybugBreakpoint;
          event.target.parentElement.removeChild(event.target);
          this.removeBreakpoint(breakpoint);
          this.breakpoints.splice(this.breakpoints.indexOf(breakpoint), 1);
        } else {
          let line = Math.floor(event.offsetY / lineHeight) + 1;
          let realLine = textEditor.screenPositionForBufferPosition([line, 0]).row;
          let breakpoint = {
            path: path,
            line: realLine
          };
          for (let b of this.breakpoints) {
            if (b.path === path && b.line == realLine) {
              this.breakpoints.splice(this.breakpoints.indexOf(b), 1);
              let bElement = element.querySelector('.breakpoint[data-breakpoint="' + realLine + '"]');
              if (bElement) {
                element.removeChild(bElement);
              }
              this.removeBreakpoint(b);
              return;
            }
          }
          applyBreakpoint(breakpoint);
          this.breakpoints.push(breakpoint);
        }
      };

      let shadowElement = document.createElement('div');
      shadowElement.className = 'breakpoint-shadow';
      shadowElement.style.display = 'none';
      element.appendChild(shadowElement);
      element.onmousemove = (event) => {
        let line = Math.floor(event.offsetY / lineHeight) + 1;
        let realLine = textEditor.screenPositionForBufferPosition([line, 0]).row;
        shadowElement.style.top = ((line - 1) * lineHeight + (lineHeight - 10) / 2) + 'px';
        shadowElement.style.left = ((element.clientWidth - 10) / 2) + 'px';
        shadowElement.style.display = 'block';
      };
      element.onmouseleave = (event) => {
        shadowElement.style.display = 'none';
      };

      // TODO: change it to something sane
      gutter.decorateMarker(textEditor.markBufferRange([[0, 0], [100000, 0]]), {
        type: 'gutter',
        class: 'polybug',
        item: element
      });
      this.gutters.push(gutter);


      let mutationObserver = new MutationObserver(() => {
        mutationObserver.disconnect();
        for (let breakpoint of state) {
          if (breakpoint.path == path) {
            applyBreakpoint(breakpoint);
          }
        }
      });

      mutationObserver.observe(element, {attributes: true, subtree: true});
      gutter.onDidDestroy(() => this.gutters.splice(this.gutters.indexOf(gutter, 1)));
    });
  },

  addBreakpoint(breakpoint) {
    this.debugger.addBreakpoint(breakpoint.path, breakpoint.line);
  },

  destroy() {
    let gutters = this.gutters.slice(0);
    for (let gutter of gutters) {
      gutter.destroy();
    }
  },

  getState() {
    return this.breakpoints;
  },

  removeBreakpoint(breakpoint) {
    this.debugger.removeBreakpoint(breakpoint.path, breakpoint.line);
  }
};

@@ -1343,336 +1343,8 @@
 %3E %7B%0A
-        if (event.target.classList.contains(BREAKPOINT_CLASS)) %7B%0A          let breakpoint = event.target.polybugBreakpoint;%0A          event.target.parentElement.removeChild(event.target);%0A          this.removeBreakpoint(breakpoint);%0A          this.breakpoints.splice(this.breakpoints.indexOf(breakpoint), 1);%0A        %7D else %7B%0A  
     
@@ -1406,26 +1406,24 @@
  1;%0A        
-  
 let realLine
@@ -1488,26 +1488,24 @@
 ow;%0A        
-  
 let breakpoi
@@ -1511,18 +1511,16 @@
 int = %7B%0A
-  
         
@@ -1543,18 +1543,16 @@
         
-  
 line: re
@@ -1562,31 +1562,27 @@
 ine%0A        
-  
 %7D;%0A
-  
         for 
@@ -1617,26 +1617,24 @@
 %7B%0A          
-  
 if (b.path =
@@ -1662,26 +1662,24 @@
 realLine) %7B%0A
-  
             
@@ -1735,18 +1735,16 @@
 b), 1);%0A
-  
         
@@ -1844,26 +1844,24 @@
             
-  
 if (bElement
@@ -1860,26 +1860,24 @@
 bElement) %7B%0A
-  
             
@@ -1913,38 +1913,34 @@
 t);%0A            
- 
- 
 %7D%0A
-  
             this
@@ -1973,18 +1973,16 @@
         
-  
 return;%0A
@@ -1983,38 +1983,34 @@
 turn;%0A          
- 
- 
 %7D%0A
-  
         %7D%0A      
@@ -1995,34 +1995,32 @@
     %7D%0A        %7D%0A
-  
         applyBre
@@ -2040,34 +2040,32 @@
 point);%0A        
- 
- 
 this.breakpoints
@@ -2083,26 +2083,16 @@
 point);%0A
-        %7D%0A
       %7D;

Remove old code