// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.

// Overlay is a mixin for ensuring components layerd on top align with their initiating controls underneath.
var Overlay = {

  _overlayControlElement: null,
  _overlayLayerElement: null,

  _findScrollParent: function (element) {
    var parent = element.parentNode;
    while (parent) {
      // account for border the lazy way for now
      if (parent.scrollHeight > (parent.offsetHeight + 10)) {
        break;
      }
      parent = parent.parentNode;
    }
    return parent;
  },

  startOverlay: function (controlElement, layerElement) {
    this._overlayControlElement = controlElement;
    this._overlayLayerElement = layerElement;

    var scrollParent = this._findScrollParent(this._overlayControlElement);
    if (scrollParent) {
      scrollParent.addEventListener('scroll', this.positionOverlay);
    }
    window.addEventListener('resize', this.positionOverlay);

    this.positionOverlay();
  },

  stopOverlay: function () {
    if (this._overlayControlElement) {
      var scrollParent = this._findScrollParent(this._overlayControlElement);
      if (scrollParent) {
        scrollParent.removeEventListener('scroll', this.positionOverlay);
      }
      window.removeEventListener('resize', this.positionOverlay);
      this._overlayControlElement = null;
      this._overlayLayerElement = null;
    }
  },

  positionOverlay: function () {
    var controlElement = this._overlayControlElement;
    var layerElement = this._overlayLayerElement;

    var controlRect = controlElement.getBoundingClientRect();
    var windowWidth = window.innerWidth;

    // clear prior styling
    layerElement.style.left = '';
    layerElement.style.width = '';
    layerElement.style.top = '';

    var width = Math.min(
      Math.max(controlElement.offsetWidth, layerElement.offsetWidth),
        windowWidth);
    // align right edge and make at least as wide as the control
    // TODO: handle being on the right edge of the window with an icon control, go left
    var left = (controlRect.left + layerElement.offsetWidth) - width;
    if ((left + width) > windowWidth) {
      left -= ((left + width) - windowWidth);
    }
    if ('left' === this.props.direction) {
      // align right edge
      left = (controlRect.left + controlElement.offsetWidth) -
        layerElement.offsetWidth;
    }
    var top = controlRect.top;
    if ('up' === this.props.direction) {
      // align bottom edge
      top = (controlRect.top + controlElement.offsetHeight) -
        layerElement.offsetHeight;
    }

    layerElement.style.left = '' + left + 'px';
    layerElement.style.width = '' + width + 'px';
    layerElement.style.top = '' + top + 'px';
  },

  componentWillUnmount: function () {
    this.stopOverlay();
  }
};

module.exports = Overlay;

@@ -245,16 +245,45 @@
 t: null,
+%0A  _overlayScrollParents: %5B%5D,
 %0A%0A  _fin
@@ -295,16 +295,17 @@
 llParent
+s
 : functi
@@ -315,24 +315,45 @@
 (element) %7B%0A
+    var result = %5B%5D;%0A
     var pare
@@ -521,13 +521,27 @@
     
-b
 re
-ak
+sult.push(parent)
 ;%0A  
@@ -597,21 +597,21 @@
  return 
-paren
+resul
 t;%0A  %7D,%0A
@@ -769,18 +769,26 @@
 nt;%0A
-%0A
     
-var s
+this._overlayS
 crol
@@ -786,32 +786,33 @@
 rlayScrollParent
+s
  = this._findScr
@@ -812,32 +812,33 @@
 findScrollParent
+s
 (this._overlayCo
@@ -852,35 +852,70 @@
 ement);%0A    
-if (scrollP
+this._overlayScrollParents.forEach(function (p
 arent) %7B%0A   
@@ -913,31 +913,25 @@
 nt) %7B%0A      
-scrollP
+p
 arent.addEve
@@ -975,24 +975,32 @@
 rlay);%0A    %7D
+, this);
 %0A    window.
@@ -1162,97 +1162,54 @@
     
-var scrollParent = this._findScrollParent(this._overlayControlElement);%0A      if (scrollP
+this._overlayScrollParents.forEach(function (p
 aren
@@ -1225,15 +1225,9 @@
     
-scrollP
+p
 aren
@@ -1284,24 +1284,32 @@
 ay);%0A      %7D
+, this);
 %0A      windo
@@ -1441,24 +1441,63 @@
 ent = null;%0A
+      this._overlayScrollParents = %5B%5D;%0A
     %7D%0A  %7D,%0A%0A

fix Overlay not tracking scrolling