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