/*
 * ===========================
 * VDK Visual Development Kit
 * Version 1.0.3
 * November 1999
 * ===========================
 *
 * Copyright (C) 1998, Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 * Based on ISDataBox
 * Developed by Ionutz Borcoman <borco@borco-ei.eng.hokudai.ac.jp>
 * based on  GtkDatabox - An extension to the gtk+ library
 * Copyright (C) 1998-1999 Roland Bock
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */

#ifndef _vdkdnd_h
#define _vdkdnd_h
#include <vdk/vdkobj.h>
#include <vdk/dlist.h>
#include <vdk/vdkprops.h>
#include <vdk/vdkutils.h>
#include <vdk/vdkcustom.h>
#include <vdk/rawpixmap.h>
#define dnd_base_signal user_signal/2
// target side
#define dnd_dropped_signal dnd_base_signal
#define dnd_get_data_signal dnd_base_signal + 1
#define dnd_drag_leave_signal dnd_base_signal + 2
#define dnd_drag_motion_signal dnd_base_signal + 3
 

// forward declaration
class VDKDnD;

/*
*/
class VDKDnDEntry
{
    protected:
        VDKObject* object;
        VDKDnD* dnd;
        GtkWidget* widget;
    public:
        VDKDnDEntry(VDKObject* object, VDKDnD* dnd, GtkWidget* widget);
        VDKObject* Object() { return object; }
        ~VDKDnDEntry() {} 
    friend class VDKDnD;
};


typedef VDKList<VDKDnDEntry> VDKDnDTable; 
typedef VDKListIterator<VDKDnDEntry> VDKDnDIterator; 


/*!
  \class VDKDnD
  \brief Provides dnd support
  
  \par Description
  This class provides support for gtk+ drag an drop
  VDKDnD can be viewed from two sides:
  \arg Source side:  the widget that is dragged. Source widget are normally
  non-containers widgets.
  \arg Target side: the widget that accept (is the target) of a dragged widget.
  Target widgets are normally containers widget even if not
  compulsory

  Widgets can be both sources and targets, so VDKDnD class
  supports m:n relationship between widgets interested in dnd.
  VDKDnD class provides support for both sides.
  
  \par SIGNALS
  Both signals for static and dynamic tables are provided.
  \arg dnd_dropped_signal 
  \arg "dnd_dropped"

  Received by target when a dragged widget is dropped into target
  \arg dnd_get_data_signal
  \arg "dnd_get_data"

  Received when source data are transferred to dnd widget
  (not very useful for a normal user)
  \arg dnd_drag_motion_signal
  \arg "dnd_drag_motion"

  Received by target when a dragged widget icon mouves over the target widget
  \arg	dnd_drag_leave_signal
  \arg	"dnd_drag_leave"

  Received by target when a dragged widget icon leaves the target widget
  \par TIP
  Signals using dynamic tables are handled by vdk overriding gtk+,
  thus user must connect with dynamic tables setting <gtk> arg always false.
  \code
  SignalConnect(target,"dnd_dropped",&DndForm::OnDrop,false);
  \endcode
  \par EXAMPLES
  In ./testvdk/dnd.cc
 */
class VDKDnD : public VDKRawObject
{
  
    protected:
  
    VDKDnDTable sources, targets;
    GtkTargetEntry *target_table;
    int n_entries;        
    // target side
    static gboolean drag_drop(GtkWidget *widget,
                                    GdkDragContext *context,
                                    gint x,
                                    gint y,
                                    guint time,
                                    gpointer gp);
    static void  drag_leave  (GtkWidget	*widget,
                            GdkDragContext  *context,
                            guint  time,
                            gpointer data);
    static gboolean drag_motion	(GtkWidget	       *widget,
        			    GdkDragContext  *context,
         			    gint x,
         			    gint y,
         			    guint time,
                            gpointer data);

    // source side
    static void source_drag_data_get(GtkWidget *widget,
                                      GdkDragContext     *context,
                            		  GtkSelectionData   *selection_data,
                                      guint               info,
                                      guint               time,
                                      gpointer            data);
    public:
    /*!
      The widget that actually is being dragged
     */
    VDKReadOnlyValueProp<VDKDnD,VDKObject*> DragSource;
    /*!
      Receiving a dnd_drag_motion signal, DragPoint contains mouse
      coordinates.
     */
    VDKReadOnlyValueProp<VDKDnD,VDKPoint> DragPoint;
    /*
      Constructor
      \param owner
      \param target_table target table
      \param n_entries entries on target table
     */
    VDKDnD(VDKForm* owner,
	   GtkTargetEntry* target_table,
	   guint n_entries);
    /*!
      Destructor
     */
    virtual ~VDKDnD();
    /*!
      Add a widget as dnd target.
     */
    void AddTarget(VDKObject* target);
    /*!
      Add a widget as dnd source.
     */
    void AddSource(VDKObject* source);
    /*!
     Remove a target from target list
     */
    void RemoveTarget(VDKObject* target);
    /*!
     Remove a target from source list
     */
    void RemoveSource(VDKObject* source);
    /*!
      Sets widget dragging icon
     */
    void SetIcon(VDKObject* object, VDKRawPixmap* pixmap);
    /*!
      Return sources dnd tables.
      \par Tip
      VDKDnDTable class is a  VDKList of VDKDnDEntry class objects.
      Each VDKDnDEntry object has a method Object() that returns
      source/target widget address.
      VDKDnDIterator class for accessing table is provided as well.    
     */
    VDKDnDTable* DnDSources() { return &sources; }
    /*!
      Return sources dnd target tables.
    */
    VDKDnDTable* DnDTargets() { return &targets; }
};



#endif
