/* elxprocs.c: This file contains procedures which access the dialog
* information which the EB system needs.
*
* "#include" this file in an application module, after #include'ing either:
*	ELXDEFS.H and ELXINFO.H		(generated by the MAKEELX utility)
*		or
*	ELXDEFS0.H and ELXINFO0.H	(stubs for temporary use)
*
*/


/* %%Function:GetNameElk %%Owner:bradch */
VOID GetNameElk(elk, st)
/* Accepts an ELK; produces the name associated with the ELK.
*/
ELK elk;
unsigned char *st;
{
	char far *lst;

	if (elk >= elkAppMac)
		{
		extern struct STTB ** vhsttbElkUser;
		char * stT;

		/* user defined keyword, load from vhsttbElkUser */
		elk -= elkAppMac;
		Assert(vhsttbElkUser != hNil);
		Assert(elk < (*vhsttbElkUser)->ibstMac);
		BLTB(stT = PstFromSttb(vhsttbElkUser, elk), st, *stT + 1);
		}
	else
		{
		lst = &rgchElkNames[rgichName[mpelkistName[elk]]];
		BLTBX(lst, (char far *)st, lst[0] + 1);
		}
}


/* %%Function:ElkLookupSt %%Owner:bradch */
NATIVE ELX ElkLookupSt(st)
/* Accepts a near pointer to a string; returns the ELK named by the string,
* or elxNil if there is no such ELK.
*
* The current lookup algorithm is a binary search.  If desired, this may
* change to a more time-efficient algorithm.
*
* Made native for optimizing macro tokenization.
*/
unsigned char *st;
{
	int istFirst, istLast;

	/* Look for the name in the hash table, or the position where it
		* should be.
		*/
	istFirst = 0;
	istLast = ibstElkAppMac;
	while (istFirst < istLast)
		{
		int istMid = (istFirst + istLast) / 2;
		int wDiff;

		wDiff = WCmpiStLst(st, &rgchElkNames[rgichName[istMid]]);

		if (wDiff < 0)
			istLast = istMid;	/* table entry too high */
		else  if (wDiff > 0)
			istFirst = istMid + 1;	/* table entry too low */
		else
			{
			return ElkFromIstElk(istMid); /* found */
			}
		}

	return elkNil;		/* not found */
}


/* %%Function:ElkFromIstElk %%Owner:bradch */
ElkFromIstElk(istElk)
int istElk;
{
	int far * pist;

	for (pist = mpelkistName; *pist != istElk; pist += 1)
		/*Assert(pist < (char *) mpelkistName + sizeof (mpelkistName))*/;

	return (int) (pist - mpelkistName);
}


/* %%Function:HidFromIeldi %%Owner:bradch */
WORD HidFromIeldi(ieldi)
int ieldi;
{
	return rgeldi[ieldi].hid;
}


/* %%Function:CbGetInfoIeldi %%Owner:bradch */
WORD CbGetInfoIeldi(ieldi, hpeldi)
/* Locates an ELDI structure and returns its size.  If "hpeldi" != hpNil,
* copies the ELDI there.
*/
int ieldi;
ELDI huge *hpeldi;
{
	extern ELDI ** vheldi;
	ELDI far * lpeldi;
	unsigned cb;

	lpeldi = (ieldi == ieldiIDDUsrDlg) ?
			(ELDI far *) *vheldi : &rgeldi[ieldi];

	cb = CbEldiOfCelfd(lpeldi->celfd);
	if (hpeldi != hpNil)
		{
		BLTBX(lpeldi, LpOfHp(hpeldi), cb);
		}

	return cb;
}


/* ---------------------------------------------------------------------- */
/* Utility functions
/* ---------------------------------------------------------------------- */

/* %%Function:WCmpiStLst %%Owner:bradch */
int WCmpiStLst(st1, lst2)
/* Compares two counted character strings.  This function must be in the same
* module as "ElxLookupSt()" (so a code-space pointer can be passed).
*/
unsigned char *st1, far *lst2;
{
	unsigned cch1, cch2;

	cch1 = *st1++;
	cch2 = *lst2++;
	while (cch1 != 0 && cch2 != 0)
		{
		unsigned char ch1 = *st1++, ch2 = *lst2++;

		if (ch1 != ch2)
			{
			ch1 |= 0x20;
			ch2 |= 0x20;
			if (!(ch1 == ch2 && ch1 >= 'a' && ch1 <= 'z'))
				return ch1 - ch2;
			}
		cch1--;
		cch2--;
		}
	return cch1 - cch2;
}


/* FUTURE: mergeelx needs to spit this out */
#ifdef DEBUG
#define ieldiMax (ieldiIDDUseCThreeVersions + 1)
#else
#define ieldiMax (ieldiIDDUsrDlg + 1)
#endif


/* FUTURE: This sucks!  Should be direct mapping from hid to ieldi! */
/* %%Function:IeldiFromHid %%Owner:bradch */
int IeldiFromHid(hid)
WORD hid;
{
	int ieldi;

	for (ieldi = 0; ieldi < ieldiMax; ++ieldi)
		{
		if (rgeldi[ieldi].hid == hid)
			{
			return ieldi;
			}
		}

	return iNil;
}


