// 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_WIDGET_H_
#define EXT_WIDGET_H_

#include <Wt/WWebWidget>
#include <Wt/Ext/ExtDllDefs.h>
#include <Wt/Ext/WExtGlobal>
#include <sstream>

namespace Wt {
  namespace Ext {

class AbstractButton;
class BorderLayout;
class TableView;

/*! \class Widget Wt/Ext/Widget Wt/Ext/Widget
 *  \brief An abstract base class for all %Ext widgets.
 *
 * %Ext Widgets wrap around JavaScript-only widgets that are provided by
 * the <a href="http://extjs.com">Ext JS</a> JavaScript widget library.
 *
 * \ingroup ext
 */
class WT_EXT_API Widget : public WWebWidget
{
protected:
  Widget(WContainerWidget *parent = 0);

public:
  /*! \brief Delete a widget.
   */
  ~Widget();

  virtual void setHidden(bool hidden,
			 const WAnimation& animation = WAnimation());

  const std::string elVar() const;
  const std::string elRef() const;
  virtual std::string createExtElement(std::stringstream& js,
				       DomElement *inContainer);

  std::string extId() const;

private:
  virtual std::string createJS(DomElement *inContainer) = 0;

protected:
  virtual void           updateDom(DomElement& element, bool all);
  virtual DomElement    *createDomElement(WApplication *app);
  virtual DomElementType domElementType() const;
  virtual void           getDomChanges(std::vector<DomElement *>& result,
				       WApplication *app);
  virtual void           propagateRenderOk(bool deep);
  virtual std::string    renderRemoveJs(bool recursive);

  virtual void createConfig(std::ostream& config);
  virtual void updateExt();

  virtual bool applySelfCss() const;

  std::string  configStruct();

  void addUpdateJS(const std::string& js);

  void addOrphan(WWidget *child);
  void removeOrphan(WWidget *child);

  void addWtSignalConfig(const std::string& handler, EventSignalBase *s,
			 const std::string& name, const std::string& eventArgs,
			 const std::string& wtArg, std::ostream& config);
  void updateWtSignal(EventSignalBase *s, const std::string& name,
		      const std::string& eventArgs,
		      const std::string& wtArg);
  void bindEventHandler(const std::string& eventName,
			const std::string& handler,
			std::stringstream& js);

  std::string createMixed(const std::vector<WWidget *>& items,
			  std::stringstream& js);
  void renderExtAdd(WWidget *item);

private:
  std::string jsUpdates_;

  static void initExt();
  void addExtChild(WWidget *child, std::stringstream& js);

  std::string jsWtSignalFunction(EventSignalBase *s, const std::string& name,
				 const std::string& eventArgs,
				 const std::string& wtArg);

  friend class AbstractButton;
  friend class Dialog;
  friend class TableView;
  friend class MessageBox;
  friend class Panel;
};

  }
}

#endif // EXT_WIDGET_H_
