/*
 * 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.animation.client.Animation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;

import java.util.ArrayList;
import java.util.List;

/**
 * Helper class for laying out a container element and its children.
 * 
 * <p>
 * This class is typically used by higher-level widgets to implement layout on
 * their behalf. It is intended to wrap an element (usually a &lt;div&gt;), and
 * lay its children out in a predictable fashion, automatically accounting for
 * changes to the parent's size, and for all elements' margins, borders, and
 * padding.
 * </p>
 * 
 * <p>
 * To use this class, create a container element (again, usually a &lt;div&gt;)
 * and pass it to {@link #Layout(Element)}. Rather than attaching child elements
 * directly to the element managed by this {@link Layout}, use the
 * {@link Layout#attachChild(Element)} method. This will attach the child
 * element and return a {@link Layout.Layer} object which is used to manage the
 * child.
 * </p>
 * 
 * <p>
 * A separate {@link Layout.Layer} instance is associated with each child
 * element. There is a set of methods available on this class to manipulate the
 * child element's position and size. In order for changes to a layer to take
 * effect, you must finally call one of {@link #layout()} or
 * {@link #layout(int)}. This allows many changes to different layers to be
 * applied efficiently, and to be animated.
 * </p>
 * 
 * <p>
 * On most browsers, this is implemented using absolute positioning. It also
 * contains extra logic to make IE6 work properly.
 * </p>
 * 
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.LayoutExample}
 * </p>
 * 
 * <p>
 * NOTE: This class will <em>only</em> work in standards mode, which requires
 * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
 * declaration.
 * </p>
 * 
 * <p>
 * NOTE: This class is still very new, and its interface may change without
 * warning. Use at your own risk.
 * </p>
 */
public class Layout {

  /**
   * Callback interface used by {@link Layout#layout(int, AnimationCallback)}
   * to provide updates on animation progress.
   */
  public interface AnimationCallback {

    /**
     * Called immediately after the animation is complete, and the entire layout
     * is in its final state.
     */
    void onAnimationComplete();

    /**
     * Called at each step of the animation, for each layer being laid out.
     * 
     * @param layer the layer being laid out
     */
    void onLayout(Layer layer, double progress);
  }

  /**
   * This class is used to set the position and size of child elements.
   * 
   * <p>
   * Each child element has three values associated with each axis: {left,
   * right, width} on the horizontal axis, and {top, bottom, height} on the
   * vertical axis. Precisely two of three values may be set at a time, or the
   * system will be over- or under-contrained. For this reason, the following
   * methods are provided for setting these values:
   * <ul>
   * <li>{@link #setLeftRight(double, Unit, double, Unit)}</li>
   * <li>{@link #setLeftWidth(double, Unit, double, Unit)}</li>
   * <li>{@link #setRightWidth(double, Unit, double, Unit)}</li>
   * <li>{@link #setTopBottom(double, Unit, double, Unit)}</li>
   * <li>{@link #setTopHeight(double, Unit, double, Unit)}</li>
   * <li>{@link #setBottomHeight(double, Unit, double, Unit)}</li>
   * </ul>
   * </p>
   * 
   * <p>
   * By default, each layer is set to fill the entire parent (i.e., {left, top,
   * right, bottom} = {0, 0, 0, 0}).
   * </p>
   */
  public class Layer {
    final Element container, child;

    Object userObject;

    boolean setLeft, setRight, setTop, setBottom, setWidth, setHeight;
    boolean setTargetLeft = true, setTargetRight = true, setTargetTop = true,
        setTargetBottom = true, setTargetWidth, setTargetHeight;
    Unit leftUnit, topUnit, rightUnit, bottomUnit, widthUnit, heightUnit;
    Unit targetLeftUnit = PX, targetTopUnit = PX, targetRightUnit = PX,
        targetBottomUnit = PX, targetWidthUnit, targetHeightUnit;
    double left, top, right, bottom, width, height;
    double sourceLeft, sourceTop, sourceRight, sourceBottom, sourceWidth,
        sourceHeight;
    double targetLeft, targetTop, targetRight, targetBottom, targetWidth,
        targetHeight;

    Layer(Element container, Element child, Object userObject) {
      this.container = container;
      this.child = child;
      this.userObject = userObject;
    }

    /**
     * Gets the container element associated with this layer.
     * 
     * <p>
     * This is the element that sits between the parent and child elements. It
     * is normally necessary to operate on this element only when you need to
     * modify certain CSS properties, such as visibility.
     * </p>
     * 
     * @return the container element
     */
    public Element getContainerElement() {
      return container;
    }

    /**
     * Gets the user-data associated with this layer.
     * 
     * @return the layer's user-data object
     */
    public Object getUserObject() {
      return this.userObject;
    }

    /**
     * Sets the layer's bottom and height values.
     * 
     * @param bottom
     * @param bottomUnit
     * @param height
     * @param heightUnit
     */
    public void setBottomHeight(double bottom, Unit bottomUnit, double height,
        Unit heightUnit) {
      this.setTargetBottom = this.setTargetHeight = true;
      this.setTargetTop = false;
      this.targetBottom = bottom;
      this.targetHeight = height;
      this.targetBottomUnit = bottomUnit;
      this.targetHeightUnit = heightUnit;
    }

    /**
     * Sets the layer's left and right values.
     * 
     * @param left
     * @param leftUnit
     * @param right
     * @param rightUnit
     */
    public void setLeftRight(double left, Unit leftUnit, double right,
        Unit rightUnit) {
      this.setTargetLeft = this.setTargetRight = true;
      this.setTargetWidth = false;
      this.targetLeft = left;
      this.targetRight = right;
      this.targetLeftUnit = leftUnit;
      this.targetRightUnit = rightUnit;
    }

    /**
     * Sets the layer's left and width values.
     * 
     * @param left
     * @param leftUnit
     * @param width
     * @param widthUnit
     */
    public void setLeftWidth(double left, Unit leftUnit, double width,
        Unit widthUnit) {
      this.setTargetLeft = this.setTargetWidth = true;
      this.setTargetRight = false;
      this.targetLeft = left;
      this.targetWidth = width;
      this.targetLeftUnit = leftUnit;
      this.targetWidthUnit = widthUnit;
    }

    /**
     * Sets the layer's right and width values.
     * 
     * @param right
     * @param rightUnit
     * @param width
     * @param widthUnit
     */
    public void setRightWidth(double right, Unit rightUnit, double width,
        Unit widthUnit) {
      this.setTargetRight = this.setTargetWidth = true;
      this.setTargetLeft = false;
      this.targetRight = right;
      this.targetWidth = width;
      this.targetRightUnit = rightUnit;
      this.targetWidthUnit = widthUnit;
    }

    /**
     * Sets the layer's top and bottom values.
     * 
     * @param top
     * @param topUnit
     * @param bottom
     * @param bottomUnit
     */
    public void setTopBottom(double top, Unit topUnit, double bottom,
        Unit bottomUnit) {
      this.setTargetTop = this.setTargetBottom = true;
      this.setTargetHeight = false;
      this.targetTop = top;
      this.targetBottom = bottom;
      this.targetTopUnit = topUnit;
      this.targetBottomUnit = bottomUnit;
    }

    /**
     * Sets the layer's top and height values.
     * 
     * @param top
     * @param topUnit
     * @param height
     * @param heightUnit
     */
    public void setTopHeight(double top, Unit topUnit, double height,
        Unit heightUnit) {
      this.setTargetTop = this.setTargetHeight = true;
      this.setTargetBottom = false;
      this.targetTop = top;
      this.targetHeight = height;
      this.targetTopUnit = topUnit;
      this.targetHeightUnit = heightUnit;
    }
  }

  private static LayoutImpl impl = GWT.create(LayoutImpl.class);

  private List<Layer> layers = new ArrayList<Layer>();
  private final Element parentElem;
  private Animation animation;

  /**
   * Constructs a new layout associated with the given parent element.
   * 
   * @param parent the element to serve as the layout parent
   */
  public Layout(Element parent) {
    this.parentElem = parent;
    impl.initParent(parent);
  }

  /**
   * Asserts that the given child element is managed by this layout.
   * 
   * @param elem the element to be tested
   */
  public void assertIsChild(Element elem) {
    assert elem.getParentElement().getParentElement() == this.parentElem : "Element is not a child of this layout";
  }

  /**
   * Attaches a child element to this layout.
   * 
   * <p>
   * This method will attach the child to the layout, removing it from its
   * current parent element. Use the {@link Layer} it returns to manipulate the
   * child.
   * </p>
   * 
   * @param child the child to be attached
   * @return the {@link Layer} associated with the element
   */
  public Layer attachChild(Element child) {
    return attachChild(child, null);
  }

  /**
   * Attaches a child element to this layout.
   * 
   * <p>
   * This method will attach the child to the layout, removing it from its
   * current parent element. Use the {@link Layer} it returns to manipulate the
   * child.
   * </p>
   * 
   * @param child the child to be attached
   * @param userObject an arbitrary object to be associated with this layer
   * @return the {@link Layer} associated with the element
   */
  public Layer attachChild(Element child, Object userObject) {
    Element container = impl.attachChild(parentElem, child);
    Layer layer = new Layer(container, child, userObject);
    layers.add(layer);
    return layer;
  }

  /**
   * Causes the parent element to fill its own parent.
   * 
   * <p>
   * This is most useful for top-level layouts that need to follow the size of
   * another element, such as the &lt;body&gt;.
   * </p>
   */
  public void fillParent() {
    impl.fillParent(parentElem);
  }

  /**
   * Returns the size of one unit, in pixels, in the context of this layout.
   * 
   * <p>
   * This will work for any unit type, but be aware that certain unit types,
   * such as {@link Unit#EM}, and {@link Unit#EX}, will return different values
   * based upon the parent's associated font size. {@link Unit#PCT} is dependent
   * upon the parent's actual size, and the axis to be measured.
   * </p>
   * 
   * @param unit the unit type to be measured
   * @param vertical whether the unit to be measured is on the vertical or
   *          horizontal axis (this matters only for {@link Unit#PCT})
   * @return the unit size, in pixels
   */
  public double getUnitSize(Unit unit, boolean vertical) {
    return impl.getUnitSizeInPixels(parentElem, unit, vertical);
  }

  /**
   * Updates this layout's children immediately. This method <em>must</em> be
   * called after updating any of its children's {@link Layer layers}.
   */
  public void layout() {
    for (Layer l : layers) {
      l.left = l.sourceLeft = l.targetLeft;
      l.top = l.sourceTop = l.targetTop;
      l.right = l.sourceRight = l.targetRight;
      l.bottom = l.sourceBottom = l.targetBottom;
      l.width = l.sourceWidth = l.targetWidth;
      l.height = l.sourceHeight = l.targetHeight;

      l.setLeft = l.setTargetLeft;
      l.setTop = l.setTargetTop;
      l.setRight = l.setTargetRight;
      l.setBottom = l.setTargetBottom;
      l.setWidth = l.setTargetWidth;
      l.setHeight = l.setTargetHeight;

      l.leftUnit = l.targetLeftUnit;
      l.topUnit = l.targetTopUnit;
      l.rightUnit = l.targetRightUnit;
      l.bottomUnit = l.targetBottomUnit;
      l.widthUnit = l.targetWidthUnit;
      l.heightUnit = l.targetHeightUnit;

      impl.layout(l);
    }

    impl.finalizeLayout(parentElem);
  }

  /**
   * Updates the layout by animating it over time.
   * 
   * @param duration the duration of the animation
   * @see #layout(int, AnimationCallback)
   */
  public void layout(int duration) {
    layout(duration, null);
  }

  /**
   * Updates the layout by animating it over time, with a callback on each frame
   * of the animation, and upon completion.
   * 
   * @param duration the duration of the animation
   * @param callback the animation callback
   */
  public void layout(int duration, final AnimationCallback callback) {
    // Deal with constraint changes (e.g. left-width => right-width, etc)
    int parentWidth = parentElem.getClientWidth();
    int parentHeight = parentElem.getClientHeight();
    for (Layer l : layers) {
      adjustHorizontalConstraints(parentWidth, l);
      adjustVerticalConstraints(parentHeight, l);
    }

    // Cancel the old animation, if there is one.
    if (animation != null) {
      animation.cancel();
    }

    animation = new Animation() {
      @Override
      protected void onCancel() {
        onComplete();
      }

      @Override
      protected void onComplete() {
        layout();
        if (callback != null) {
          callback.onAnimationComplete();
        }
        animation = null;
      }

      @Override
      protected void onUpdate(double progress) {
        for (Layer l : layers) {
          if (l.setTargetLeft) {
            l.left = l.sourceLeft + (l.targetLeft - l.sourceLeft) * progress;
          }
          if (l.setTargetRight) {
            l.right = l.sourceRight + (l.targetRight - l.sourceRight)
                * progress;
          }
          if (l.setTargetTop) {
            l.top = l.sourceTop + (l.targetTop - l.sourceTop) * progress;
          }
          if (l.setTargetBottom) {
            l.bottom = l.sourceBottom + (l.targetBottom - l.sourceBottom)
                * progress;
          }
          if (l.setTargetWidth) {
            l.width = l.sourceWidth + (l.targetWidth - l.sourceWidth)
                * progress;
          }
          if (l.setTargetHeight) {
            l.height = l.sourceHeight + (l.targetHeight - l.sourceHeight)
                * progress;
          }

          impl.layout(l);
          if (callback != null) {
            callback.onLayout(l, progress);
          }
        }
        impl.finalizeLayout(parentElem);
      }
    };

    animation.run(duration);
  }

  /**
   * This method must be called when the parent element becomes attached to the
   * document.
   * 
   * @see #onDetach()
   */
  public void onAttach() {
    impl.onAttach(parentElem);
  }

  /**
   * This method must be called when the parent element becomes detached from
   * the document.
   * 
   * @see #onAttach()
   */
  public void onDetach() {
    impl.onDetach(parentElem);
  }

  /**
   * Removes a child element from this layout.
   * 
   * @param layer the layer associated with the child to be removed
   */
  public void removeChild(Layer layer) {
    impl.removeChild(layer.container, layer.child);
    layers.remove(layer);
  }

  private void adjustHorizontalConstraints(int parentWidth, Layer l) {
    double leftPx = l.left * getUnitSize(l.leftUnit, false);
    double rightPx = l.right * getUnitSize(l.rightUnit, false);
    double widthPx = l.width * getUnitSize(l.widthUnit, false);

    if (l.setLeft && !l.setTargetLeft) {
      // -left
      l.setLeft = false;

      if (!l.setWidth) {
        // +width
        l.setTargetWidth = true;
        l.sourceWidth = (parentWidth - (leftPx + rightPx))
            / getUnitSize(l.targetWidthUnit, false);
      } else {
        // +right
        l.setTargetRight = true;
        l.sourceRight = (parentWidth - (leftPx + widthPx))
            / getUnitSize(l.targetRightUnit, false);
      }
    } else if (l.setWidth && !l.setTargetWidth) {
      // -width
      l.setWidth = false;

      if (!l.setLeft) {
        // +left
        l.setTargetLeft = true;
        l.sourceLeft = (parentWidth - (rightPx + widthPx))
            / getUnitSize(l.targetLeftUnit, false);
      } else {
        // +right
        l.setTargetRight = true;
        l.sourceRight = (parentWidth - (leftPx + widthPx))
            / getUnitSize(l.targetRightUnit, false);
      }
    } else if (l.setRight && !l.setTargetRight) {
      // -right
      l.setRight = false;

      if (!l.setWidth) {
        // +width
        l.setTargetWidth = true;
        l.sourceWidth = (parentWidth - (leftPx + rightPx))
            / getUnitSize(l.targetWidthUnit, false);
      } else {
        // +left
        l.setTargetLeft = true;
        l.sourceLeft = (parentWidth - (rightPx + widthPx))
            / getUnitSize(l.targetLeftUnit, false);
      }
    }

    l.setLeft = l.setTargetLeft;
    l.setRight = l.setTargetRight;
    l.setWidth = l.setTargetWidth;

    l.leftUnit = l.targetLeftUnit;
    l.rightUnit = l.targetRightUnit;
    l.widthUnit = l.targetWidthUnit;
  }

  private void adjustVerticalConstraints(int parentHeight, Layer l) {
    double topPx = l.top * getUnitSize(l.topUnit, true);
    double bottomPx = l.bottom * getUnitSize(l.bottomUnit, true);
    double heightPx = l.height * getUnitSize(l.heightUnit, true);

    if (l.setTop && !l.setTargetTop) {
      // -top
      l.setTop = false;

      if (!l.setHeight) {
        // +height
        l.setTargetHeight = true;
        l.sourceHeight = (parentHeight - (topPx + bottomPx))
            / getUnitSize(l.targetHeightUnit, true);
      } else {
        // +bottom
        l.setTargetBottom = true;
        l.sourceBottom = (parentHeight - (topPx + heightPx))
            / getUnitSize(l.targetBottomUnit, true);
      }
    } else if (l.setHeight && !l.setTargetHeight) {
      // -height
      l.setHeight = false;

      if (!l.setTop) {
        // +top
        l.setTargetTop = true;
        l.sourceTop = (parentHeight - (bottomPx + heightPx))
            / getUnitSize(l.targetTopUnit, true);
      } else {
        // +bottom
        l.setTargetBottom = true;
        l.sourceBottom = (parentHeight - (topPx + heightPx))
            / getUnitSize(l.targetBottomUnit, true);
      }
    } else if (l.setBottom && !l.setTargetBottom) {
      // -bottom
      l.setBottom = false;

      if (!l.setHeight) {
        // +height
        l.setTargetHeight = true;
        l.sourceHeight = (parentHeight - (topPx + bottomPx))
            / getUnitSize(l.targetHeightUnit, true);
      } else {
        // +top
        l.setTargetTop = true;
        l.sourceTop = (parentHeight - (bottomPx + heightPx))
            / getUnitSize(l.targetTopUnit, true);
      }
    }

    l.setTop = l.setTargetTop;
    l.setBottom = l.setTargetBottom;
    l.setHeight = l.setTargetHeight;

    l.topUnit = l.targetTopUnit;
    l.bottomUnit = l.targetBottomUnit;
    l.heightUnit = l.targetHeightUnit;
  }
}
