/*
 *    File blklist.c
 *      Block list is a virtual list handled in blocks.
 *      The number of items must be known.
 */

#include <stdio.h>

#include "mgui.h"

extern void CloseDialogCB(MOBJECT p, void *s, void *v);
extern void ScrolledListCB(MOBJECT p, LIST_ACT * la, void *v);

extern MTColor black, white, darkblue, cadetblue, seagreen;

/**************************************************
*	This callback is called by the Object when
*	it needs data for drawing rows in the
*	virtual list. The application must 'sprintf'
*	row data in the linked list passed by the
*	Object
**************************************************/
static void 
NewBlockCB(MOBJECT obj, SBL_NEW_BLOCK * pnb, void *data)
{
    int i;
    long ll, off;
    char c1, c2, c3, c4, c5, c6;
    XL_ITEM *pd = pnb->pi;

    off = pnb->offset;
    for (i = 0; i < pnb->nr && pd; i++)
    {
	ll = off;
	c6 = 'a' + (char) (ll % 26);
	ll /= 26;
	c5 = 'a' + (char) (ll % 26);
	ll /= 26;
	c4 = 'a' + (char) (ll % 26);
	ll /= 26;
	c3 = 'a' + (char) (ll % 26);
	ll /= 26;
	c2 = 'a' + (char) (ll % 26);
	ll /= 26;
	c1 = 'a' + (char) (ll % 26);
	sprintf(pd->data, "%c%c%c%c%c%c %09ld %09ld", c1, c2, c3, c4, c5, c6, off, pnb->offset);
	pd->u_data = (void *) off++;
	pd = pd->next;
    }
}

/**************************************************
*	This callback is called by the Object when
*	it needs to know the position (if any) of
*	an item in the list.
**************************************************/
static void 
NewPosCB(MOBJECT obj, SBL_ITEM_SEEK * pis, void *data)
{
    int i;
    long ll;
    char *str = pis->sub_item;

    while (*str == ' ')
	str++;
    ll = 0L;
    for (i = 0; i < 6; i++)
    {
	ll *= 26;
	if (*str)
	{
	    ll += *str - 'a';
	    str++;
	}
    }
    pis->pos = (*str ? -1L : ll);
}

/*****************************************************
 *	This callback opens the dialog when the
 *	corresponding menu item is selected
 *****************************************************/
void 
BlockListCB(MOBJECT o, void *o_data, void *a_data)
{
    MOBJECT pbutton, shell, form0, form;
    MOBJECT blklist, sfile;
    char str[512];
    long ll;

    shell = MCreateShell("Block List", SF_MODAL);

    form0 = MCreateColForm(shell);

    form = MCreateRowForm(form0);
	MObjectSetBackgroundImageFile(form, "tile4.bmp", BI_TILED);
/*
 * The virtual list will contain all possible strings
 * constructed with six alpha lower case characters (26^6)
 */
    ll = 26L * 26 * 26L * 26L * 26 * 26L;
    sprintf(str, "%ld elements", ll);
    MCreateLabel(form, str, FIXED_MEDIUM);

    blklist = MCreateSListClip(form, NewBlockCB, 0L, NewPosCB, 0L, FIXED_MEDIUM, 12, 16, 30, ll);
    MSListSetCallback(blklist, ScrolledListCB, (void *) blklist);
    MObjectSetColor(blklist, cadetblue, black);
    MSBLSetHead(blklist, "Value  Position  Block");
    MSBLHeadSetColor(blklist, seagreen, white);
	MObjectSetTransparency(blklist, 255);

    sfile = MCreateSFile(form0, __FILE__, FIXED_MEDIUM, 15, 58);
    MObjectSetColor(sfile, darkblue, white);

    pbutton = MCreatePButton(shell, "Close", TIMES_MEDIUM);
    MPButtonSetCallback(pbutton, CloseDialogCB, 0L);

    MShellRealize(shell);
}
