/*
 *   xmcd - Motif(tm) CD Audio Player
 *
 *   Copyright (C) 1993-2001  Ti Kan
 *   E-mail: xmcd@amb.org
 *
 *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#ifndef LINT
static char *_userreg_c_ident_ = "@(#)userreg.c	7.18 01/04/09";
#endif

#include "common_d/appenv.h"
#include "common_d/patchlevel.h"
#include "common_d/util.h"
#include "cdinfo_d/cdinfo.h"
#include "xmcd_d/xmcd.h"
#include "xmcd_d/widget.h"
#include "xmcd_d/cdfunc.h"
#include "xmcd_d/dbprog.h"
#include "xmcd_d/help.h"
#include "xmcd_d/userreg.h"
#include "libdi_d/libdi.h"


extern widgets_t	widgets;
extern appdata_t	app_data;
extern FILE		*errfp;


/***********************
 *  internal routines  *
 ***********************/



/***********************
 *   public routines   *
 ***********************/

/*
 * dbprog_structupd
 *	Update userreg window widgets to match the userreg structure.
 *
 * Args:
 *	s - Pointer to the curstat_t structure.
 *
 * Return:
 *	Nothing.
 */
/*ARGSUSED*/
void
userreg_structupd(curstat_t *s)
{
	cdinfo_incore_t	*dbp = cdinfo_addr();
	char		*p;

	if (dbp->userreg.handle != NULL) {
		p = XmTextGetString(widgets.userreg.handle_txt);
		if (p == NULL || strcmp(p, dbp->userreg.handle) != 0) {
			XmTextSetString(
				widgets.userreg.handle_txt,
				dbp->userreg.handle
			);
			XmTextSetInsertionPosition(
				widgets.userreg.handle_txt,
				strlen(dbp->userreg.handle)
			);
		}
		if (p != NULL)
			XtFree(p);
	}
	else {
		XmTextSetString(widgets.userreg.handle_txt, "");
	}

	if (dbp->userreg.hint != NULL) {
		p = XmTextGetString(widgets.userreg.hint_txt);
		if (p == NULL || strcmp(p, dbp->userreg.hint) != 0) {
			XmTextSetString(
				widgets.userreg.hint_txt,
				dbp->userreg.hint
			);
			XmTextSetInsertionPosition(
				widgets.userreg.hint_txt,
				strlen(dbp->userreg.hint)
			);
		}
		if (p != NULL)
			XtFree(p);
	}
	else {
		XmTextSetString(widgets.userreg.hint_txt, "");
	}

	if (dbp->userreg.email != NULL) {
		p = XmTextGetString(widgets.userreg.email_txt);
		if (p == NULL || strcmp(p, dbp->userreg.email) != 0) {
			XmTextSetString(
				widgets.userreg.email_txt,
				dbp->userreg.email
			);
			XmTextSetInsertionPosition(
				widgets.userreg.email_txt,
				strlen(dbp->userreg.email)
			);
		}
		if (p != NULL)
			XtFree(p);
	}
	else {
		XmTextSetString(widgets.userreg.email_txt, "");
	}

	if (dbp->userreg.region != NULL) {
		p = XmTextGetString(widgets.userreg.region_txt);
		if (p == NULL || strcmp(p, dbp->userreg.region) != 0) {
			XmTextSetString(
				widgets.userreg.region_txt,
				cdinfo_region_name(dbp->userreg.region)
			);
		}
		if (p != NULL)
			XtFree(p);
	}
	else {
		XmTextSetString(widgets.userreg.region_txt, "");
	}

	if (dbp->userreg.age != NULL) {
		p = XmTextGetString(widgets.userreg.age_txt);
		if (p == NULL || strcmp(p, dbp->userreg.age) != 0) {
			XmTextSetString(
				widgets.userreg.age_txt,
				dbp->userreg.age
			);
			XmTextSetInsertionPosition(
				widgets.userreg.age_txt,
				strlen(dbp->userreg.age)
			);
		}
		if (p != NULL)
			XtFree(p);
	}
	else {
		XmTextSetString(widgets.userreg.age_txt, "");
	}

	if (dbp->userreg.gender != NULL) {
		if (dbp->userreg.gender[0] == 'm') {
			XmToggleButtonSetState(
				widgets.userreg.male_btn, True, False
			);
		}
		else if (dbp->userreg.gender[0] == 'f') {
			XmToggleButtonSetState(
				widgets.userreg.female_btn, True, False
			);
		}
		else {
			XmToggleButtonSetState(
				widgets.userreg.unspec_btn, True, False
			);
		}
	}
	else {
		XmToggleButtonSetState(
			widgets.userreg.unspec_btn, True, False
		);
	}

	XmToggleButtonSetState(
		widgets.userreg.allowmail_btn,
		(Boolean) dbp->userreg.allowemail,
		False
	);
	XmToggleButtonSetState(
		widgets.userreg.allowstats_btn,
		(Boolean) dbp->userreg.allowstats,
		False
	);
}


/*
 * userreg_do_popup
 *	User registration window pop up
 *
 * Args:
 *	s - Pointer to the curstat_t structure
 *	from_prog - Denotes that this is a program-initiated popup
 *
 * Return:
 *	Nothing
 */
void
userreg_do_popup(curstat_t *s, bool_t from_prog)
{
	static bool_t	first = TRUE;

	if (!from_prog && XtIsManaged(widgets.userreg.form)) {
		XtUnmapWidget(XtParent(widgets.userreg.form));
		XtUnmanageChild(widgets.userreg.form);
		return;
	}

	/* Update userreg widgets */
	userreg_structupd(s);

	/* The userreg popup has mappedWhenManaged set to False,
	 * so we have to map/unmap explicitly.  The reason for this
	 * is we want to avoid a screen glitch when we move the window
	 * in cd_dialog_setpos(), so we map the window afterwards.
	 */
	XtManageChild(widgets.userreg.form);
	if (first) {
		first = FALSE;

		/* Set up dialog box position */
		cd_dialog_setpos(XtParent(widgets.userreg.form));
	}
	XtMapWidget(XtParent(widgets.userreg.form));

	/* Put focus on the user handle text field */
	XmProcessTraversal(widgets.userreg.handle_txt, XmTRAVERSE_CURRENT);
}


/**************** vv Callback routines vv ****************/


/*
 * userreg_popup
 *	Callback function for the "Register..." button
 */
/*ARGSUSED*/
void
userreg_popup(Widget w, XtPointer client_data, XtPointer call_data)
{
	curstat_t	*s = (curstat_t *)(void *) client_data;

	userreg_do_popup(s, FALSE);
}


/*
 * userreg_focus_next
 *	Change focus to the next widget on done
 */
/*ARGSUSED*/
void
userreg_focus_next(Widget w, XtPointer client_data, XtPointer call_data)
{
	Widget	nextw;

	if (w == widgets.userreg.handle_txt)
		nextw = widgets.userreg.passwd_txt;
	else if (w == widgets.userreg.passwd_txt)
		nextw = widgets.userreg.vpasswd_txt;
	else if (w == widgets.userreg.vpasswd_txt)
		nextw = widgets.userreg.hint_txt;
	else if (w == widgets.userreg.hint_txt)
		nextw = widgets.userreg.email_txt;
	else if (w == widgets.userreg.email_txt)
		nextw = widgets.userreg.region_chg_btn;
	else if (w == widgets.userreg.postal_txt)
		nextw = widgets.userreg.age_txt;
	else if (w == widgets.userreg.age_txt)
		nextw = widgets.userreg.male_btn;
	else
		return;

	/* Put focus on the next widget */
	XmProcessTraversal(nextw, XmTRAVERSE_CURRENT);
}


/*
 * userreg_gender_sel
 *	User registration gender selector callback
 */
/*ARGSUSED*/
void
userreg_gender_sel(Widget w, XtPointer client_data, XtPointer call_data)
{
	XmRowColumnCallbackStruct	*p =
		(XmRowColumnCallbackStruct *)(void *) call_data;
	XmToggleButtonCallbackStruct	*q;
	cdinfo_incore_t			*dbp = cdinfo_addr();
	char				*str;

	if (p == NULL)
		return;

	q = (XmToggleButtonCallbackStruct *)(void *) p->callbackstruct;

	if (!q->set)
		return;

	if (p->widget == widgets.userreg.male_btn)
		str = "m";
	else if (p->widget == widgets.userreg.female_btn)
		str = "f";
	else
		str = "";

	if (!util_newstr(&dbp->userreg.gender, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}

	/* Put focus on the next widget */
	XmProcessTraversal(widgets.userreg.allowmail_btn, XmTRAVERSE_CURRENT);
}


/*
 * userreg_gethint
 *	User registration "gethint" button callback.
 */
/*ARGSUSED*/
void
userreg_gethint(Widget w, XtPointer client_data, XtPointer call_data)
{
	curstat_t	*s = (curstat_t *)(void *) client_data;
	cdinfo_incore_t	*dbp = cdinfo_addr();
	cdinfo_ret_t	ret;
	char		*str;

	str = XmTextGetString(widgets.userreg.handle_txt);
	if (!util_newstr(&dbp->userreg.handle, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	if (dbp->userreg.handle == NULL) {
		/* Put input focus on the passwd text widget */
		XmProcessTraversal(
			widgets.userreg.handle_txt,
			XmTRAVERSE_CURRENT
		);

		CD_INFO(app_data.str_handlereq);
		return;
	}

	/* Switch to watch cursor */
	cd_busycurs(TRUE, CURS_USERREG);

	/* Get password hint */
	if ((ret = cdinfo_getpasshint(s)) != 0) {
		DBGPRN(DBG_CDI)(errfp,
			"cdinfo_getpasshint: status=%d arg=%d\n",
			CDINFO_GET_STAT(ret), CDINFO_GET_ARG(ret));
	}

	/* Switch to normal cursor */
	cd_busycurs(FALSE, CURS_USERREG);

	switch (CDINFO_GET_STAT(ret)) {
	case 0:
		/* Success */
		CD_INFO(app_data.str_mailinghint);
		break;

	case NAME_ERR:
		CD_INFO(app_data.str_unknhandle);
		break;

	case HINT_ERR:
		CD_INFO(app_data.str_nohint);
		break;

	case MAIL_ERR:
		CD_INFO(app_data.str_nomailhint);
		break;

	default:
		CD_INFO(app_data.str_hinterr);
		break;
	}
}


/*
 * userreg_ok
 *	User registration OK button callback
 */
/*ARGSUSED*/
void
userreg_ok(Widget w, XtPointer client_data, XtPointer call_data)
{
	curstat_t	*s = (curstat_t *)(void *) client_data;
	char		*str;
	cdinfo_incore_t	*dbp = cdinfo_addr();
	cdinfo_ret_t	ret;

	str = XmTextGetString(widgets.userreg.handle_txt);
	if (!util_newstr(&dbp->userreg.handle, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	str = XmTextGetString(widgets.userreg.hint_txt);
	if (!util_newstr(&dbp->userreg.hint, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	str = XmTextGetString(widgets.userreg.email_txt);
	if (!util_newstr(&dbp->userreg.email, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	str = XmTextGetString(widgets.userreg.email_txt);
	if (!util_newstr(&dbp->userreg.email, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	str = XmTextGetString(widgets.userreg.postal_txt);
	if (!util_newstr(&dbp->userreg.postal, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	str = XmTextGetString(widgets.userreg.age_txt);
	if (!util_newstr(&dbp->userreg.age, str)) {
		CD_FATAL(app_data.str_nomemory);
		return;
	}
	XtFree(str);

	dbp->userreg.allowemail = (bool_t) XmToggleButtonGetState(
		widgets.userreg.allowmail_btn
	);

	dbp->userreg.allowstats = (bool_t) XmToggleButtonGetState(
		widgets.userreg.allowstats_btn
	);

	/* Sanity check */
	if (dbp->userreg.handle == NULL) {
		/* Put input focus on the user handle text widget */
		XmProcessTraversal(
			widgets.userreg.handle_txt,
			XmTRAVERSE_CURRENT
		);

		CD_INFO(app_data.str_handlereq);
		return;
	}
	else if (dbp->userreg.passwd == NULL) {
		/* Put input focus on the passwd text widget */
		XmProcessTraversal(
			widgets.userreg.passwd_txt,
			XmTRAVERSE_CURRENT
		);

		CD_INFO(app_data.str_passwdreq);
		return;
	}
	else if (dbp->userreg.vpasswd == NULL ||
	         strcmp(dbp->userreg.passwd, dbp->userreg.vpasswd) != 0) {
		/* Put input focus on the passwd text widget */
		XmProcessTraversal(
			widgets.userreg.passwd_txt,
			XmTRAVERSE_CURRENT
		);

		CD_INFO(app_data.str_passwdmatcherr);

		/* Clear out the password fields */
		XmTextSetString(widgets.userreg.passwd_txt, "");
		XmTextSetString(widgets.userreg.vpasswd_txt, "");
		return;
	}

	/* Switch to watch cursor */
	cd_busycurs(TRUE, CURS_USERREG);

	/* Register the user */
	if ((ret = cdinfo_reguser(s)) != 0) {
		DBGPRN(DBG_CDI)(errfp, "cdinfo_reguser: status=%d arg=%d\n",
			CDINFO_GET_STAT(ret), CDINFO_GET_ARG(ret));
	}

	/* Switch to normal cursor */
	cd_busycurs(FALSE, CURS_USERREG);

	switch (CDINFO_GET_STAT(ret)) {
	case 0:
		/* Success */
		break;

	case NAME_ERR:
		/* User handle or password error */
		CD_INFO(app_data.str_handleerr);

		/* Put focus on the user handle text field */
		XmProcessTraversal(
			widgets.userreg.handle_txt,
			XmTRAVERSE_CURRENT
		);
		return;

	default:
		/* Failure */
		CD_INFO(app_data.str_userregfail);
		return;
	}

	/* Registration success - pop down registration form */
	XtUnmapWidget(XtParent(widgets.userreg.form));
	XtUnmanageChild(widgets.userreg.form);

	/* Clear out passwords */
	XmTextSetString(widgets.userreg.passwd_txt, "");
	XmTextSetString(widgets.userreg.vpasswd_txt, "");
	if (dbp->userreg.passwd != NULL) {
		memset(dbp->userreg.passwd, 0, strlen(dbp->userreg.passwd));
		MEM_FREE(dbp->userreg.passwd);
		dbp->userreg.passwd = NULL;
	}
	if (dbp->userreg.vpasswd != NULL) {
		memset(dbp->userreg.vpasswd, 0, strlen(dbp->userreg.vpasswd));
		MEM_FREE(dbp->userreg.vpasswd);
		dbp->userreg.vpasswd = NULL;
	}

	if (s->qmode != QMODE_MATCH) {
		/* Re-load from CDDB */
		dbprog_dbclear(s, TRUE);
		dbprog_dbget(s);
	}
}


/*
 * userreg_privacy
 *	User registration privacy info button callback
 */
/*ARGSUSED*/
void
userreg_privacy(Widget w, XtPointer client_data, XtPointer call_data)
{
	char	path[FILE_PATH_SZ];

	(void) sprintf(path, DOCFILE_PATH, app_data.libdir);;
	(void) strcat(path, "PRIVACY");
	help_loadfile(path);
}


/*
 * userreg_cancel
 *	User registration cancel button callback
 */
/*ARGSUSED*/
void
userreg_cancel(Widget w, XtPointer client_data, XtPointer call_data)
{
	XtUnmapWidget(XtParent(widgets.userreg.form));
	XtUnmanageChild(widgets.userreg.form);
}


