// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef EXT_SPLITTER_H_
#define EXT_SPLITTER_H_

#include <Wt/WContainerWidget>
#include <Wt/Ext/ExtDllDefs.h>

namespace Wt {

  class WTable;
  class WTableCell;

  namespace Ext {

    class SplitterHandle;

/*! \class Splitter Wt/Ext/Splitter Wt/Ext/Splitter
 *  \brief A container widget with resize handles between its children.
 *
 * Provides a container in which widgets are laid out either
 * horizontally (side by side, Horizontal orientation), or vertically
 * (Vertical orientation).
 *
 * Widgets are separated by a SplitterHandle which the user may use to
 * resize widgets. For this to work properly, you need to properly specify
 * widths, and minimum- and maximum widths for the widgets:
 *
 * <ul>
 *   <li>They MUST have their width (or height) set using WWidget::resize(),
 *     in WLength::Pixel units. You cannot specify the size through CSS!</li>
 *
 *   <li>Optionally, the may have a minimum width (or minimum height)
 *     set using WWidget::setMinimumSize() and
 *     WWidget::setMaximumSize(). Again, you cannot specify these
 *     properties through CSS!</li>
 *
 *   <li>Probably you will want to insert each widget in a WScrollArea, or
 *     set the CSS overflow attribute to hidden (which clips anything that
 *     goes outside) or auto (to add scroll bars).</li>
 * </ul>
 *
 * <i>Note: removing or adding widgets after initial render is not yet
 *    supported.</i>
 *
 * \ingroup ext
 */
class WT_EXT_API Splitter : public WContainerWidget
{
public:
  /*! \brief Create a new horizontal splitter.
   */
  Splitter(WContainerWidget *parent = 0);

  /*! \brief Create a new splitter with the given orientation.
   */
  Splitter(Orientation orientation, WContainerWidget *parent = 0);

  /*! \brief Set the orientation.
   */
  void setOrientation(Orientation orientation);

  /*! \brief Return the orientation.
   */
  Orientation orientation() const { return orientation_; }

  /*! \brief Set the width of the resize handles (in pixels).
   *
   * The default width is 4 pixels.
   *
   * \sa handleWidth()
   */
  void setHandleWidth(int width);

  /*! \brief Return the width of the resize handles.
   *
   * The default width is 4 pixels.
   *
   * \sa setHandleWidth()
   */
  int handleWidth() const { return handleWidth_; }

  /*! \brief Returns the handle to the left (or above) the widget at
   *         the given <i>index</i>.
   *
   * There is no handle to the left of the widget at index 0, and 0 will
   * be returned.
   */
  SplitterHandle *handle(int index) const;

  virtual void addWidget(WWidget *widget);
  virtual void insertWidget(int index, WWidget *widget);
  virtual void insertBefore(WWidget *widget, WWidget *before);

  const std::vector<WWidget *>& children() const { return children_; }

private:
  Orientation                   orientation_;
  WContainerWidget             *container_;
  std::vector<WWidget *>        children_;
  std::vector<SplitterHandle *> handles_;
  int                           handleWidth_;

  virtual DomElement *createDomElement(WApplication *app);

  void insertHandle(int index);
  void deleteHandle(int index);

  WWidget *widgetBefore(const SplitterHandle *handle) const;
  WWidget *widgetAfter(const SplitterHandle *handle) const;
  SplitterHandle *splitterBefore(const SplitterHandle *handle) const;
  SplitterHandle *splitterAfter(const SplitterHandle *handle) const;

  friend class SplitterHandle;
};

  }
}

#endif // EXT_SPLITTER_H_
