/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <Xm/Xm.h>
#include <Xm/List.h>
#include <Xm/Text.h>
#include <Xm/PushB.h>
#include <mars.h>
#include <Drag.h>
#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <sys/stat.h>
#include <xec.h>
#include <drop.h>

typedef struct data {
	char *to;
	char *subject;
} data;

static option opts[] = {
	{"to",NULL,NULL,"metview@ecmwf.int",
	t_str,sizeof(char*),OFFSET(data,to),},
	{"subject",NULL,NULL,"Metview Bug Report",
	t_str,sizeof(char*),OFFSET(data,subject),},
};

data setup;


Boolean bug = False;
svc *s;
extern Widget top,text_to,text_subject,text_msg,list_icons,
remove_button,menu_to;

XtAppContext app_context;
Display      *display;

void out(int lvl,const char *message)
{
	static request *r = NULL;
	if(r == NULL) r = empty_request("USER_MESSAGE");
	set_value(r,"INFO","%s",message);
	send_message(s,r);
}

int execute(char *buf)
{
	char line[1024];
	FILE *f = popen(buf,"r");
	if(!f) {
		marslog(LOG_EROR|LOG_PERR,"popen(%s) failed",buf);
		return -1;
	}

	while(fgets(line,sizeof(line),f))
		marslog(LOG_INFO,"%s",line);

	if(pclose(f))
	{
		marslog(LOG_EROR|LOG_PERR,"pclose(%s) failed",buf);
		return -1;
	}
	return 0;
}

void add_addresses(char *add)
{
	char line[1024];
	if(add)
	{
		if(*add)
			XtManageChild(XmCreatePushButton(menu_to,add,0,0));
	}
	else
	{
		FILE *f = popen("sort -u $METVIEW_USER_DIRECTORY/..mail","r");
		if(!f) return;
		while(fgets(line,sizeof(line),f))
		{
			if(*line) line[strlen(line)-1] = 0;
			if(*line) XtManageChild(XmCreatePushButton(menu_to,line,0,0));
		}
		pclose(f);
	}
}

void save_addresses()
{
	char buf[1024];
	FILE *f;
	Widget *children;
	int count,i;

	sprintf(buf,"%s/..mail",getenv("METVIEW_USER_DIRECTORY"));
	f = fopen(buf,"w");
	if(!f) return;

	XtVaGetValues(menu_to,
		XmNchildren,&children,
		XmNnumChildren,&count,NULL);

	for(i=0;i<count;i++)
		fprintf(f,"%s\n",XtName(children[i]));

	fclose(f);
}

void drag_callback( Widget w , XtPointer cd , DragCallbackStruct* cb )
{
	/* cb->accept_it = True; */
	/* printf("drag_callback\n"); */
}

void send_callback (Widget w, XtPointer cd, XmAnyCallbackStruct *cb )
{
	char  cmd[10240];
	char  buf[1024];
	XmString *items;
	int       item_count,i;
	char *tmp = marstmp();
	char *p;


	xec_SaveText(text_msg,tmp);

	sprintf(cmd,"%s/metview-mail -s ",getenv("METVIEW_BIN"));

	sprintf(buf,"\"%s\" ",p=XmTextGetString(text_to)) ; XtFree((XtPointer)p);
	strcat(cmd,buf);
	sprintf(buf,"\"%s\" ",p=XmTextGetString(text_subject));XtFree((XtPointer)p);
	strcat(cmd,buf);
	sprintf(buf,"\"%s\" ",tmp);
	strcat(cmd,buf);

	XtVaGetValues(list_icons,XmNitems,&items,XmNitemCount,&item_count,NULL);
	for(i=0;i<item_count;i++)
	{
		sprintf(buf,"\"%s\" ",p=xec_GetString(items[i]));XtFree((XtPointer)p);
		strcat(cmd,buf);
	}


	add_addresses(p = XmTextGetString(text_to));XtFree((XtPointer)p);
	save_addresses();

	strcat(cmd," 2>&1");

	if(execute(cmd) == 0)
	{
		marslog(LOG_INFO,"Mail sent...");
		exit(0);
	}
	marslog(LOG_INFO,"Error while sending mail...");
}

void cancel_callback (Widget w, XtPointer cd, XmAnyCallbackStruct *cb )
{
	marsexit(0);
}

void browse_callback (Widget w, XtPointer cd, XmListCallbackStruct *cb )
{
	XtSetSensitive(remove_button,cb->selected_item_count>0);
}

void remove_callback (Widget w, XtPointer cd, XmAnyCallbackStruct *cb )
{
	XmString *items;
	int       item_count;

	XtVaGetValues(list_icons,
	    XmNselectedItems,&items,
	    XmNselectedItemCount,&item_count,NULL);
	XmListDeleteItems(list_icons,items,item_count);
	XtSetSensitive(remove_button,False);
}

void entry_callback (Widget w, XtPointer cd, XmRowColumnCallbackStruct *cb )
{
	XmTextSetString(text_to,XtName(cb->widget));
}

void init(request *r)
{
	const char *p;
	int n = 0;

	if(XtIsRealized(top)) XMapRaised(XtDisplay(top),XtWindow(top));

	p = get_value(r,"TO",0);
	XmTextSetString(text_to,(char*)(p?p:""));
	p = get_value(r,"SUBJECT",0);
	XmTextSetString(text_subject,(char*)(p?p:""));
	p = get_value(r,"MESSAGE",0);
	XmTextSetString(text_msg,(char*)(p?p:""));

	xec_ClearList(list_icons);
	XtSetSensitive(remove_button,False);

	/* while(p = get_value(r,"SELECTION",n++)) xec_AddListItem(list_icons,p);*/
}

/* rename 'mail' to 'email' because 'mail' conflicts with './Mars/tools.c' */
void email(svcid *id,request *r,void *v)
{
	init(r);
	bug = False;
	send_reply(id,NULL);
}

void bugs(svcid *id,request *r,void *v)
{
	init(r);
	bug = True;
	XmTextSetString(text_to,setup.to);
	XmTextSetString(text_subject,setup.subject);
	send_reply(id,NULL);
}

void state(svcid *id,request *r,void *v)
{
	mars.debug = 1;
	print_all_requests(r);
	r = empty_request("MAIL");
	send_reply(id,r);
	free_all_requests(r);
}

void drop(svcid *id,request *r,void *v)
{
	while(r)
	{
        const char *p = get_value(r,"NAME",0);
        if(p) xec_AddListItem(list_icons,p);
		r = r->next;
	}
	send_reply(id,0);
}

void receive(Widget w, dropid *id  , void *data)
{
	int i;
	for(i=0;i<id->count;i++)
		printf("receive --- %s %s\n",id->cb[i].icon_name,id->cb[i].icon_class);

	id->header = empty_request("DROP");
	id->action = DROP_ACTION_NAME_AND_CLASS;
}



int main (int argc, char **argv)
{
	marsinit(&argc,argv,&setup,NUMBER(opts),opts);


	XtToolkitInitialize ();
	app_context = XtCreateApplicationContext ();
	display = XtOpenDisplay (app_context, NULL, argv[0], "Metview",
	    NULL, 0, &argc, argv);
	if (!display)
	{
		printf("%s: can't open display, exiting...\n", argv[0]);
		exit (-1);
	}
	/* Register converters, just in case you are really unlucky !! */
	XmRegisterConverters();
	/* String to unit type doesn't get added !! */
	XtAddConverter ( XmRString, XmRUnitType, XmCvtStringToUnitType, NULL, 0 );
	create_top ( display, argv[0], argc, argv );


	s = RegisterService(app_context,progname());

	mars.outproc = out;

	add_service_callback(s,"MAIL", email, NULL);
	add_service_callback(s,"BUGS", bugs, NULL);
	add_service_callback(s,"DROP", drop, NULL);

	RegisterDropTarget(s,list_icons,receive,NULL);
	XtRealizeWidget (top);

	add_addresses(NULL);

	XtAppMainLoop (app_context);
	exit (0);
}
