/********************************************************************************************
	Clean OS Windows library module version 1.2.1.
	This module is part of the Clean Object I/O library, version 1.2.1,
	for the Windows platform.
********************************************************************************************/

/********************************************************************************************
	About this module:
	Routines related to menu handling.
********************************************************************************************/
#include "cCrossCallMenus_121.h"
#include "cAcceleratorTable_121.h"
#include "cCrossCall_121.h"


/*	Cross call procedure implementations.
	Eval<nr> corresponds with a CrossCallEntry generated by NewCrossCallEntry (nr,Eval<nr>).
*/

/*	Remove a shortkey from a framewindow shortkey table. */
void EvalCcRqREMOVEMENUSHORTKEY (CrossCallInfo *pcci)	/* frameptr, cmd; no result. */
{
	ProcessShortcutTable table;
	HWND frameptr;
	int cmd;

	frameptr = (HWND) pcci->p1;
	cmd      = pcci->p2;

	table    = (ProcessShortcutTable) GetWindowLong (frameptr,0);
	table    = RemoveProcessShortcut (cmd, table);
	SetWindowLong (frameptr, 0, (long)table);

	if (gAcceleratorTableIsUpToDate)
	{
		gAcceleratorTableIsUpToDate = !(ghActiveFrameWindow==frameptr);
	}

	MakeReturn0Cci (pcci);
}

void EvalCcRqMODIFYMENUITEM (CrossCallInfo *pcci)	/* hitem, hmenu, textptr; no result.	*/
{
	MENUITEMINFO info;

	info.cbSize        = (UINT) sizeof (MENUITEMINFO);
	info.fMask         = MIIM_TYPE;
	info.fType         = MFT_STRING;
	info.fState        = (UINT) 0;
	info.wID           = (UINT) pcci->p1;
	info.hSubMenu      = (HMENU) NULL;
	info.hbmpChecked   = NULL;
	info.hbmpUnchecked = NULL;
	info.dwItemData    = (DWORD) 0;
	info.dwTypeData    = (LPTSTR) pcci->p3;//correcttext;
	info.cch           = strlen ((LPTSTR)pcci->p3);//(correcttext);

	SetMenuItemInfo ((HMENU) pcci->p2, (UINT) pcci->p1, FALSE, &info);

	MakeReturn0Cci (pcci);
}

void EvalCcRqINSERTMENUITEM (CrossCallInfo *pcci)		/* on/off, hmenu, textptr, marked, pos;    HITEM result. */
{
	UINT flags;
	ProcessShortcutTable table;
	HITEM hitem;
	HWND frameptr;
	char key;
	LPTSTR  title;
	LPCTSTR text;

	frameptr = (HWND) pcci->p2;
	key = (char) pcci->p5;

	flags = MF_BYPOSITION | MF_STRING;

	if (pcci->p1 & 2)
	{
		flags |= MF_ENABLED;
	}
	else
	{
		flags |= MF_GRAYED;
	}

	if (pcci->p1 & 1)
	{
		flags |= MF_CHECKED;
	}
	else
	{
		flags |= MF_UNCHECKED;
	}

	text  = (LPCTSTR) pcci->p4;
	title = text;
	if (key)
	{
		title = malloc(strlen(text)+8);
		if (title)
			sprintf(title, "%s\tCtrl+%c", text, key);
		else
			title = text;
	}

	hitem = NextMenuItemID ();		/*	PA: replaced NextItemHandle by NextMenuItemID. */

	InsertMenu ((HMENU) pcci->p3,			/* hMenu	  */
				(UINT) pcci->p6,			/* position   */
				flags,						/* Flags	  */
				(UINT) hitem,				/* id		  */
				title
			);

	if (title != text)
		free(title);

	table = (ProcessShortcutTable) GetWindowLong (frameptr,0);
	table = AddProcessShortcut (key, hitem, table);
	SetWindowLong (frameptr, 0, (long)table);
	if (gAcceleratorTableIsUpToDate)
	{
		gAcceleratorTableIsUpToDate = !(ghActiveFrameWindow==frameptr);
	}

	MakeReturn1Cci (pcci, hitem);
}

void EvalCcRqITEMENABLE (CrossCallInfo *pcci)	/* parent, HITEM, onoff; no result.  */
{
	UINT greystate;

	if (pcci->p3)
	{
		greystate = MF_ENABLED;
	}
	else
	{
		greystate = MF_GRAYED;
	}
	EnableMenuItem ((HMENU) pcci->p1,			/* parent menu	*/
					(UINT) pcci->p2,			/* menu item id */
					MF_BYCOMMAND | greystate);	/* flags		*/
	MakeReturn0Cci (pcci);
}

/*	Remove a menu */
void EvalCcRqDELETEMENU (CrossCallInfo *pcci)			/* HMENU, HITEM; no result. */
{
	DeleteMenu ((HMENU) pcci->p1,		/* parent menu  */
				(UINT) pcci->p2,		/* menu item id */
				MF_BYCOMMAND);
	DestroyMenu ((HMENU) pcci->p2);
	MakeReturn0Cci (pcci);
}

void EvalCcRqREMOVEMENUITEM (CrossCallInfo *pcci)		/* menu, HITEM; no result. */
{
	RemoveMenu ((HMENU) pcci->p1,
				(UINT) pcci->p2,
				MF_BYCOMMAND);
	MakeReturn0Cci (pcci);
}

void EvalCcRqINSERTSEPARATOR (CrossCallInfo *pcci)		/* hmenu, pos no result. */
{
	InsertMenu ((HMENU) pcci->p1,				/* hMenu				 */
				(UINT) pcci->p2,				/* position 			 */
				MF_BYPOSITION | MF_SEPARATOR,	/* Flags				 */
				0,								/* no id for separator	 */
				NULL);							/* no text for separator */
	MakeReturn1Cci (pcci, 0);
}

void EvalCcRqMODIFYMENU (CrossCallInfo *pcci)	/* hitem, hmenu, textptr; no result.	*/
{
	MENUITEMINFO info;

	info.cbSize        = (UINT) sizeof (MENUITEMINFO);
	info.fMask         = MIIM_TYPE;
	info.fType         = MFT_STRING;
	info.fState        = (UINT) 0;
	info.wID           = (UINT) pcci->p1;
	info.hSubMenu      = (HMENU) pcci->p2;
	info.hbmpChecked   = NULL;
	info.hbmpUnchecked = NULL;
	info.dwItemData    = (DWORD) 0;
	info.dwTypeData    = (LPTSTR) pcci->p3;
	info.cch           = strlen ((LPTSTR)pcci->p3);

	SetMenuItemInfo ((HMENU) pcci->p2, (UINT) pcci->p1, FALSE, &info);

	MakeReturn0Cci (pcci);
}

/*	Insert a menu into the menu bar. */
void EvalCcRqINSERTMENU (CrossCallInfo *pcci)	/* on/off, hmenu, textptr, hsubmenu, pos; no result */
{
	HMENU hMenu;
	UINT graystate;

	if (pcci->p1)
	{
		graystate = MF_ENABLED;
	}
	else
	{
		graystate = MF_GRAYED;
	}

	hMenu = CreatePopupMenu ();
	InsertMenu ((HMENU) pcci->p2,						/* hMenu		*/
				(UINT) pcci->p4,						/* position		*/
				MF_BYPOSITION | MF_POPUP | graystate,	/* flags		*/
				(UINT) hMenu,							/* hSubMenu		*/
				(LPCTSTR) pcci->p3
		);
	MakeReturn1Cci (pcci, (int) hMenu);
}

void EvalCcRqMENUENABLE (CrossCallInfo *pcci)	/* parent, zero based position of menu, onoff; no result. */
{
	UINT greystate;
	HMENU hParentMenu, hSubMenu;
	int i;

	if (pcci->p3)
	{
		greystate = MF_ENABLED;
	}
	else
	{
		greystate = MF_GRAYED;
	}

	hParentMenu = (HMENU) pcci->p1;
	hSubMenu = (HMENU) pcci->p2;

	for (i = GetMenuItemCount(hParentMenu)-1; i >= 0; i--)
	{
		MENUITEMINFO mii;
		memset(&mii, 0, sizeof(mii));
		mii.cbSize = sizeof(mii);
		mii.fMask  = MIIM_SUBMENU;
		if (GetMenuItemInfo(hParentMenu, i, TRUE, &mii) && mii.hSubMenu == hSubMenu)
		{
			EnableMenuItem (hParentMenu,i,MF_BYPOSITION | greystate);
		}
	};

	MakeReturn0Cci (pcci);
}

void EvalCcRqDRAWMBAR (CrossCallInfo *pcci)		/* framePtr, clientPtr; no result. */
{
	HWND framePtr  = (HWND) pcci->p1;
	HWND clientPtr = (HWND) pcci->p2;

	if (clientPtr != 0)
		SendMessage (clientPtr,WM_MDIREFRESHMENU,(WPARAM)0,(LPARAM)0);

	DrawMenuBar (framePtr);
	MakeReturn0Cci (pcci);
}

/*	Track pop up menu. */
void EvalCcRqTRACKPOPMENU (CrossCallInfo *pcci)	/* popupmenu,framePtr; BOOL result. */
{
	HMENU popupmenu;
	HWND  framePtr;
	UINT  flags;
	POINT mousePos;
	BOOL  ok;

	popupmenu = (HMENU) pcci->p1;
	framePtr  = (HWND)  pcci->p2;
	flags     = TPM_CENTERALIGN | TPM_RIGHTBUTTON;
	GetCursorPos (&mousePos);

	ok = TrackPopupMenu (popupmenu,flags,mousePos.x,mousePos.y,0,framePtr,NULL);

	MakeReturn1Cci (pcci,(int)ok);
}

void EvalCcRqCREATEPOPMENU (CrossCallInfo *pcci) /* no params; MENU result.   */
{
	MakeReturn1Cci (pcci, (int) CreatePopupMenu ());
}

void EvalCcRqCHECKMENUITEM (CrossCallInfo *pcci) /* menu, HITEM, on/off; no result.	*/
{
	UINT check;
	if (pcci->p3)
	{
		check = MF_CHECKED;
	}
	else
	{
		check = MF_UNCHECKED;
	}
	CheckMenuItem ((HMENU) pcci->p1, (UINT) pcci->p2, MF_BYCOMMAND | check);
	MakeReturn0Cci (pcci);
}


/*	Install the cross call procedures in the gCrossCallProcedureTable of cCrossCall_121.
*/
void InstallCrossCallMenus ()
{
	CrossCallProcedureTable newTable;

	newTable = EmptyCrossCallProcedureTable ();
	AddCrossCallEntry (newTable, CcRqREMOVEMENUSHORTKEY, EvalCcRqREMOVEMENUSHORTKEY);
	AddCrossCallEntry (newTable, CcRqMODIFYMENUITEM,     EvalCcRqMODIFYMENUITEM);
	AddCrossCallEntry (newTable, CcRqINSERTMENUITEM,     EvalCcRqINSERTMENUITEM);
	AddCrossCallEntry (newTable, CcRqITEMENABLE,         EvalCcRqITEMENABLE);
	AddCrossCallEntry (newTable, CcRqDELETEMENU,         EvalCcRqDELETEMENU);
	AddCrossCallEntry (newTable, CcRqREMOVEMENUITEM,     EvalCcRqREMOVEMENUITEM);
	AddCrossCallEntry (newTable, CcRqINSERTSEPARATOR,    EvalCcRqINSERTSEPARATOR);
	AddCrossCallEntry (newTable, CcRqMODIFYMENU,         EvalCcRqMODIFYMENU);
	AddCrossCallEntry (newTable, CcRqINSERTMENU,         EvalCcRqINSERTMENU);
	AddCrossCallEntry (newTable, CcRqMENUENABLE,         EvalCcRqMENUENABLE);
	AddCrossCallEntry (newTable, CcRqDRAWMBAR,           EvalCcRqDRAWMBAR);
	AddCrossCallEntry (newTable, CcRqTRACKPOPMENU,       EvalCcRqTRACKPOPMENU);
	AddCrossCallEntry (newTable, CcRqCREATEPOPMENU,      EvalCcRqCREATEPOPMENU);
	AddCrossCallEntry (newTable, CcRqCHECKMENUITEM,      EvalCcRqCHECKMENUITEM);
	AddCrossCallEntries (gCrossCallProcedureTable, newTable);
}
