/*
 * 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 {

  /**
   * Used to specify the alignment of child elements within a layer.
   */
  public enum Alignment {

    /**
     * Positions an element at the beginning of a given axis.
     */
    BEGIN,

    /**
     * Positions an element at the beginning of a given axis.
     */
    END,

    /**
     * Stretches an element to fill the layer on a given axis.
     */
    STRETCH;
  }

  /**
   * 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;

    Alignment hPos = Alignment.STRETCH, vPos = Alignment.STRETCH;
    boolean visible = true;

    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 CSS properties that are not directly modeled by the Layer class.
     * </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 child element's horizontal position within the layer.
     * 
     * @param position
     */
    public void setChildHorizontalPosition(Alignment position) {
      this.hPos = position;
    }

    /**
     * Sets the child element's vertical position within the layer.
     * 
     * @param position
     */
    public void setChildVerticalPosition(Alignment position) {
      this.vPos = position;
    }

    /**
     * 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;
    }

    /**
     * Sets the layer's visibility.
     * 
     * @param visible
     */
    public void setVisible(boolean visible) {
      this.visible = visible;
    }
  }

  private 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 before the child element before which to insert
   * @return the {@link Layer} associated with the element
   */
  public Layer attachChild(Element child, Element before) {
    return attachChild(child, before, 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) {
    return attachChild(child, null, userObject);
  }

  /**
   * 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 before the child element before which to insert
   * @param userObject an arbitrary object to be associated with this layer
   * @return the {@link Layer} associated with the element
   */
  public Layer attachChild(Element child, Element before, Object userObject) {
    Element container = impl.attachChild(parentElem, child, before);
    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() {
    layout(0);
  }

  /**
   * 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) {
    // If there's no actual animation going on, don't do any of the expensive
    // constraint calculations or anything like that.
    if (duration == 0) {
      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);
      if (callback != null) {
        callback.onAnimationComplete();
      }
      return;
    }

    // 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;
  }
}
