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

static Widget xd_optmenu_item(Widget rootwidget, int nIndex)
{
    // Find an item in an option menu given its index.
    // Return NULL if the index is out of range.

    // Get the menu pane
    Widget cascade=XmOptionButtonGadget(rootwidget);
    Widget menupane;
    XtVaGetValues(cascade, XmNsubMenuId, &menupane, 0);
    WidgetList children;
    Cardinal num_children;
    XtVaGetValues(menupane,
		    XmNchildren, &children,
		    XmNnumChildren, &num_children,
		    0);
    if (nIndex<0 || nIndex>=num_children)
	return NULL;
    else
	return children[nIndex];
}

static char *xd_optmenu_text(Widget rootwidget, int nIndex)
{
    // Get text from an option menu item given its index
    Widget w=xd_optmenu_item(rootwidget, nIndex);
    if (w)
	return xd_text_from_XmLabel(w);
    else
	return NULL;
}

int CComboBox::GetCurSel() const
{
    // Return the index of the currently selected item
    // Return value:
    //  0 if the widget has not been created (no call to create() yet).
    //  The zero-based index of the currently selected item otherwise.
    if (_xd_rootwidget==0)
	return 0;
    Widget selected;
    XtVaGetValues(_xd_rootwidget, XmNmenuHistory, &selected, 0);
    short position;
    XtVaGetValues(selected, XmNpositionIndex, &position, 0);
    return position;
}

int CComboBox::GetLBText(int nIndex, LPSTR lpszText) const
{
    // Get a copy of the text of the item identified by nIndex
    // and return its length
    // Return value:
    //  0 if the widget has not been created (no call to create() yet).
    //  LB_ERR if the index is out of range.
    //  The length of the item text otherwise.

    int len=0;
    if (_xd_rootwidget!=0)
    {
	char *s=xd_optmenu_text(_xd_rootwidget, nIndex);
	if (s)
	{
	    strcpy(lpszText, s);
	    len=strlen(s);
	    XtFree(s);
	}
	else
	    len=LB_ERR;
    }
    return len;
}

int CComboBox::GetLBTextLen(int nIndex) const
{
    // Get the length of the text of the item identified by nIndex
    // Return value:
    //  0 if the widget has not been created (no call to create() yet).
    //  LB_ERR if the index is out of range.
    //  The length of the item text otherwise.

    int len=0;
    if (_xd_rootwidget!=0)
    {
	char *s=xd_optmenu_text(_xd_rootwidget, nIndex);
	if (s)
	{
	    len=strlen(s);
	    XtFree(s);
	}
	else
	    len=LB_ERR;
    }
    return len;
}

int CComboBox::SetCurSel(int nSelect)
{
    // Set the currently selected item by index.
    // Return value:
    //  0 if the widget has not been created (no call to create() yet).
    //  LB_ERR if the index is out of range.
    //  The index of the selected item otherwise.

    // MFC difference:
    // The value nSelect==-1 is not supported as it is not
    // possible to clear the selection.

    if (_xd_rootwidget==0)
	return 0;
    Widget cascade=XmOptionButtonGadget(_xd_rootwidget);
    Widget menupane;
    XtVaGetValues(cascade, XmNsubMenuId, &menupane, 0);
    WidgetList children;
    Cardinal num_children;
    XtVaGetValues(menupane,
		    XmNchildren, &children,
		    XmNnumChildren, &num_children,
		    0);
    if (nSelect<0 || nSelect>=num_children)
	return LB_ERR;
    else
    {
	XtVaSetValues(_xd_rootwidget,
			XmNmenuHistory, children[nSelect],
			NULL);
	return nSelect;
    }
}

int CComboBox::xd_get_window_text(LPSTR lpszStringBuf, int nMaxCount) const
{
    // Get the window text of a combo box (which is the text of
    // the selected item)
    // Return value:
    //  0 if the widget has not been created (no call to create() yet).
    //  LB_ERR if there is no selected item.
    //  The length of the text otherwise.
    int len=0;
    if (_xd_rootwidget!=0)
    {
	Widget w;
	XtVaGetValues(_xd_rootwidget, XmNmenuHistory, &w, 0);
	if (w)
	{
	    char *s=xd_text_from_XmLabel(w);
	    strncpy(lpszStringBuf, s, nMaxCount - 1);
	    lpszStringBuf[nMaxCount-1]='\0';
	    len=strlen(lpszStringBuf);
	    XtFree(s);
	}
	else
	    len=LB_ERR;
    }
    return len;
}

int CComboBox::xd_get_window_text_length() const
{
    // This corresponds to the MFC behaviour
    if (_xd_rootwidget!=0)
	return -1;
    else
	return 0;
}
