/*
 *    File msellist.c
 */

#include <stdio.h>
#include <string.h>

#include "mguipp.h"

#include "mguitest.hpp"

class MSelList : public CmCallback
{
    CmShell *shell;
    CmSList *mslist;
    CmSList *slist;
    CmLabel *label;
public:
    MSelList();
    void closeDialog(void) { delete shell; delete this; };
    void moveItems(void);
    void selectAllItems(void);
    void deselectAllItems(void);
    void onSelection(LIST_SEL * sel);
};

/***************************************************************
 *	This callback moves all the selected items from a
 *	source list to a destination list
 ***************************************************************/
void MSelList::moveItems(void)
{
    LIST_ACT *pi;
/*
 * Freeze the lists to prevent unnecessary drawing
 */
    mslist->freeze();
    slist->freeze();
    pi = mslist->getFirstSelectedItem();
    while (pi)
    {
	slist->addItem(pi->item, 0L);
	mslist->delItem(pi->item);
	pi = mslist->getNextSelectedItem();
    }
    mslist->thaw();
    slist->thaw();
}

/***************************************************************
 *	This function selects all items in the source list
 ***************************************************************/
void MSelList::selectAllItems(void)
{
    LIST_ACT *pi;

    pi = mslist->getFirstItem();
    mslist->freeze();
    while (pi)
    {
	mslist->selectItem(pi->item);
	pi = mslist->getNextItem();
    }
    mslist->thaw();
}

/***************************************************************
 *	This function deselects all items in the source list
 ***************************************************************/
void MSelList::deselectAllItems(void)
{
    LIST_ACT *pi;

    pi = mslist->getFirstItem();
    mslist->freeze();
    while (pi)
    {
	mslist->deselectItem(pi->item);
	pi = mslist->getNextItem();
    }
    mslist->thaw();
}

/***************************************************************
 *	This function shows the focused item text, position
 *	and user data
 ***************************************************************/
void MSelList::onSelection(LIST_SEL * la)
{
    static int nn;
    char str[128];

    if (la->pos >= 0)
	sprintf(str, " %c Focused row # %ld <%s> user data: %ld",
		(nn++) & 1 ? '-' : '|',
		la->pos, la->item, (long) la->u_data);
    else
	strcpy(str, "No focused item in the list !");
    label->setText(str);
}

MSelList::MSelList(void)
{
    CmForm *form, *form0, *form1;
    CmPushButton *pb;
    CmSFile *sfile;
    int i;
    char str[512];

    shell = new CmShell("Multi Selection List", SF_MODAL);

    form0 = new CmColForm(shell);
    form = new CmRowForm(form0);
    form1 = new CmColForm(form);

    mslist = new CmSList(form1, FIXED_MEDIUM, 16, 10, 12);
    mslist->setSelectionCallback(this, (LISTSEL_CB)&MSelList::onSelection);
    mslist->enableMultiSelection();
    mslist->setHead("Nome    Cognome ");
    mslist->setColor(seagreen, white);

    slist = new CmSList(form1, FIXED_MEDIUM, 16, 10, 10);
    slist->setColor(cadetblue, white);
    slist->setSortCallback(strcmp);

    form = new CmColForm(form);
    pb = new CmPushButton(form, "Move", TIMES_N_FONT);
    pb->setCallback(this, (VOID_CB)&MSelList::moveItems);
    pb = new CmPushButton(form, "Select All", TIMES_N_FONT);
    pb->setCallback(this, (VOID_CB)&MSelList::selectAllItems);
    pb = new CmPushButton(form, "Deselect All", TIMES_N_FONT);
    pb->setCallback(this, (VOID_CB)&MSelList::deselectAllItems);
/*
 * Insert 50 items in the source list
 */
    for (i = 0; i < 50; i++)
    {
	sprintf(str, "nome%03d cogn%04d", i, i);
	mslist->addItem(str, (void *) i);
    }
/*
 * Create a SFile to view this source file
 */
    sfile = new CmSFile(form0, __FILE__, FIXED_MEDIUM, 15, 60);
    sfile->setColor(darkblue, white);

    label = new CmLabel(shell, "", FIXED_MEDIUM);

    pb = new CmPushButton(shell, "Close", TIMES_MEDIUM);
    pb->setCallback(this, (VOID_CB)&MSelList::closeDialog);

    shell->realize();
}

/*****************************************************
 *	This function opens the dialog when the
 *	corresponding menu item is selected
 *****************************************************/
void 
MSelListDemo(void)
{
	new MSelList;
}
