{***********************************************************************}
{									}
{ __ItemMnu   Add or replace one menu item in a list of items.		}
{									}
{ function  __ItemMnu( MenuPtr : _MenuPtr;				}
{		      Col,Row,						}
{		      HiChPos,						}
{		      HiChFore, 					}
{		      HiChBack : byte;					}
{		       Protect : boolean;				}
{		      MenuItem : _MenuString) : _ItemPtr;		}
{									}
{	      MenuPtr	Pointer to the menu descriptor returned by	}
{			__MakeMnu when the menu was constructed.	}
{	      Col,Row	Item position within the window 		}
{	      HiChPos	Position of the highlighted character in	}
{			the string MenuItem				}
{	      HiChFore	Attribute of the highlighted character		}
{	      HiChBack							}
{	      Protect	Availability of the item for selection		}
{	      MenuItem	The text of the item				}
{									}
{ Description __ItemMnu adds or replaces one _Item in a menu		}
{	      linked list of items, then returns a pointer to the	}
{	      _Item.							}
{									}
{	      Every menu has a doubly-linked list of _Item records	}
{	      'attached' to it by the pointer _MItemsPtr, which points	}
{	      to the first item in the list.  The list is created	}
{	      with repeated calls to this function.  An item for a	}
{	      particular menu is uniquely defined by its column and	}
{	      row (_ColRow) coordinates.  When __ItemMnu finds an	}
{	      item with a matching column and row, it replaces the	}
{	      existing item, otherwise it adds a new item.		}
{									}
{	      This function returns NIL if an error is encountered.	}
{									}
{	      On error _MenuError may be set to:  _InvalidWindow	}
{						  _InvalidMenu		}
{						  _InvalidItem		}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc. 1987		}
{_______________________________________________________________________}

function __ItemMnu( MenuPtr : _MenuPtr;
		    Col,Row,
		    HiChPos,
		   HiChFore,
		   HiChBack : byte;
		    Protect : boolean;
		   MenuItem : _MenuString) : _ItemPtr;

  var
    TempPtr,PrevPtr : _ItemPtr;
    Found	    : boolean;
    ColRow	    : word;

  begin {__ItemMnu}

    __ItemMnu := NIL;

    { First determine that a valid menu and window are specified.	}

    if (not ValidSig(MenuPtr,MENUSIG_)) then
       Exit;
    if (not ValidWindow(MenuPtr^._MWinPtr)) then
       begin
	 SetMenuError(_InvalidWindow);
	 Exit
       end;

    { Check the item position and the text string.			}

    if ((Col < 1) or (Row < 1) or (MenuItem = '')) then
       begin
	 SetMenuError(_InvalidItem);
	 Exit
       end;

    { Find if there is another item already defined at the position.	}

    Hi(ColRow) := Col;
    Lo(ColRow) := Row;
    Found      := FALSE;
    TempPtr    := MenuPtr^._MItemsPtr;
    PrevPtr    := TempPtr;
    while ((TempPtr <> NIL) and (not Found)) do
      if (not ValidSig(TempPtr,ITEMSIG_)) then
	 Exit
      else
	 if (TempPtr^._ColRow = ColRow) then
	    Found := TRUE
	 else
	   begin
	     PrevPtr := TempPtr;
	     TempPtr := TempPtr^._NextItem;
	  end;

    if (Found) then		       { Replace an existing item	}
       with TempPtr^ do
	 begin
	   FreeMem(_ItemStrPtr,_Len + 1);
	   _Len        := length(MenuItem);
	   _HiChPos    := HiChPos mod (_Len + 1);
	   _HiChFore   := HiChFore mod 16;
	   _HiChBack   := HiChBack mod 16;
	   _Protect    := Protect;
	   GetMem(_ItemStrPtr,_Len + 1);
	   _MenuString(_ItemStrPtr^) := MenuItem;
	   __ItemMnu := TempPtr
	 end
    else			       { Add an item			}
       begin
	 GetMem(TempPtr,sizeof(_Item));
	 with TempPtr^ do
	   begin
	     _ISig     := 'I';
	     _ColRow   := ColRow;
	     _Len      := length(MenuItem);
	     _Active   := TRUE;
	     _HiChPos  := HiChPos mod (_Len + 1);
	     _HiChFore := HiChFore mod 16;
	     _HiChBack := HiChBack mod 16;
	     _Protect  := Protect;
	     _LDescPtr := NIL;
	     GetMem(_ItemStrPtr,_Len + 1);
	     _MenuString(_ItemStrPtr^) := MenuItem;
	     _NextItem	 := NIL;
				       { Adjust the pointer in the list }
	     if (MenuPtr^._MItemsPtr = NIL) then
		begin
		  MenuPtr^._MItemsPtr := TempPtr;
		  _PrevItem := NIL
		end
	     else
		begin
		  PrevPtr^._NextItem := TempPtr;
		  _PrevItem := PrevPtr
		end;
	     MenuPtr^._MITailPtr := TempPtr;
	     __ItemMnu := TempPtr
	   end
       end

  end;	{__ItemMnu}
