#include <stdlib.h>
#include <Xm/Xm.h>
#include <xdclass.h>
#include <utils.h>


#ifdef    VMS
#ifndef   STRDUP_SUPPORTED

#include <stdlib.h>

#define   _STRDUP_UNSUPPORTED
#endif /* STRDUP_SUPPORTED */
#endif /* VMS */


#ifdef    _STRDUP_UNSUPPORTED
#define   _LPCSTR_COPY        _LpcstrCopy

static LPCSTR _LpcstrCopy(LPCSTR s)
{
	register char *cptr = (char *) 0 ;

	if (s != (LPCSTR) 0) {
		cptr = (char *) malloc((unsigned) (strlen((char *) s) + 1)) ;

		if (cptr != (char *) 0) {
			(void) strcpy(cptr,(char *) s) ;
		}
	}

	return (LPCSTR) cptr ;
}
#endif /* _STRDUP_UNSUPPORTED */


#ifndef   _LPCSTR_COPY
#define   _LPCSTR_COPY        strdup
#endif /* _LPCSTR_COPY */


CFileDialog::CFileDialog(
	BOOL bOpenFileDialog,
	LPCSTR /*lpszDefExt*/, // Ignored
	LPCSTR lpszFileName,
	DWORD /*dwFlags*/, // Ignored
	LPCSTR lpszFilter,
	CWnd* pParentWnd)
{
    _xd_bOpenFileDialog=bOpenFileDialog;
    if ( lpszFileName )
	_xd_lpszFileName = _LPCSTR_COPY(lpszFileName);
    else
	_xd_lpszFileName=NULL;
    if ( lpszFilter)
	_xd_lpszFilter = _LPCSTR_COPY(lpszFilter);
    else
	_xd_lpszFilter=NULL;
    _xd_pParentWnd=pParentWnd;
    _xd_current_state=virgin;
}

CFileDialog::~CFileDialog()
{
    if (_xd_lpszFileName)
	free(_xd_lpszFileName);
    if (_xd_lpszFilter)
	free(_xd_lpszFilter);
}

BOOL
CFileDialog::OnInitDialog()
{
    return TRUE;
}

int
CFileDialog::DoModal()
{
    // Have to set resources and callbacks to emulate MFC behaviour
    // and use private event loop so that we can return
    // a value.
    if (_xd_current_state==virgin)
    {
	OnInitDialog ();
	WidgetList children;
	XmString xm_name_string = NULL;
	XmString xm_filter_string = NULL;
	XtVaGetValues(_xd_rootwidget, XmNchildren, &children, 0);
	if ( children && children[0] )
	{
	    XtAddCallback(children[0], XmNokCallback, xd_OnOk, this);
	    XtAddCallback(children[0], XmNcancelCallback, xd_OnCancel, this);
	    XtAddCallback(_xd_rootwidget, XmNpopdownCallback, xd_OnCancel, this);
	    if (_xd_lpszFilter)
	    {
		xm_filter_string = XmStringCreateLtoR ( _xd_lpszFilter, XmFONTLIST_DEFAULT_TAG );
		XtVaSetValues ( children[0], XmNpattern, xm_filter_string, NULL );
		XmStringFree ( xm_filter_string );
	    }
	    if (_xd_lpszFileName)
	    {
		xm_name_string = XmStringCreateLtoR ( _xd_lpszFileName, XmFONTLIST_DEFAULT_TAG );
		XtVaSetValues ( children[0], XmNdirSpec, xm_name_string, NULL );
		XmStringFree ( xm_name_string );
	    }
	}
    }
    _xd_current_state=undecided;
    // Popup the dialog
    WidgetList children;
    XtVaGetValues(_xd_rootwidget, XmNchildren, &children, 0);
    XtManageChild(children[0]);
    XtAppContext app_context=XtWidgetToApplicationContext(_xd_rootwidget);
    XEvent event;
    // Process events until Ok or Cancel callback triggered
    while (_xd_current_state==undecided)
    {
	XtAppNextEvent(app_context, &event);
	XtDispatchEvent(&event);
    }
    XtUnmanageChild(children[0]);
    return _xd_current_state;
}

CString
CFileDialog::GetPathName() const
{
    static char* s=NULL;
    XtFree(s);
    if (_xd_current_state!=ok)
	return "";
    XmString xmstr;
    WidgetList children;
    XtVaGetValues(_xd_rootwidget, XmNchildren, &children, 0);
    XtVaGetValues(children[0], XmNdirSpec, &xmstr, 0);
    s=xd_text_from_XmString(xmstr);
    XmStringFree(xmstr);
    return s;
}

void
CFileDialog::xd_OnOk(Widget, XtPointer client_data, XtPointer)
{
    CFileDialog *instance=(CFileDialog *)client_data;
    instance->OnOK();
}

void
CFileDialog::OnOK()
{
    _xd_current_state=ok;
}

void
CFileDialog::xd_OnCancel(Widget, XtPointer client_data, XtPointer)
{
    CFileDialog *instance=(CFileDialog *)client_data;
    instance->OnCancel();
}

void
CFileDialog::OnCancel()
{
    // From cancel button or popdown (via WM menu or OK button)
    if (_xd_current_state==undecided)
	_xd_current_state=cancel;
}
