/*******************************************************************************
 * Copyright (c) 2002, 2012 Innoopract Informationssysteme GmbH and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Innoopract Informationssysteme GmbH - initial API and implementation
 *    EclipseSource - ongoing development
 ******************************************************************************/
package org.eclipse.swt.widgets;

import org.eclipse.rwt.lifecycle.ProcessActionRunner;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.SerializableCompatibility;
import org.eclipse.swt.internal.widgets.ControlHolder;
import org.eclipse.swt.internal.widgets.ICompositeAdapter;
import org.eclipse.swt.internal.widgets.IControlHolderAdapter;


/**
 * Instances of this class are controls which are capable
 * of containing other controls.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>NO_FOCUS, NO_RADIO_GROUP</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * This class may be subclassed by custom control implementors
 * who are building controls that are constructed from aggregates
 * of other controls.
 * </p>
 */
public class Composite extends Scrollable {

  private final ICompositeAdapter compositeAdapter;
  private Layout layout;
  int layoutCount;
  private final ControlHolder controlHolder;
  private Control[] tabList;
  int backgroundMode;

  Composite( Composite parent ) {
    // prevent instantiation from outside this package
    super( parent );
    controlHolder = new ControlHolder();
    compositeAdapter = new CompositeAdapter();
  }

  /**
   * Constructs a new instance of this class given its parent
   * and a style value describing its behavior and appearance.
   * <p>
   * The style value is either one of the style constants defined in
   * class <code>SWT</code> which is applicable to instances of this
   * class, or must be built by <em>bitwise OR</em>'ing together
   * (that is, using the <code>int</code> "|" operator) two or more
   * of those <code>SWT</code> style constants. The class description
   * lists the style constants that are applicable to the class.
   * Style bits are also inherited from superclasses.
   * </p>
   *
   * @param parent a widget which will be the parent of the new instance (cannot be null)
   * @param style the style of widget to construct
   *
   * @exception IllegalArgumentException <ul>
   *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
   * </ul>
   * @exception SWTException <ul>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
   * </ul>
   *
   * @see SWT#NO_FOCUS
   * @see SWT#NO_RADIO_GROUP
   * @see Widget#getStyle
   */
  public Composite( Composite parent, int style ) {
    super( parent, style );
    controlHolder = new ControlHolder();
    compositeAdapter = new CompositeAdapter();
  }

  @Override
  void initState() {
    if( ( style & ( SWT.H_SCROLL | SWT.V_SCROLL ) ) == 0 ) {
      state |= THEME_BACKGROUND;
    }
  }

  /**
   * Returns a (possibly empty) array containing the receiver's children.
   * Children are returned in the order that they are drawn.  The topmost
   * control appears at the beginning of the array.  Subsequent controls
   * draw beneath this control and appear later in the array.
   * <p>
   * Note: This is not the actual structure used by the receiver
   * to maintain its list of children, so modifying the array will
   * not affect the receiver.
   * </p>
   *
   * @return an array of children
   *
   * @see Control#moveAbove
   * @see Control#moveBelow
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public Control[] getChildren() {
    checkWidget();
    return controlHolder.getControls();
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> T getAdapter( Class<T> adapter ) {
    T result;
    if( adapter == IControlHolderAdapter.class ) {
      result = ( T )controlHolder;
    } else if( adapter == ICompositeAdapter.class ) {
      result = ( T )compositeAdapter;
    } else {
      result = super.getAdapter( adapter );
    }
    return result;
  }

  //////////////////
  // Layout methods

  /**
   * Sets the layout which is associated with the receiver to be
   * the argument which may be null.
   *
   * @param layout the receiver's new layout or null
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void setLayout( Layout layout ) {
    checkWidget();
    this.layout = layout;
  }

  /**
   * Returns layout which is associated with the receiver, or
   * null if one has not been set.
   *
   * @return the receiver's layout or null
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public Layout getLayout() {
    checkWidget();
    return layout;
  }

  /**
   * If the argument is <code>true</code>, causes subsequent layout
   * operations in the receiver or any of its children to be ignored.
   * No layout of any kind can occur in the receiver or any of its
   * children until the flag is set to false.
   * Layout operations that occurred while the flag was
   * <code>true</code> are remembered and when the flag is set to
   * <code>false</code>, the layout operations are performed in an
   * optimized manner.  Nested calls to this method are stacked.
   *
   * @param defer the new defer state
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @see #layout(boolean)
   * @see #layout(Control[])
   *
   * @since 1.3
   */
  public void setLayoutDeferred( boolean defer ) {
    checkWidget();
    if( !defer ) {
      if( --layoutCount == 0 ) {
        if( ( state & LAYOUT_CHILD ) != 0 || ( state & LAYOUT_NEEDED ) != 0 ) {
          updateLayout( true, true );
        }
      }
    } else {
      layoutCount++;
    }
  }

  /**
   * Returns <code>true</code> if the receiver has deferred
   * the performing of layout, and <code>false</code> otherwise.
   *
   * @return the receiver's deferred layout state
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @see #setLayoutDeferred(boolean)
   * @see #isLayoutDeferred()
   */
  public boolean getLayoutDeferred() {
    checkWidget();
    return layoutCount > 0;
  }

  /**
   * Returns <code>true</code> if the receiver or any ancestor
   * up to and including the receiver's nearest ancestor shell
   * has deferred the performing of layouts.  Otherwise, <code>false</code>
   * is returned.
   *
   * @return the receiver's deferred layout state
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @see #setLayoutDeferred(boolean)
   * @see #getLayoutDeferred()
   */
  public boolean isLayoutDeferred() {
    checkWidget();
    return findDeferredControl() != null;
  }

  /**
   * If the receiver has a layout, asks the layout to <em>lay out</em>
   * (that is, set the size and location of) the receiver's children.
   * If the receiver does not have a layout, do nothing.
   * <p>
   * This is equivalent to calling <code>layout(true)</code>.
   * </p>
   * <p>
   * Note: Layout is different from painting. If a child is
   * moved or resized such that an area in the parent is
   * exposed, then the parent will paint. If no child is
   * affected, the parent will not paint.
   * </p>
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void layout() {
    checkWidget();
    layout( true );
  }

  /**
   * If the receiver has a layout, asks the layout to <em>lay out</em>
   * (that is, set the size and location of) the receiver's children.
   * If the argument is <code>true</code> the layout must not rely
   * on any information it has cached about the immediate children. If it
   * is <code>false</code> the layout may (potentially) optimize the
   * work it is doing by assuming that none of the receiver's
   * children has changed state since the last layout.
   * If the receiver does not have a layout, do nothing.
   * <p>
   * If a child is resized as a result of a call to layout, the
   * resize event will invoke the layout of the child.  The layout
   * will cascade down through all child widgets in the receiver's widget
   * tree until a child is encountered that does not resize.  Note that
   * a layout due to a resize will not flush any cached information
   * (same as <code>layout(false)</code>).
   * </p>
   * <p>
   * Note: Layout is different from painting. If a child is
   * moved or resized such that an area in the parent is
   * exposed, then the parent will paint. If no child is
   * affected, the parent will not paint.
   * </p>
   *
   * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void layout( boolean changed ) {
    checkWidget();
    if( layout != null ) {
      layout( changed, false );
    }
  }

  /**
   * If the receiver has a layout, asks the layout to <em>lay out</em>
   * (that is, set the size and location of) the receiver's children.
   * If the changed argument is <code>true</code> the layout must not rely
   * on any information it has cached about its children. If it
   * is <code>false</code> the layout may (potentially) optimize the
   * work it is doing by assuming that none of the receiver's
   * children has changed state since the last layout.
   * If the all argument is <code>true</code> the layout will cascade down
   * through all child widgets in the receiver's widget tree, regardless of
   * whether the child has changed size.  The changed argument is applied to
   * all layouts.  If the all argument is <code>false</code>, the layout will
   * <em>not</em> cascade down through all child widgets in the receiver's widget
   * tree.  However, if a child is resized as a result of a call to layout, the
   * resize event will invoke the layout of the child.  Note that
   * a layout due to a resize will not flush any cached information
   * (same as <code>layout(false)</code>).
   * </p>
   * <p>
   * Note: Layout is different from painting. If a child is
   * moved or resized such that an area in the parent is
   * exposed, then the parent will paint. If no child is
   * affected, the parent will not paint.
   * </p>
   *
   * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise
   * @param all <code>true</code> if all children in the receiver's widget tree should be laid out, and <code>false</code> otherwise
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void layout( boolean changed, boolean all ) {
    checkWidget();
    if( layout != null || all ) {
      markLayout( changed, all );
      updateLayout( true, all );
    }
  }

  /**
   * Forces a lay out (that is, sets the size and location) of all widgets that
   * are in the parent hierarchy of the changed control up to and including the
   * receiver.  The layouts in the hierarchy must not rely on any information
   * cached about the changed control or any of its ancestors.  The layout may
   * (potentially) optimize the work it is doing by assuming that none of the
   * peers of the changed control have changed state since the last layout.
   * If an ancestor does not have a layout, skip it.
   * <p>
   * Note: Layout is different from painting. If a child is
   * moved or resized such that an area in the parent is
   * exposed, then the parent will paint. If no child is
   * affected, the parent will not paint.
   * </p>
   *
   * @param changed a control that has had a state change which requires a recalculation of its size
   *
   * @exception IllegalArgumentException <ul>
   *    <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
   *    <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
   * </ul>
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void layout( Control[] changed ) {
    checkWidget();
    if( changed == null ) {
      error( SWT.ERROR_INVALID_ARGUMENT );
    }
    layout( changed, SWT.NONE );
  }

  /**
   * Forces a lay out (that is, sets the size and location) of all widgets that
   * are in the parent hierarchy of the changed control up to and including the
   * receiver.
   * <p>
   * The parameter <code>flags</code> may be a combination of:
   * <dl>
   * <dt><b>SWT.ALL</b></dt>
   * <dd>all children in the receiver's widget tree should be laid out</dd>
   * <dt><b>SWT.CHANGED</b></dt>
   * <dd>the layout must flush its caches</dd>
   * <dt><b>SWT.DEFER</b></dt>
   * <dd>layout will be deferred</dd>
   * </dl>
   * </p>
   * <p>
   * When the <code>changed</code> array is specified, the flags <code>SWT.ALL</code>
   * and <code>SWT.CHANGED</code> have no effect. In this case, the layouts in the
   * hierarchy must not rely on any information cached about the changed control or
   * any of its ancestors.  The layout may (potentially) optimize the
   * work it is doing by assuming that none of the peers of the changed
   * control have changed state since the last layout.
   * If an ancestor does not have a layout, skip it.
   * </p>
   * <p>
   * When the <code>changed</code> array is not specified, the flag <code>SWT.ALL</code>
   * indicates that the whole widget tree should be laid out. And the flag
   * <code>SWT.CHANGED</code> indicates that the layouts should flush any cached
   * information for all controls that are laid out.
   * </p>
   * <p>
   * The <code>SWT.DEFER</code> flag always causes the layout to be deferred by
   * calling <code>Composite.setLayoutDeferred(true)</code> and scheduling a call
   * to <code>Composite.setLayoutDeferred(false)</code>, which will happen when
   * appropriate (usually before the next event is handled). When this flag is set,
   * the application should not call <code>Composite.setLayoutDeferred()</code>.
   * </p>
   * <p>
   * Note: Layout is different from painting. If a child is
   * moved or resized such that an area in the parent is
   * exposed, then the parent will paint. If no child is
   * affected, the parent will not paint.
   * </p>
   *
   * @param changed a control that has had a state change which requires a recalculation of its size
   * @param flags the flags specifying how the layout should happen
   *
   * @exception IllegalArgumentException <ul>
   *    <li>ERROR_INVALID_ARGUMENT - if any of the controls in changed is null or has been disposed</li>
   *    <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
   * </ul>
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @since 1.3
   */
  // [if]: This is a verbatim copy of SWT, thus no reformatting was done.
  public void layout (Control [] changed, int flags) {
    checkWidget ();
    if (changed != null) {
      for (int i=0; i<changed.length; i++) {
        Control control = changed [i];
        if (control == null) {
          error (SWT.ERROR_INVALID_ARGUMENT);
        }
        if (control.isDisposed ()) {
          error (SWT.ERROR_INVALID_ARGUMENT);
        }
        boolean ancestor = false;
        Composite composite = control.parent;
        while (composite != null) {
          ancestor = composite == this;
          if (ancestor) {
            break;
          }
          composite = composite.parent;
        }
        if (!ancestor) {
          error (SWT.ERROR_INVALID_PARENT);
        }
      }
      int updateCount = 0;
      Composite [] update = new Composite [16];
      for (int i=0; i<changed.length; i++) {
        Control child = changed [i];
        Composite composite = child.parent;
        while (child != this) {
          if (composite.layout != null) {
            composite.state |= LAYOUT_NEEDED;
            if (!composite.layout.flushCache (child)) {
              composite.state |= LAYOUT_CHANGED;
            }
          }
          if (updateCount == update.length) {
            Composite [] newUpdate = new Composite [update.length + 16];
            System.arraycopy (update, 0, newUpdate, 0, update.length);
            update = newUpdate;
          }
          child = update [updateCount++] = composite;
          composite = child.parent;
        }
      }
      if ((flags & SWT.DEFER) != 0) {
        setLayoutDeferred (true);
        display.addLayoutDeferred (this);
      }
      for (int i=updateCount-1; i>=0; i--) {
        update [i].updateLayout (false);
      }
    } else {
      if (layout == null && (flags & SWT.ALL) == 0) {
        return;
      }
      markLayout ((flags & SWT.CHANGED) != 0, (flags & SWT.ALL) != 0);
      if ((flags & SWT.DEFER) != 0) {
        setLayoutDeferred (true);
        display.addLayoutDeferred (this);
      }
      updateLayout ((flags & SWT.ALL) != 0);
    }
  }

  @Override
  void markLayout( boolean changed, boolean all ) {
    if( layout != null ) {
      state |= LAYOUT_NEEDED;
      if( changed ) {
        state |= LAYOUT_CHANGED;
      }
    }
    if( all ) {
      Control[] children = controlHolder.getControls();
      for( int i = 0; i < children.length; i++ ) {
        children[ i ].markLayout( changed, all );
      }
    }
  }

  void updateLayout( boolean all ) {
    updateLayout( true, all );
  }

  @Override
  void updateLayout( boolean resize, boolean all ) {
    Composite parent = findDeferredControl();
    if( parent != null ) {
      parent.state |= LAYOUT_CHILD;
      return;
    }
    if( ( state & LAYOUT_NEEDED ) != 0 ) {
      boolean changed = ( state & LAYOUT_CHANGED ) != 0;
      state &= ~( LAYOUT_NEEDED | LAYOUT_CHANGED );
// if (resize) setResizeChildren (false);
      layout.layout( this, changed );
// if (resize) setResizeChildren (true);
    }
    if( all ) {
      state &= ~LAYOUT_CHILD;
      Control[] children = controlHolder.getControls();
      for( int i = 0; i < children.length; i++ ) {
        children[ i ].updateLayout( resize, all );
      }
    }
  }

  Composite findDeferredControl() {
    return layoutCount > 0 ? this : parent.findDeferredControl();
  }

  @Override
  public Point computeSize( int wHint, int hHint, boolean changed ) {
    checkWidget();
    Point size;
    boolean hasChanged = changed;
    if( layout != null ) {
      if( wHint == SWT.DEFAULT || hHint == SWT.DEFAULT ) {
        hasChanged |= ( state & LAYOUT_CHANGED ) != 0;
        state &= ~LAYOUT_CHANGED;
        size = layout.computeSize( this, wHint, hHint, hasChanged );
      } else {
        size = new Point( wHint, hHint );
      }
    } else {
      size = minimumSize( wHint, hHint, hasChanged );
    }
    if( size.x == 0 ) {
      size.x = DEFAULT_WIDTH;
    }
    if( size.y == 0 ) {
      size.y = DEFAULT_HEIGHT;
    }
    if( wHint != SWT.DEFAULT ) {
      size.x = wHint;
    }
    if( hHint != SWT.DEFAULT ) {
      size.y = hHint;
    }
    Rectangle trim = computeTrim( 0, 0, size.x, size.y );
    return new Point( trim.width, trim.height );
  }

  /**
   * Clears any data that has been cached by a Layout for all widgets that
   * are in the parent hierarchy of the changed control up to and including the
   * receiver.  If an ancestor does not have a layout, it is skipped.
   *
   * @param changed an array of controls that changed state and require a recalculation of size
   *
   * @exception IllegalArgumentException <ul>
   *    <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
   *    <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
   * </ul>
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @since 1.0
   */
  public void changed( Control[] changed ) {
    checkWidget();
    if( changed == null ) {
      error( SWT.ERROR_INVALID_ARGUMENT );
    }
    for( int i = 0; i < changed.length; i++ ) {
      Control control = changed[ i ];
      if( control == null ) {
        error( SWT.ERROR_INVALID_ARGUMENT );
      }
      if( control.isDisposed() ) {
        error( SWT.ERROR_INVALID_ARGUMENT );
      }
      boolean ancestor = false;
      Composite composite = control.parent;
      while( composite != null ) {
        ancestor = composite == this;
        if( ancestor ) {
          break;
        }
        composite = composite.parent;
      }
      if( !ancestor ) {
        error( SWT.ERROR_INVALID_PARENT );
      }
      }
    for( int i = 0; i < changed.length; i++ ) {
      Control child = changed[ i ];
      Composite composite = child.parent;
      while( child != this ) {
        if( composite.layout == null || !composite.layout.flushCache( child ) )
        {
          composite.state |= LAYOUT_CHANGED;
        }
        child = composite;
        composite = child.parent;
      }
    }
  }

  /**
   * Returns the receiver's background drawing mode. This
   * will be one of the following constants defined in class
   * <code>SWT</code>:
   * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
   * <code>INHERTIT_FORCE</code>.
   *
   * @return the background mode
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @see SWT
   *
   * @since 1.1
   */
  public int getBackgroundMode() {
    checkWidget();
    return backgroundMode;
  }

  /**
   * Sets the background drawing mode to the argument which should be one of the
   * following constants defined in class <code>SWT</code>:
   * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
   * <code>INHERIT_FORCE</code>.
   *
   * @param mode the new background mode
   * @exception SWTException
   *                <ul>
   *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
   *                disposed</li>
   *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
   *                thread that created the receiver</li>
   *                </ul>
   * @see SWT
   * @since 1.1
   */
  public void setBackgroundMode( int mode ) {
    checkWidget();
    backgroundMode = mode;
    Control[] children = controlHolder.getControls();
    for( int i = 0; i < children.length; i++ ) {
      children[ i ].updateBackgroundMode();
    }
  }

  @Override
  void updateBackgroundMode() {
    super.updateBackgroundMode();
    Control[] children = controlHolder.getControls();
    for( int i = 0; i < children.length; i++ ) {
      children[ i ].updateBackgroundMode();
    }
  }

  // ///////////////////
  // setFocus override

  @Override
  public boolean setFocus() {
    checkWidget();
    Control[] children = getChildren();
//     for( int i = 0; i < children.length; i++ ) {
//      Control child = children[ i ];
//      if( child.setRadioFocus() )
//        return true;
//    }
    Control focusedChild = null;
    for( int i = 0; focusedChild == null && i < children.length; i++ ) {
      Control child = children[ i ];
      if( child.setFocus() ) {
        focusedChild = child;
      }
    }
    boolean result = true;
    if( focusedChild == null ) {
      result = super.setFocus();
    }
    return result;
  }

  ////////////
  // Tab Order

  /**
   * Sets the tabbing order for the specified controls to
   * match the order that they occur in the argument list.
   *
   * @param tabList the ordered list of controls representing the tab order or null
   *
   * @exception IllegalArgumentException <ul>
   *    <li>ERROR_INVALID_ARGUMENT - if a widget in the tabList is null or has been disposed</li>
   *    <li>ERROR_INVALID_PARENT - if widget in the tabList is not in the same widget tree</li>
   * </ul>
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   */
  public void setTabList( Control[] tabList ) {
    checkWidget();
    Control[] newList = tabList;
    if( tabList != null ) {
      for( int i = 0; i < tabList.length; i++ ) {
        Control control = tabList[ i ];
        if( control == null ) {
          error( SWT.ERROR_INVALID_ARGUMENT );
        }
        if( control.isDisposed() ) {
          error( SWT.ERROR_INVALID_ARGUMENT );
        }
        if( control.parent != this ) {
          error( SWT.ERROR_INVALID_PARENT );
        }
      }
      newList = new Control[ tabList.length ];
      System.arraycopy( tabList, 0, newList, 0, tabList.length );
    }
    this.tabList = newList;
  }

  /**
   * Gets the (possibly empty) tabbing order for the control.
   *
   * @return tabList the ordered list of controls representing the tab order
   *
   * @exception SWTException <ul>
   *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
   * </ul>
   *
   * @see #setTabList
   */
  // returns only tabGroups
  public Control[] getTabList() {
    checkWidget();
    Control[] result = _getTabList();
    if( result == null ) {
      int count = 0;
      Control[] list = controlHolder.getControls();
      for( int i = 0; i < list.length; i++ ) {
        if( list[ i ].isTabGroup() ) {
          count++;
        }
      }
      result = new Control[ count ];
      int index = 0;
      for( int i = 0; i < list.length; i++ ) {
        if( list[ i ].isTabGroup() ) {
          result[ index++ ] = list[ i ];
        }
      }
    }
    return result;
  }

  // filters disposed controls out
  Control[] _getTabList() {
    if( tabList != null ) {
      int count = 0;
      for( int i = 0; i < tabList.length; i++ ) {
        if( !tabList[ i ].isDisposed() ) {
          count++;
        }
      }
      if( count != tabList.length ) {
        Control[] newList = new Control[ count ];
        int index = 0;
        for( int i = 0; i < tabList.length; i++ ) {
          if( !tabList[ i ].isDisposed() ) {
            newList[ index++ ] = tabList[ i ];
          }
        }
        tabList = newList;
      }
    }
    return tabList;
  }

  @Override
  boolean isTabGroup() {
    return true;
  }


  /////////////////////////////////////
  // Helping method used by computeSize

  Point minimumSize( int wHint, int hHint, boolean changed ) {
    Control[] children = getChildren();
    Rectangle clientArea = getClientArea();
    int width = 0, height = 0;
    for( int i = 0; i < children.length; i++ ) {
      Rectangle rect = children[ i ].getBounds();
      width = Math.max( width, rect.x - clientArea.x + rect.width );
      height = Math.max( height, rect.y - clientArea.y + rect.height );
    }
    return new Point( width, height );
  }

  /////////////////////////////////////////////////
  // Internal methods to maintain the child controls

  @Override
  void releaseChildren() {
    super.releaseChildren();
    Control[] children = controlHolder.getControls();
    for( int i = 0; i < children.length; i++ ) {
      children[ i ].dispose();
    }
  }

  void removeControl( Control control ) {
    if( controlHolder.contains( control ) ) {
      controlHolder.remove( control );
    }
  }

  ////////////////
  // Resize helper

  @Override
  void notifyResize( Point oldSize ) {
    // TODO [rh] revise this: the SWT code (method sendResize) first calls
    //      'super' (fires resize events) and *then* does the layouting
    if( !oldSize.equals( getSize() ) || isLayoutNeeded() ) {
      ProcessActionRunner.add( new Runnable() {
        public void run() {
          if( !isDisposed() && layout != null ) {
            markLayout( false, false );
            updateLayout( false, false );
          }
        }
      } );
    }
    super.notifyResize( oldSize );
  }

  private boolean isLayoutNeeded() {
    return ( state & LAYOUT_NEEDED ) != 0;
  }

  ///////////////////
  // Skinning support

  @Override
  void reskinChildren( int flags ) {
    super.reskinChildren( flags );
    Control[] children = controlHolder.getControls();
    for( int i = 0; i < children.length; i++ ) {
      Control child = children[ i ];
      if( child != null ) {
        child.reskin( flags );
      }
    }
  }

  ////////////////
  // Inner classes

  private final class CompositeAdapter implements ICompositeAdapter, SerializableCompatibility {

    public void markLayoutNeeded() {
      markLayout( false, false );
    }

  }
}