/* Gnome panel: extern applet functions
 * (C) 1997 the Free Software Foundation
 *
 * Authors:  George Lebl
 *           Federico Mena
 *           Miguel de Icaza
 */

#include <gdk/gdkx.h>
#include <config.h>
#include <string.h>
#include <signal.h>
#include <gnome.h>

#include "panel-include.h"
#include "gnome-panel.h"

#define APPLET_EVENT_MASK (GDK_BUTTON_PRESS_MASK |		\
			   GDK_BUTTON_RELEASE_MASK |		\
			   GDK_POINTER_MOTION_MASK |		\
			   GDK_POINTER_MOTION_HINT_MASK)

extern GSList *panels;

extern GSList *applets;
extern GSList *applets_last;
extern int applet_count;

extern int config_sync_timeout;
extern GSList *applets_to_sync;
extern int panels_to_sync;
extern int globals_to_sync;
extern int need_complete_save;

extern GtkTooltips *panel_tooltips;

extern GlobalConfig global_config;

extern char *panel_cfg_path;
extern char *old_panel_cfg_path;

/********************* CORBA Stuff *******************/

CORBA_ORB orb = NULL;
CORBA_Environment ev;
PortableServer_POA thepoa;

/***Panel stuff***/
static GNOME_PanelSpot
s_panel_add_applet(POA_GNOME_Panel *servant,
		   GNOME_Applet panel_applet,
		   CORBA_char *goad_id,
		   CORBA_char ** cfgpath,
		   CORBA_char ** globcfgpath,
		   CORBA_unsigned_long* wid,
		   CORBA_Environment *ev);

static GNOME_PanelSpot
s_panel_add_applet_full(POA_GNOME_Panel *servant,
			GNOME_Applet panel_applet,
			CORBA_char *goad_id,
			CORBA_short panel,
			CORBA_short pos,
			CORBA_char ** cfgpath,
			CORBA_char ** globcfgpath,
			CORBA_unsigned_long* wid,
			CORBA_Environment *ev);

static void
s_panel_quit(POA_GNOME_Panel *servant, CORBA_Environment *ev);

static CORBA_boolean
s_panel_get_in_drag(POA_GNOME_Panel *servant, CORBA_Environment *ev);



/*** PanelSpot stuff ***/

static CORBA_char *
s_panelspot_get_tooltip(POA_GNOME_PanelSpot *servant,
			CORBA_Environment *ev);

static void
s_panelspot_set_tooltip(POA_GNOME_PanelSpot *servant,
			CORBA_char *val,
			CORBA_Environment *ev);

static CORBA_short
s_panelspot_get_parent_panel(POA_GNOME_PanelSpot *servant,
			     CORBA_Environment *ev);

static CORBA_short
s_panelspot_get_spot_pos(POA_GNOME_PanelSpot *servant,
			 CORBA_Environment *ev);

static GNOME_Panel_OrientType
s_panelspot_get_parent_orient(POA_GNOME_PanelSpot *servant,
			      CORBA_Environment *ev);

static void
s_panelspot_register_us(POA_GNOME_PanelSpot *servant,
		     CORBA_Environment *ev);

static void
s_panelspot_unregister_us(POA_GNOME_PanelSpot *servant,
		       CORBA_Environment *ev);

static void
s_panelspot_abort_load(POA_GNOME_PanelSpot *servant,
		       CORBA_Environment *ev);

static void
s_panelspot_show_menu(POA_GNOME_PanelSpot *servant,
		      CORBA_Environment *ev);

static void
s_panelspot_drag_start(POA_GNOME_PanelSpot *servant,
		       CORBA_Environment *ev);

static void
s_panelspot_drag_stop(POA_GNOME_PanelSpot *servant,
		      CORBA_Environment *ev);

static void
s_panelspot_add_callback(POA_GNOME_PanelSpot *servant,
			 CORBA_char *callback_name,
			 CORBA_char *stock_item,
			 CORBA_char *menuitem_text,
			 CORBA_Environment *ev);

static void
s_panelspot_remove_callback(POA_GNOME_PanelSpot *servant,
			    CORBA_char *callback_name,
			    CORBA_Environment *ev);

static void
s_panelspot_sync_config(POA_GNOME_PanelSpot *servant,
			CORBA_Environment *ev);

static PortableServer_ServantBase__epv panel_base_epv = {
  NULL, /* _private */
  NULL, /* finalize */
  NULL, /* use base default_POA function */
};

static POA_GNOME_Panel__epv panel_epv = {
  NULL, /* private data */
  (gpointer)&s_panel_add_applet,
  (gpointer)&s_panel_add_applet_full,
  (gpointer)&s_panel_quit,
  (gpointer)&s_panel_get_in_drag
};
static POA_GNOME_Panel__vepv panel_vepv = { &panel_base_epv, &panel_epv };
static POA_GNOME_Panel panel_servant = { NULL, &panel_vepv };


static PortableServer_ServantBase__epv panelspot_base_epv = {
  NULL, /* _private */
  NULL, /* finalize */
  NULL, /* use base default_POA function */
};

static POA_GNOME_PanelSpot__epv panelspot_epv = {
  NULL, /* private data */
  (gpointer)&s_panelspot_get_tooltip,
  (gpointer)&s_panelspot_set_tooltip,
  (gpointer)&s_panelspot_get_parent_panel,
  (gpointer)&s_panelspot_get_spot_pos,
  (gpointer)&s_panelspot_get_parent_orient,
  (gpointer)&s_panelspot_register_us,
  (gpointer)&s_panelspot_unregister_us,
  (gpointer)&s_panelspot_abort_load,
  (gpointer)&s_panelspot_show_menu,
  (gpointer)&s_panelspot_drag_start,
  (gpointer)&s_panelspot_drag_stop,
  (gpointer)&s_panelspot_add_callback,
  (gpointer)&s_panelspot_remove_callback,
  (gpointer)&s_panelspot_sync_config
};
static POA_GNOME_PanelSpot__vepv panelspot_vepv = { &panelspot_base_epv, &panelspot_epv };

/********************* NON-CORBA Stuff *******************/

static void
extern_start_new_goad_id(Extern *e)
{
        CORBA_Environment ev;
	CORBA_exception_init(&ev);
	CORBA_Object_release(goad_server_activate_with_id(NULL, e->goad_id, GOAD_ACTIVATE_NEW_ONLY|GOAD_ACTIVATE_ASYNC, NULL),&ev);
	CORBA_exception_free(&ev);
}

void
extern_clean(Extern *ext)
{
	CORBA_Environment ev;
	CORBA_exception_init(&ev);

	g_free(ext->goad_id);
	g_free(ext->cfg);

	CORBA_Object_release(ext->pspot, &ev);
	CORBA_Object_release(ext->applet, &ev);
	POA_GNOME_PanelSpot__fini((PortableServer_Servant) ext, &ev);

	g_free(ext);

	CORBA_exception_free(&ev);
}




static void
extern_socket_destroy(GtkWidget *w, gpointer data)
{
	Extern *ext = data;
	gtk_widget_destroy(ext->ebox);
	extern_clean(ext);
}

/*static void
sal(GtkWidget *applet, GtkAllocation *alloc)
{
	printf("SOCKET req:   %dx%d\nSOCKET alloc: %dx%d\n",
	       applet->requisition.width,
	       applet->requisition.height,
	       applet->allocation.width,
	       applet->allocation.height);
}*/

static void
test_size(GtkWidget *applet, GtkAllocation *alloc)
{
	if(applet->allocation.width > applet->requisition.width ||
	   applet->allocation.height > applet->requisition.height) {
		gtk_widget_queue_resize(applet->parent);
	}
}

/*note that type should be APPLET_EXTERN_RESERVED or APPLET_EXTERN_PENDING
  only*/
static CORBA_unsigned_long
reserve_applet_spot (Extern *ext, PanelWidget *panel, int pos,
		     AppletType type)
{
	GtkWidget *socket;

	ext->ebox = gtk_event_box_new();
	gtk_widget_set_events(ext->ebox, (gtk_widget_get_events(ext->ebox) |
					  APPLET_EVENT_MASK) &
			      ~( GDK_POINTER_MOTION_MASK |
				 GDK_POINTER_MOTION_HINT_MASK));

	socket = gtk_socket_new();

	gtk_signal_connect_after(GTK_OBJECT(socket),"size_allocate",
				 GTK_SIGNAL_FUNC(test_size),NULL);

	/*gtk_signal_connect_after(GTK_OBJECT(socket),"size_allocate",
				 GTK_SIGNAL_FUNC(sal),NULL);*/


	g_return_val_if_fail(socket!=NULL,0);

	gtk_container_add(GTK_CONTAINER(ext->ebox),socket);

	gtk_signal_connect(GTK_OBJECT(socket),"destroy",
			   GTK_SIGNAL_FUNC(extern_socket_destroy),
			   ext);

	gtk_widget_show_all (ext->ebox);
	
	/*we save the obj in the id field of the appletinfo and the 
	  path in the path field */
	ext->info = NULL;
	if(!register_toy(ext->ebox,ext,panel,pos,type)) {
		g_warning("Couldn't add applet");
		return 0;
	}
	ext->info = applets_last->data;
	
	if(!GTK_WIDGET_REALIZED(socket))
		gtk_widget_realize(socket);

	return GDK_WINDOW_XWINDOW(socket->window);
}

void
load_extern_applet(char *goad_id, char *cfgpath, PanelWidget *panel, int pos, int queue)
{
	Extern *ext;
	POA_GNOME_PanelSpot *panelspot_servant;

	if(!cfgpath || !*cfgpath)
		cfgpath = g_strconcat(old_panel_cfg_path,
					 "Applet_Dummy/",NULL);
	else
		/*we will free this lateer*/
		cfgpath = g_strdup(cfgpath);
	
	ext = g_new(Extern,1);
	ext->started = FALSE;

	panelspot_servant = (POA_GNOME_PanelSpot *)ext;
	panelspot_servant->_private = NULL;
	panelspot_servant->vepv = &panelspot_vepv;

	POA_GNOME_PanelSpot__init(panelspot_servant, &ev);
	
	CORBA_free(PortableServer_POA_activate_object(thepoa, panelspot_servant, &ev));
	g_return_if_fail(ev._major == CORBA_NO_EXCEPTION);

	ext->pspot = CORBA_OBJECT_NIL; /*will be filled in during add_applet*/
	ext->applet = CORBA_OBJECT_NIL;
	ext->goad_id = g_strdup(goad_id);
	ext->cfg = cfgpath;

	if(reserve_applet_spot (ext, panel, pos, APPLET_EXTERN_PENDING)==0) {
		g_warning("Whoops! for some reason we can't add "
			  "to the panel");
		extern_clean(ext);
		return;
	}

	if(!queue) {
		extern_start_new_goad_id(ext);
		ext->started = TRUE;
	}
}

void
load_queued_externs(void)
{
	GSList *li;
	for(li=applets;li!=NULL;li=g_slist_next(li)) {
		AppletInfo *info = li->data;
		if(info->type == APPLET_EXTERN_PENDING ||
		   info->type == APPLET_EXTERN_RESERVED) {
			Extern *ext = info->data;
			if(!ext->started) {
				extern_start_new_goad_id(ext);
				ext->started = TRUE;
			}
		}
	}
}

/********************* CORBA Stuff *******************/


static GNOME_PanelSpot
s_panel_add_applet(POA_GNOME_Panel *servant,
		   GNOME_Applet panel_applet,
		   CORBA_char *goad_id,
		   CORBA_char ** cfgpath,
		   CORBA_char ** globcfgpath,
		   CORBA_unsigned_long* wid,
		   CORBA_Environment *ev)
{
	return s_panel_add_applet_full(servant,panel_applet,goad_id,0,0,
				       cfgpath,globcfgpath,wid,ev);
}

static GNOME_PanelSpot
s_panel_add_applet_full(POA_GNOME_Panel *servant,
			GNOME_Applet panel_applet,
			CORBA_char *goad_id,
			CORBA_short panel,
			CORBA_short pos,
			CORBA_char ** cfgpath,
			CORBA_char ** globcfgpath,
			CORBA_unsigned_long* wid,
			CORBA_Environment *ev)
{
	GSList *li;
	int i;
	Extern *ext;
	char *p;
	POA_GNOME_PanelSpot *panelspot_servant;
	GNOME_PanelSpot acc;
	
	for(li=applets;li!=NULL;li=g_slist_next(li)) {
		AppletInfo *info = li->data;
		if(info && info->type == APPLET_EXTERN_PENDING) {
			Extern *ext = info->data;
			g_assert(ext);
			g_assert(ext->info == info);
			if(strcmp(ext->goad_id,goad_id)==0) {
				/*we started this and already reserved a spot
				  for it, including the socket widget*/
				GtkWidget *socket =
					GTK_BIN(info->widget)->child;
				g_return_val_if_fail(GTK_IS_SOCKET(socket),
						     NULL);

				ext->applet = CORBA_Object_duplicate(panel_applet, ev);
				*cfgpath = CORBA_string_dup(ext->cfg);
				g_free(ext->cfg);
				ext->cfg = NULL;
				*globcfgpath = CORBA_string_dup(old_panel_cfg_path);
				info->type = APPLET_EXTERN_RESERVED;
				*wid=GDK_WINDOW_XWINDOW(socket->window);
				printf("\nSOCKET XID: %lX\n\n", (long)*wid);

				panelspot_servant = (POA_GNOME_PanelSpot *)ext;
				acc = PortableServer_POA_servant_to_reference(thepoa, panelspot_servant, ev);
				g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION,NULL);
				ext->pspot = CORBA_Object_duplicate(acc, ev);
				g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION,NULL);

				return CORBA_Object_duplicate(acc, ev);
			}
		}
	}
	
	/*this is an applet that was started from outside, otherwise we would
	  have already reserved a spot for it*/
	ext = g_new(Extern,1);

	panelspot_servant = (POA_GNOME_PanelSpot *)ext;
	panelspot_servant->_private = NULL;
	panelspot_servant->vepv = &panelspot_vepv;

	POA_GNOME_PanelSpot__init(panelspot_servant, ev);
	
	CORBA_free(PortableServer_POA_activate_object(thepoa, panelspot_servant, ev));
	g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION,NULL);

	acc = PortableServer_POA_servant_to_reference(thepoa, panelspot_servant, ev);
	g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION,NULL);

	ext->pspot = CORBA_Object_duplicate(acc, ev);

	g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION,NULL);

	ext->applet = CORBA_Object_duplicate(panel_applet, ev);
	ext->goad_id = g_strdup(goad_id);
	ext->cfg = NULL;

	/*select the nth panel*/
	if(panel)
		li = g_slist_nth(panels,panel);
	else
		li = NULL;
	if(!li)
		li = panels;

	*wid = reserve_applet_spot (ext, li->data, pos,
				      APPLET_EXTERN_RESERVED);
	if(*wid == 0) {
		extern_clean(ext);
		*globcfgpath = NULL;
		*cfgpath = NULL;
		return CORBA_OBJECT_NIL;
	}
	p = g_strconcat(old_panel_cfg_path,"Applet_Dummy/",NULL);
	*cfgpath = CORBA_string_dup(p);
	g_free(p);
	*globcfgpath = CORBA_string_dup(old_panel_cfg_path);

	return CORBA_Object_duplicate(acc, ev);
}

static void
s_panel_quit(POA_GNOME_Panel *servant, CORBA_Environment *ev)
{
	panel_quit();
}

static CORBA_boolean
s_panel_get_in_drag(POA_GNOME_Panel *servant, CORBA_Environment *ev)
{
	return panel_applet_in_drag;
}



/*** PanelSpot stuff ***/

static CORBA_char *
s_panelspot_get_tooltip(POA_GNOME_PanelSpot *servant,
			CORBA_Environment *ev)
{
	/*FIXME: get the tooltip text*/
	return CORBA_string_dup("");
}

static void
s_panelspot_set_tooltip(POA_GNOME_PanelSpot *servant,
			CORBA_char *val,
			CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	if(val && *val)
		gtk_tooltips_set_tip (panel_tooltips,ext->ebox,val,NULL);
	else
		gtk_tooltips_set_tip (panel_tooltips,ext->ebox,NULL,NULL);
}

static CORBA_short
s_panelspot_get_parent_panel(POA_GNOME_PanelSpot *servant,
			     CORBA_Environment *ev)
{
	int panel;
	GSList *list;
	gpointer p;
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	g_assert(ext->info);

	p = PANEL_WIDGET(ext->info->widget->parent);

	for(panel=0,list=panels;list!=NULL;list=g_slist_next(list),panel++)
		if(list->data == p)
			return panel;
	return -1;
}

static CORBA_short
s_panelspot_get_spot_pos(POA_GNOME_PanelSpot *servant,
			 CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;
	AppletData *ad;

	g_assert(ext);
	g_assert(ext->info);
	
	ad = gtk_object_get_data(GTK_OBJECT(ext->info->widget),
				 PANEL_APPLET_DATA);
	if(!ad)
		return -1;
	return ad->pos;
}

static GNOME_Panel_OrientType
s_panelspot_get_parent_orient(POA_GNOME_PanelSpot *servant,
			      CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;

	g_assert(ext);
	g_assert(ext->info);

	panel = PANEL_WIDGET(ext->info->widget->parent);

	g_return_val_if_fail(panel != NULL,ORIENT_UP);

	return get_applet_orient(panel);
}

static void
s_panelspot_register_us(POA_GNOME_PanelSpot *servant,
			CORBA_Environment *ev)
{
	PanelWidget *panel;
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	g_assert(ext->info);
	
	printf("register ext: %lX\n",(long)ext);
	printf("register ext->info: %lX\n",(long)(ext->info));

	panel = PANEL_WIDGET(ext->info->widget->parent);
	g_return_if_fail(panel!=NULL);

	/*no longer pending*/
	ext->info->type = APPLET_EXTERN;

	orientation_change(ext->info,panel);
	back_change(ext->info,panel);

	GNOME_Applet_set_tooltips_state(ext->applet,
					global_config.tooltips_enabled, ev);
	if(ev->_major)
		panel_clean_applet(ext->info);
}

static void
s_panelspot_unregister_us(POA_GNOME_PanelSpot *servant,
			  CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	panel_clean_applet(ext->info);
}

static void
s_panelspot_abort_load(POA_GNOME_PanelSpot *servant,
		       CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_return_if_fail(ext != NULL);

	g_return_if_fail(ext->info != NULL);
	
	/*only reserved spots can be canceled, if an applet
	  wants to chance a pending applet it needs to first
	  user reserve spot to obtain id and make it EXTERN_RESERVED*/
	if(ext->info->type != APPLET_EXTERN_RESERVED)
		return;

	panel_clean_applet(ext->info);
}

static void
s_panelspot_show_menu(POA_GNOME_PanelSpot *servant,
		      CORBA_Environment *ev)
{
	GtkWidget *panel;
	Extern *ext = (Extern *)servant;
	
	printf("show menu ext: %lX\n",(long)ext);
	printf("show menu ext->info: %lX\n",(long)(ext->info));

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);

	if (!ext->info->menu)
		create_applet_menu(ext->info);

	panel = get_panel_parent(ext->info->widget);
	if(IS_SNAPPED_WIDGET(panel)) {
		SNAPPED_WIDGET(panel)->autohide_inhibit = TRUE;
		snapped_widget_queue_pop_down(SNAPPED_WIDGET(panel));
	}

	ext->info->menu_age = 0;
	gtk_menu_popup(GTK_MENU(ext->info->menu), NULL, NULL,
		       global_config.off_panel_popups?applet_menu_position:NULL,
		       ext->info, 3, GDK_CURRENT_TIME);
}


static void
s_panelspot_drag_start(POA_GNOME_PanelSpot *servant,
		       CORBA_Environment *ev)
{
	PanelWidget *panel;
	Extern *ext = (Extern *)servant;

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);

	panel = PANEL_WIDGET(ext->info->widget->parent);

	g_return_if_fail(panel!=NULL);

	/*panel_widget_applet_drag_start(panel,info->widget);
	panel_widget_applet_drag_end(panel);*/
	panel_widget_applet_drag_start(panel,ext->info->widget);
}

static void
s_panelspot_drag_stop(POA_GNOME_PanelSpot *servant,
		      CORBA_Environment *ev)
{
	PanelWidget *panel;
	Extern *ext = (Extern *)servant;

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);

	panel = PANEL_WIDGET(ext->info->widget->parent);

	g_return_if_fail(panel!=NULL);

	panel_widget_applet_drag_end(panel);
}

static void
s_panelspot_add_callback(POA_GNOME_PanelSpot *servant,
			 CORBA_char *callback_name,
			 CORBA_char *stock_item,
			 CORBA_char *menuitem_text,
			 CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	printf("add callback ext: %lX\n",(long)ext);

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);
	applet_add_callback(ext->info, callback_name, stock_item,
			    menuitem_text);
}

static void
s_panelspot_remove_callback(POA_GNOME_PanelSpot *servant,
			    CORBA_char *callback_name,
			    CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);
	applet_remove_callback(ext->info, callback_name);
}

static void
s_panelspot_sync_config(POA_GNOME_PanelSpot *servant,
			CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_return_if_fail(ext != NULL);
	g_return_if_fail(ext->info != NULL);
	if(g_slist_find(applets_to_sync, ext->info)==NULL)
		applets_to_sync = g_slist_prepend(applets_to_sync,ext->info);
	panel_config_sync();
}

void
panel_corba_clean_up(void)
{
  goad_server_unregister(CORBA_OBJECT_NIL, "gnome_panel", "server", &ev);
  CORBA_ORB_shutdown(orb, CORBA_FALSE, &ev);
}

gint
panel_corba_gtk_init(CORBA_ORB panel_orb)
{
  GNOME_Panel acc;
  char hostname [4096];
  char *name;
  CORBA_Object ns, old_server;
  gint status;

  CORBA_exception_init(&ev);

  orb = panel_orb;

  POA_GNOME_Panel__init(&panel_servant, &ev);
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  thepoa = (PortableServer_POA)
    CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(thepoa, &ev), &ev);
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  CORBA_free(PortableServer_POA_activate_object(thepoa,
						&panel_servant, &ev));
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  acc = PortableServer_POA_servant_to_reference(thepoa, &panel_servant, &ev);
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  old_server = goad_server_activate_with_repo_id (NULL, "IDL:GNOME/Panel:1.0", 
						  GOAD_ACTIVATE_EXISTING_ONLY,
						  NULL);

  if(! CORBA_Object_is_nil(old_server, &ev)) {
    CORBA_Object_release(old_server, &ev);
    return -4;
  }

  status = goad_server_register(CORBA_OBJECT_NIL, acc, "gnome_panel", "server", &ev);

  /*
  CORBA_Object_release(acc, &ev);
  */
  g_return_val_if_fail(ev._major == CORBA_NO_EXCEPTION, -1);

  return status;
}
