//  BMP
//  Copyright (C) 2005-2008 BMP development.
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//  --
//
//  The BMPx project hereby grants permission for non-GPL compatible GStreamer
//  plugins to be used and distributed together with GStreamer and BMPx. This
//  permission is above and beyond the permissions granted by the GPL license
//  BMPx is covered by.

#include <cstring>
#include <gtkmm.h>
#include "xds.hh"
#define MAX_URI_LEN 4096

namespace Bmp
{
    void
    XDS::xds_set ()
    {
      using namespace Gtk;
      using namespace std;

      typedef vector < TargetEntry > TEntries;
      TEntries entries;
      entries.push_back (TargetEntry ("XdndDirectSave0", Gtk::TargetFlags(0), 0));
      dynamic_cast<Gtk::Widget *>(this)->drag_source_set (entries, Gdk::MODIFIER_MASK); 
    }

    void
    XDS::xds_unset ()
    {
      dynamic_cast<Gtk::Widget *>(this)->drag_source_unset ();
    }


    XDS::XDS () {};
    XDS::~XDS () {};

    void
    XDS::xds_drag_end (const Glib::RefPtr<Gdk::DragContext>& context_)
    {
      GdkDragContext *context = context_->gobj();
      GdkAtom property;

      //XDS: Set up atoms
      property = gdk_atom_intern ("XdndDirectSave0", FALSE);

      //XDS: Clear property on the window
      gdk_property_delete (context->source_window, property);
    }

    void
    XDS::xds_drag_begin (const Glib::RefPtr<Gdk::DragContext>& context_, Glib::ustring const& basename)
    {
      GdkDragContext *context = context_->gobj();
      GdkAtom         property, type;

      //XDS: Set up atoms
      property = gdk_atom_intern ("XdndDirectSave0", FALSE);
      type = gdk_atom_intern ("text/plain", FALSE); 

      //XDS: Set property on the window
      gdk_property_change (context->source_window,
               property, type, 8, GDK_PROP_MODE_REPLACE,
               (const unsigned char *) basename.c_str(), !basename.empty() ? strlen (basename.c_str()) : 0);
    }
  
    void
    XDS::xds_drag_data_get (const Glib::RefPtr<Gdk::DragContext>& context_, Gtk::SelectionData& selection_data_, unsigned int info, unsigned int time)
    {
      GdkDragContext *context = context_->gobj();
      GtkSelectionData *selection_data = selection_data_.gobj();
      GdkAtom        property = gdk_atom_intern ("XdndDirectSave0", FALSE);
      GdkAtom        type     = gdk_atom_intern ("text/plain", FALSE);
      unsigned char *dnddata;
      char      *_uri; 
      int           length;
      Glib::ustring  uri;

      if (!gdk_property_get (context->source_window, property, type,
                  0, MAX_URI_LEN, FALSE,
                  NULL, NULL, &length, &dnddata))
    return;


      _uri = g_strndup ((const char *) dnddata, length);
      uri  = _uri;
      g_free (dnddata);
      g_free (_uri);

      if (xds_acceptable (uri))
    {
        gtk_selection_data_set (selection_data, selection_data->target, 8,
                      (const unsigned char *) "S", 1);
        xds_drag_action (uri);
    }
      else
    {
        gtk_selection_data_set (selection_data, selection_data->target, 8,
                      (const unsigned char *) "E", 1);
    }
    }
}
