/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.layout.client;

import static com.google.gwt.dom.client.Style.Unit.PX;

import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.layout.client.Layout.Layer;
import com.google.gwt.user.client.Window;

/**
 * IE6-specific implementation, which uses the "onresize" event, along with a
 * series of measurement tools, to deal with several IE6 bugs. Specifically,
 * IE6 doesn't support simultaneous left-right and top-bottom values, and it
 * misplaces by one pixel elements whose right/bottom properties are set.
 * 
 * Because this implementation gets compiled in for both IE6 and 7, it
 * dynamically detects IE7 and punts to the super implementation.
 */
class LayoutImplIE6 extends LayoutImplIE8 {

  private static Element createStyleRuler(Element parent) {
    DivElement styleRuler = Document.get().createDivElement();
    DivElement styleInner = Document.get().createDivElement();

    styleRuler.getStyle().setPosition(Position.ABSOLUTE);
    styleRuler.getStyle().setLeft(-10000, PX);

    parent.appendChild(styleRuler);
    styleRuler.appendChild(styleInner);
    return styleRuler;
  }

  @SuppressWarnings("unused") // called from JSNI
  private static void hookWindowResize(final Element elem) {
    Window.addResizeHandler(new ResizeHandler() {
      public void onResize(ResizeEvent event) {
        resizeRelativeToParent(elem);
      }
    });
  }

  @SuppressWarnings("unused") // called from JSNI
  private static native void measureDecoration(Element elem) /*-{
    var ruler = elem.__styleRuler;
    var inner = ruler.children[0];
    var s = inner.style, cs = elem.currentStyle;

    s.borderLeftStyle = cs.borderLeftStyle;
    s.borderRightStyle = cs.borderRightStyle;
    s.borderTopStyle = cs.borderTopStyle;
    s.borderBottomStyle = cs.borderBottomStyle;

    s.borderLeftWidth = cs.borderLeftWidth;
    s.borderRightWidth = cs.borderRightWidth;
    s.borderTopWidth = cs.borderTopWidth;
    s.borderBottomWidth = cs.borderBottomWidth;

    // Oddly enough, allowing the word 'auto' to creep into the style
    // ruler's margin causes it to take up all of its parent's space.
    s.marginLeft = (cs.marginLeft == 'auto') ? '' : cs.marginLeft;
    s.marginRight = (cs.marginRight == 'auto') ? '' : cs.marginRight;
    s.marginTop = (cs.marginTop == 'auto') ? '' : cs.marginTop;
    s.marginBottom = (cs.marginBottom == 'auto') ? '' : cs.marginBottom;

    s.paddingLeft = cs.paddingLeft;
    s.paddingRight = cs.paddingRight;
    s.paddingTop = cs.paddingTop;
    s.paddingBottom = cs.paddingBottom;

    s.width = s.height = 32;
    elem.__decoWidth = ruler.offsetWidth - 32;
    elem.__decoHeight = ruler.offsetHeight - 32;
  }-*/;

  private static native void resizeRelativeToParent(Element elem) /*-{
    var parent = elem.__resizeParent;
    if (parent) {
      @com.google.gwt.layout.client.LayoutImplIE6::measureDecoration(Lcom/google/gwt/dom/client/Element;)(elem);
      elem.style.left = 0;
      elem.style.top = 0;
      elem.style.width = parent.clientWidth - elem.__decoWidth;
      elem.style.height = parent.clientHeight - elem.__decoHeight;
    }
  }-*/;

  private static native void setLayer(Element container, Layer layer) /*-{
    // Potential leak: This is cleaned up in detach().
    container.__layer = layer;
  }-*/;

  private static native void setPropertyElement(Element elem, String name,
      Element value) /*-{
    elem[name] = value;
  }-*/;

  @Override
  public Element attachChild(Element parent, Element child, Element before) {
    DivElement container = Document.get().createDivElement();
    container.appendChild(child);

    container.getStyle().setPosition(Position.ABSOLUTE);
    container.getStyle().setOverflow(Overflow.HIDDEN);
    child.getStyle().setPosition(Position.ABSOLUTE);

    // Hang the style ruler from the container element, but associate it with
    // the child element, so that measureDecoration(child) will work.
    setPropertyElement(child, "__styleRuler", createStyleRuler(container));

    Element beforeContainer = null;
    if (before != null) {
      beforeContainer = before.getParentElement();
      assert beforeContainer.getParentElement() == parent : "Element to insert before must be a sibling";
    }
    parent.insertBefore(container, beforeContainer);
    return container;
  }

  @Override
  public void fillParent(Element elem) {
    fillParentImpl(elem);
  }

  @Override
  public void finalizeLayout(Element parent) {
    resizeRelativeToParent(parent);
    resizeHandler(parent, true);
  }

  @Override
  public void initParent(Element parent) {
    super.initParent(parent);
    setPropertyElement(parent, "__styleRuler", createStyleRuler(parent));
  }

  @Override
  public void layout(Layer layer) {
    Element elem = layer.container;
    Style style = elem.getStyle();

    if (layer.visible) {
      style.clearDisplay();
    } else {
      style.setDisplay(Display.NONE);
    }

    setLayer(elem, layer);
  }

  @Override
  public void onAttach(Element parent) {
    // No need to re-connect layer refs. This will be taken care of
    // automatically in layout().
    initResizeHandler(parent);
    initUnitChangeHandler(parent, relativeRuler);
  }

  @Override
  public void onDetach(Element parent) {
    removeLayerRefs(parent);
    removeResizeHandler(parent);
    removeUnitChangeHandler(relativeRuler);
  }

  private native void fillParentImpl(Element elem) /*-{
    // Hook the parent element's onresize event. If the parent is the <body>,
    // then we have to go through the Window class to get the resize event,
    // because IE6 requires a bunch of foul hackery to safely hook it.
    var parent = elem.parentElement;
    if (parent.tagName.toLowerCase() == 'body') {
      elem.style.position = 'absolute';
      var docElem = parent.parentElement;
      elem.__resizeParent = docElem;
      @com.google.gwt.layout.client.LayoutImplIE6::hookWindowResize(Lcom/google/gwt/dom/client/Element;)(elem);
      return;
    }

    function resize() {
      @com.google.gwt.layout.client.LayoutImplIE6::resizeRelativeToParent(Lcom/google/gwt/dom/client/Element;)(elem);
    }

    elem.__resizeParent = parent;
    parent.onresize = resize;
    resize();
  }-*/;

  /**
   * This does not call $entry() because no user code is reachable from
   * resizeHandler.
   */
  private native void initResizeHandler(Element parent) /*-{
    // Potential leak: This is cleaned up in detach().
    var self = this;
    parent.onresize = function() {
      self.@com.google.gwt.layout.client.LayoutImplIE6::resizeHandler(Lcom/google/gwt/dom/client/Element;)(parent);
    };
  }-*/;

  /**
   * This does not call $entry() because no user code is reachable from
   * resizeHandler.
   */
  private native void initUnitChangeHandler(Element parent, Element ruler) /*-{
    // Potential leak: This is cleaned up in detach().
    var self = this;
    ruler.onresize = function() {
      self.@com.google.gwt.layout.client.LayoutImplIE6::resizeHandler(Lcom/google/gwt/dom/client/Element;Z)(parent, true);
    };
  }-*/;

  private native void removeLayerRefs(Element parent) /*-{
    for (var i = 0; i < parent.childNodes.length; ++i) {
      var container = parent.childNodes[i];
      if (container.__layer) {
        container.__layer = null;
      }
    }
  }-*/;

  private native void removeResizeHandler(Element parent) /*-{
    parent.onresize = null;
  }-*/;

  private native void removeUnitChangeHandler(Element ruler) /*-{
    ruler.onresize = null;
  }-*/;

  @SuppressWarnings("unused") // called from JSNI
  private void resizeHandler(Element parent) {
    resizeHandler(parent, false);
  }
  
  private native void resizeHandler(Element parent, boolean force) /*-{
    if (!force &&
        ((parent.offsetWidth == parent.__oldWidth) &&
         (parent.offsetHeight == parent.__oldHeight))) {
      return;
    }
    parent.__oldWidth = parent.offsetWidth;
    parent.__oldHeight = parent.offsetHeight;

    var parentWidth = parent.clientWidth;
    var parentHeight = parent.clientHeight;

    // Iterate over the children, assuming each of them is an unstyled
    // container element.
    for (var i = 0; i < parent.childNodes.length; ++i) {
      // Don't attempt to layout the rulers.
      var container = parent.childNodes[i];
      var layer = container.__layer;
      if (!layer) {
        continue;
      }

      // This is ugly, but it's less ugly than writing all these JSNI refs inline.
      var _setLeft = layer.@com.google.gwt.layout.client.Layout.Layer::setLeft;
      var _setTop = layer.@com.google.gwt.layout.client.Layout.Layer::setTop;
      var _setWidth = layer.@com.google.gwt.layout.client.Layout.Layer::setWidth;
      var _setHeight = layer.@com.google.gwt.layout.client.Layout.Layer::setHeight;
      var _setRight = layer.@com.google.gwt.layout.client.Layout.Layer::setRight;
      var _setBottom = layer.@com.google.gwt.layout.client.Layout.Layer::setBottom;

      var _left = layer.@com.google.gwt.layout.client.Layout.Layer::left;
      var _top = layer.@com.google.gwt.layout.client.Layout.Layer::top;
      var _width = layer.@com.google.gwt.layout.client.Layout.Layer::width;
      var _height = layer.@com.google.gwt.layout.client.Layout.Layer::height;
      var _right = layer.@com.google.gwt.layout.client.Layout.Layer::right;
      var _bottom = layer.@com.google.gwt.layout.client.Layout.Layer::bottom;

      var _leftUnit = layer.@com.google.gwt.layout.client.Layout.Layer::leftUnit;
      var _topUnit = layer.@com.google.gwt.layout.client.Layout.Layer::topUnit;
      var _widthUnit = layer.@com.google.gwt.layout.client.Layout.Layer::widthUnit;
      var _heightUnit = layer.@com.google.gwt.layout.client.Layout.Layer::heightUnit;
      var _rightUnit = layer.@com.google.gwt.layout.client.Layout.Layer::rightUnit;
      var _bottomUnit = layer.@com.google.gwt.layout.client.Layout.Layer::bottomUnit;

      var _hPos = layer.@com.google.gwt.layout.client.Layout.Layer::hPos
                  .@com.google.gwt.layout.client.Layout.Alignment::ordinal()();
      var _vPos = layer.@com.google.gwt.layout.client.Layout.Layer::vPos
                  .@com.google.gwt.layout.client.Layout.Alignment::ordinal()();

      // Apply the requested position & size values to the element's style.
      var style = container.style;
      style.left = _setLeft ? (_left + _leftUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
      style.top = _setTop ? (_top + _topUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
      style.width = _setWidth ? (_width + _widthUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
      style.height = _setHeight ? (_height + _heightUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";

      // If right is defined, reposition/size the container horizontally.
      if (_setRight) {
        var ratio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _rightUnit, false);
        var right = parentWidth - (_right * ratio);

        if (!_setLeft) {
          // There's no left defined; adjust the left position move the element to the right edge.
          container.style.left = (right - container.offsetWidth) + 'px';
        } else {
          // Both left and right are defined; calculate the width and set it.
          var leftRatio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _leftUnit, false);
          var left = (_left * leftRatio);
          if (right > left) {
            container.style.width = (right - left) + 'px';
          }
        }
      }

      // If bottom is defined, reposition/size the container vertically.
      if (_setBottom) {
        var ratio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _bottomUnit, true);
        var bottom = parentHeight - (_bottom * ratio);

        if (!_setTop) {
          // There's no top defined; adjust the left position move the element to the bottom edge.
          container.style.top = (bottom - container.offsetHeight) + 'px';
        } else {
          // Both top and bottom are defined; calculate the height and set it.
          var topRatio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _topUnit, true);
          var top = (_top * topRatio);
          if (bottom > top) {
            container.style.height = (bottom - top) + 'px';
          }
        }
      }

      // Resize and position the child based on the layer's [hv]Pos.
      var child = container.firstChild;
      @com.google.gwt.layout.client.LayoutImplIE6::measureDecoration(Lcom/google/gwt/dom/client/Element;)(child);
      var childDecoWidth = child.__decoWidth;
      var childDecoHeight = child.__decoHeight;

      if (container.offsetWidth > childDecoWidth) {
        switch (_hPos) {
          case 0: // BEGIN
            child.style.left = '0px';
            break;
          case 1: // END
            child.style.left = (container.offsetWidth - childDecoWidth - child.offsetWidth) + 'px';
            break;
          case 2: // STRETCH
            child.style.left = '0px';
            child.style.width = (container.offsetWidth - childDecoWidth) + 'px';
            break;
        }
      }
      if (container.offsetHeight > childDecoHeight) {
        switch (_vPos) {
          case 0: // BEGIN
            child.style.top = '0px';
            break;
          case 1: // END
            child.style.top = (container.offsetHeight - childDecoHeight - child.offsetHeight) + 'px';
            break;
          case 2: // STRETCH
            child.style.top = '0px';
            child.style.height = (container.offsetHeight - childDecoHeight) + 'px';
            break;
        }
      }
    }
  }-*/;
}
