/**
 * Fractal Runtime
 *
 * Copyright (C) 2009 STMicroelectronics
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * Contact: mind@ow2.org
 *
 * Authors: Matthieu Leclercq
 */

#include "ErrorCode.idt"

/**
 * A component interface to control the content of the component to which it
 * belongs. This content is supposed to be made of an unordered, unstructured
 * set of components and bindings.
 */
interface fractal.api.ContentController {

  /**
   * Returns the sub-components of the component to which this
   * interface belongs. More precisely, if the given <code>subComponents</code>
   * is <code>null</code>, this method returns the number of sub components.
   * If it is not <code>null</code>, this method assumes that the given array is
   * big enough to contain all the references to the {@link Component}
   * interfaces of the sub components.
   *
   * @param subComponents an array into which the references to the
   *      {@link Component} interfaces of the sub components are copied. Can be
   *      <code>null</code>.
   * @return the number of sub components; or
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int getFcSubComponents(in fractal.api.Component subComponents[]);

  /**
   * Returns the sub-component of the component to which this
   * interface belongs and which has the given name.
   *
   * @param name the name of the sub-component to return.
   * @param subComponent (out parameter) the {@link Component} interface of the
   *      sub-component.
   * @return  <code>0</code> if the sub-component has been returned correctly.
   *      {@link FRACTAL_API_NO_SUCH_SUB_COMPONENT} if no sub-component with the
   *      given name can be found.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int getFcSubComponent(in string name, out fractal.api.Component subComponent);

  /**
   * Returns the name of the given sub-component.
   *
   * @param subComponent the {@link Component} interface of a sub-component.
   * @param name (out parameter) the name of the given sub-component.
   * @return  <code>0</code> if the name of the sub-component has been returned
   *      correctly.
   *      {@link FRACTAL_API_NO_SUCH_SUB_COMPONENT} if the given
   *      <code>subComponent</code> is not a sub component.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int getFcSubComponentName(in fractal.api.Component subComponent,
      out string name);

  /**
   * Adds a sub-component to this component with a <code>NULL</code> local-name.
   * More precisely adds the component whose reference is given as a 
   * sub-component of the component to which this interface belongs. If <i>C</i>
   * is the sub-component set returned by {@link #getFcSubComponents 
   * getFcSubComponents} just before a call to this method, and <i>C'</i> is the
   * sub-component set just after this call, then <code>subComponent</code> is 
   * guaranteed to be in <i>C'</i>, but <i>C'</i> is <i>not</i> guaranteed to be
   * the union of <i>C</i> and <i>{subComponent}</i>, nor to contain all the
   * elements of <i>C</i>.
   *
   * @param subComponent the component to be added inside this component.
   * @return <code>0</code> if the component is added correctly.
   *      {@link FRACTAL_API_ILLEGAL_CONTENT} if the component cannot be added.
   *      {@link FRACTAL_API_ILLEGAL_LIFE_CYCLE} if this component has a
   *      {@link LifeCycleController} interface, but it is not in an appropriate
   *      state to perform this operation.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int addFcSubComponent(in fractal.api.Component subComponent);

  /**
   * Adds a sub-component to this component with the given local-name.
   * More precisely adds the component whose reference is given as a 
   * sub-component of the component to which this interface belongs. If <i>C</i>
   * is the sub-component set returned by {@link #getFcSubComponents 
   * getFcSubComponents} just before a call to this method, and <i>C'</i> is the
   * sub-component set just after this call, then <code>subComponent</code> is 
   * guaranteed to be in <i>C'</i>, but <i>C'</i> is <i>not</i> guaranteed to be
   * the union of <i>C</i> and <i>{subComponent}</i>, nor to contain all the
   * elements of <i>C</i>.
   *
   * @param subComponent the component to be added inside this component.
   * @param name the local-name of the added sub-component. May be 
   *      <code>null</code>.
   * @return <code>0</code> if the component is added correctly.
   *      {@link FRACTAL_API_ILLEGAL_CONTENT} if the component cannot be added.
   *      {@link FRACTAL_API_ILLEGAL_LIFE_CYCLE} if this component has a
   *      {@link LifeCycleController} interface, but it is not in an appropriate
   *      state to perform this operation.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int addFcNamedSubComponent(in fractal.api.Component subComponent, 
      in string name);

  /**
   * Removes a sub-component from this component. More precisely removes the
   * sub-component whose reference is given from the component to which this
   * interface belongs. If <i>C</i> is the sub-component set returned by {@link
   * #getFcSubComponents getFcSubComponents} just before a call to this
   * method, and <i>C'</i> is the sub-component set just after this call, then
   * <code>subComponent</code> is guaranteed not to be in <i>C'</i>, but
   * <i>C'</i> is <i>not</i> guaranteed to be the difference of <i>C</i> and
   * <i>{subComponent}</i>, nor to contain all the elements of <i>C</i> distinct
   * from <code>subComponent</code>.
   *
   * @param subComponent the component to be removed from this component.
   * @return <code>0</code> if the component has been removed correctly.
   *      {@link FRACTAL_API_ILLEGAL_CONTENT} if the component cannot be removed.
   *      {@link FRACTAL_API_NO_SUCH_SUB_COMPONENT} if the given
   *      <code>subComponent</code> is not a sub component.
   *      {@link FRACTAL_API_ILLEGAL_LIFE_CYCLE} if this component has a
   *      {@link LifeCycleController} interface, but it is not in an appropriate
   *      state to perform this operation.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int removeFcSubComponent(in fractal.api.Component subComponent);

  /**
   * Creates a binding inside this component.
   *
   * @param clientComponent the component that contains the client interface
   *      that has to be bound. If <code>null</code> the client component is
   *      assumed to be the component this interface belongs.
   * @param clientItfName the name of the interface at the client side of the
   *      binding. If the given <code>clientComponent</code> is a sub component;
   *      this name must refer to a client interface. If the given
   *      <code>clientComponent</code> refers to the component this interface
   *      belongs; this name must refer to a server interface.
   * @param serverComponent the component that contains the server interface
   *      that has to be bound. If <code>null</code> the server component is
   *      assumed to be the component this interface belongs.
   * @param serverItfName the name of the interface at the server side of the
   *      binding. If the given <code>serverComponent</code> is a sub component;
   *      this name must refer to a server interface. If the given
   *      <code>serverComponent</code> refers to the component this interface
   *      belongs; this name must refer to a client interface.
   * @return <code>0</code> if the binding has been added correctly.
   *      {@link FRACTAL_API_ILLEGAL_BINDING} if the binding cannot be created.
   *      {@link FRACTAL_API_NO_SUCH_SUB_COMPONENT} if the
   *      <code>clientComponent</code> or the <code>serverComponent</code> is
   *      neither a sub component nor the component this interface belongs.
   *      {@link FRACTAL_API_ILLEGAL_LIFE_CYCLE} if this component has a
   *      {@link LifeCycleController} interface, but it is not in an appropriate
   *      state to perform this operation.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int addFcSubBinding(in fractal.api.Component clientComponent,
      in string clientItfName, in fractal.api.Component serverComponent,
      in string serverItfName);

  /**
   * Removes a binding inside this component.
   *
   * @param clientComponent the component that contains the client interface
   *      that has to be unbound. If <code>null</code> the client component is
   *      assumed to be the component this interface belongs.
   * @param clientItfName the name of the interface that has to be unbound.
   *      If the given <code>clientComponent</code> is a sub component;
   *      this name must refer to a client interface. If the given
   *      <code>clientComponent</code> refers to the component this interface
   *      belongs; this name must refer to a server interface.
   * @return <code>0</code> if the binding has been removed correctly.
   *      {@link FRACTAL_API_ILLEGAL_BINDING} if the binding cannot be removed.
   *      {@link FRACTAL_API_NO_SUCH_SUB_COMPONENT} if the given
   *      <code>clientComponent</code> is neither a sub component nor the
   *      component this interface belongs.
   *      {@link FRACTAL_API_ILLEGAL_LIFE_CYCLE} if this component has a
   *      {@link LifeCycleController} interface, but it is not in an appropriate
   *      state to perform this operation.
   *      {@link FRACTAL_API_OPERATION_NOT_SUPPORTED} if this operation is not
   *      supported.
   */
  int removeFcSubBinding(in fractal.api.Component clientComponent,
      in string clientItfName);
}
