/*
 * sample 14
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "mgui.h"

#define MAX_POS	26L*26L*26L*26L*26L*26L

static long skip_pos = MAX_POS - 10;

void ExitCB(MOBJECT obj, void *a, void *b)
{
	obj = MObjectShell(obj);
	MShellUnrealize(obj);
	MShellDestroy(obj);
	MGUITerm();
	exit(0);
}

static char *PosToString(long ll)
{
	static char buff[8];
	int i;

	i = 6;
	buff[i] = '\0';
	for (; i-- > 0; ll/= 26)
		buff[i] = 'a' + ll%26;

	return buff;
}

static long StringToPos(char *str)
{
	long ll;
	int i;

	ll = 0L;
	for (i=0; i<6; i++) {
		ll *= 26;
		if (*str) {
			if (!islower(*str))
				return -1L;
			ll += *str - 'a';
			str++;
		}
	}
	return (*str == '\0' ? ll : -1L);
}

static void SkipBlockCB(MOBJECT obj, SBL_NEW_BLOCK *pnb, void *data)
{
	int i;
	long off=skip_pos;
	XL_ITEM *pd = pnb->pi;
	long max = MAX_POS;

	switch (pnb->from) {
		case SEEK_SET:
			off = pnb->offset;
			break;
		case SEEK_CUR:
			off += pnb->offset;
			if (off < 0L) {
				pnb->nr = -1;
				return;
			}
			else if (off >= max) {
				pnb->nr = -1;
				return;
			}
			break;
		case SEEK_END:
			off = pnb->offset + max;
			break;
		default:
			off = 0L;
	}
	for (i=0; i < pnb->nr && pd && off < max; i++) {
		sprintf(pd->data, "%s %09ld %09ld", PosToString(off), off, pnb->offset);
		pd->u_data = (void *)off++;
		pd = pd->next;
	}
	pnb->nr = i;
/*
 * skip_pos points to the last supplied item
 */
	skip_pos = off-1;
}

static void SkipSearchCB(MOBJECT obj, SBL_ITEM_SEEK *pis, void *data)
{
	long ll;
	char *str = pis->sub_item;

        if ((ll = StringToPos(str)) != -1L) {
		pis->pos = 0;
		skip_pos = ll;
	}
}

void MGUIMain(int argc, char **argv)
{
	MTColor black, white, cadetblue, seagreen;
	MOBJECT pbutton, shell, form, slist;
	char str[512];

	black = MBlackColor();
	white = MWhiteColor();
	cadetblue = MAllocColor(0x60, 0x85, 0x95);
	seagreen = MAllocColor(0x70, 0xa5, 0xa0);

	shell = MCreateShell("Sample 12", SF_MODAL);

	form = MCreateRowForm(shell);

	sprintf(str, "%ld elements", MAX_POS);
	MCreateLabel(form, str, DEFAULT_FONT);

	slist = MCreateSListSkip(form, SkipBlockCB, NULL, SkipSearchCB, NULL, DEFAULT_FONT, 12, 16, 30);
	MObjectSetColor(slist, cadetblue, black);
	MSBLSetHead(slist, "Value  Position  Offset");
	MSBLHeadSetColor(slist, seagreen, white);

	pbutton = MCreatePButton(shell, "Close", TIMES_L_FONT);
	MPButtonSetCallback(pbutton, ExitCB, NULL);

	MShellRealize(shell);
	MMainLoop();
}

