package Claw.Menus.Popup is

    -- This package contains popup menus (also known as Context menus or
    -- Shortcut menus).

    type Popup_Menu_Type is new Claw.Menus.Basic_Menu_Type with private;

    procedure Load (Popup_Menu : in out Popup_Menu_Type;
		    Menu_Name : in String);
	-- Load Menu_Name from a resource.
	-- The resource should have a single submenu, which will
	-- be used for the popup menu.
	-- Raises:
	--	Windows_Error if Windows reports an error.
	--	Already_Valid_Error if Popup_Menu is already valid.
	--	Not_Valid_Error if the first item in Menu_Name is not a submenu.

    procedure Create (Popup_Menu : in out Popup_Menu_Type);
	-- Creates an empty Popup_Menu.
	-- Raises:
	--	Windows_Error if Windows reports an error.
	--	Already_Valid_Error if Popup_Menu is already valid.


    -- Use of Popup menus.

    type Button_Track_Type is (Left_Button, Right_Button);
    type Horizontal_Alignment_Type is (Left_Align, Center_Align, Right_Align);
    type Vertical_Alignment_Type is (Top_Align, Center_Align, Bottom_Align);
    type Exclusion_Alignment_Type is (Horizontal, Vertical);

    procedure Use_Popup_Menu (Menu : in out Popup_Menu_Type;
			      Window : in out Claw.Root_Window_Type'Class;
			      Screen_Location : in Claw.Point_Type;
			      Mouse_Button : in Button_Track_Type
				  := Right_Button;  -- Windows standard
			      Ignore_Already_Open_Error : in Boolean := False;
			      Horizontal_Alignment : in Horizontal_Alignment_Type
				  := Left_Align;
			      Vertical_Alignment : in Vertical_Alignment_Type
				  := Top_Align);
	-- Use a popup menu (as a shortcut or context menu).
	-- Mouse_Button is the button used to select from the menu (it should
	-- be the same as the button used to popup the menu).
	-- Screen_Location is the location to show the menu; if this routine
	-- is called from a When_Mouse_Down routine, Claw.Window_Operations.Client_to_Screen
	-- should be called to convert the coordinates.
	-- Alignment specifies where the menu appears relative to the point.
	-- This routine does not return until the user makes a selection
	-- or the menu is dismissed by moving the mouse outside of it.
	-- Then the appropriate When_Command routine(s) are called.
	-- If Ignore_Already_Open_Error is true, this routine will do nothing if
	-- a Popup or Submenu is open.  Otherwise, an exception will be raised.
	-- Raises:
	--	Not_Valid_Error if Menu or Window are not valid.
	--	Already_Valid_Error if a Popup menu (or Menu Bar Submenu)
	--	    are already open and Ignore_Already_Open_Error is False.
	--	Windows_Error if Windows reports an error.
	--	Not_Supported_Error if Vertical_Alignment /= Top_Align
	--		on Windows 3.x.

    procedure Use_Popup_Menu (Menu : in out Popup_Menu_Type;
			      Window : in out Claw.Root_Window_Type'Class;
			      Screen_Location : in Claw.Point_Type;
			      Mouse_Button : in Button_Track_Type
				  := Right_Button;  -- Windows standard
			      Ignore_Already_Open_Error : in Boolean := False;
			      Horizontal_Alignment : in Horizontal_Alignment_Type
				  := Left_Align;
			      Vertical_Alignment : in Vertical_Alignment_Type
				  := Top_Align;
			      Live_Area: in Claw.Rectangle_Type);
	-- Use a popup menu (as a shortcut or context menu).
	-- Mouse_Button is the button used to select from the menu (it should
	-- be the same as the button used to popup the menu).
	-- Screen_Location is the location to show the menu; if this routine
	-- is called from a When_Mouse_Down routine, Claw.Window_Operations.Client_to_Screen
	-- should be called to convert the coordinates.
	-- Alignment specifies where the menu appears relative to the point.
	-- This routine does not return until the user makes a selection
	-- or the menu is dismissed by moving the mouse outside of Live_Area.
	-- Then the appropriate When_Command routine(s) are called.
	-- If Ignore_Already_Open_Error is true, this routine will do nothing if
	-- a Popup or Submenu is open.  Otherwise, an exception will be raised.
	-- Raises:
	--	Not_Valid_Error if Menu or Window are not valid.
	--	Already_Valid_Error if a Popup menu (or Menu Bar Submenu)
	--	    are already open and Ignore_Already_Open_Error is False.
	--	Windows_Error if Windows reports an error.
	--	Not_Supported_Error if Vertical_Alignment /= Top_Align
	--		on Windows 3.x.

    procedure Use_Popup_Menu (Menu : in out Popup_Menu_Type;
			      Window : in out Claw.Root_Window_Type'Class;
			      Screen_Location : in Claw.Point_Type;
			      Mouse_Button : in Button_Track_Type
				  := Right_Button;  -- Windows standard
			      Ignore_Already_Open_Error : in Boolean := False;
			      Horizontal_Alignment : in Horizontal_Alignment_Type
				  := Left_Align;
			      Vertical_Alignment : in Vertical_Alignment_Type
				  := Top_Align;
			      Most_Important : in Exclusion_Alignment_Type := Horizontal;
			      Excluded_Area: in Claw.Rectangle_Type);
	-- Use a popup menu (as a shortcut or context menu).
	-- Mouse_Button is the button used to select from the menu (it should
	-- be the same as the button used to popup the menu).
	-- Screen_Location is the location to show the menu; if this routine
	-- is called from a When_Mouse_Down routine, Claw.Window_Operations.Client_to_Screen
	-- should be called to convert the coordinates.
	-- The menu will not be shown within Excluded_Area.
	-- Alignment specifies where the menu appears relative to the point.
	-- Most_Important specifies which alignment (Horizontal or Vertical)
	-- is used if the menu will overlap the excluded area.
	-- This routine does not return until the user makes a selection
	-- or the menu is dismissed by moving the mouse outside of it.
	-- Then the appropriate When_Command routine(s) are called.
	-- If Ignore_Already_Open_Error is true, this routine will do nothing if
	-- a Popup or Submenu is open.  Otherwise, an exception will be raised.
	-- Raises:
	--	Not_Valid_Error if Menu or Window are not valid.
	--	Already_Valid_Error if a Popup menu (or Menu Bar Submenu)
	--	    are already open and Ignore_Already_Open_Error is False.
	--	Not_Supported_Error if this is called on Windows 3.x.
	--	Windows_Error if Windows reports an error.

private

    type Popup_Menu_Type is new Claw.Menus.Basic_Menu_Type with record
	Original_Handle : Claw.Win32.HMenu := Claw.Win32.Null_HMenu;
	    -- If Popup was created via Load, this handle is that of the
	    -- actual loaded menu.
    end record;

    -- We need to override these:
    procedure Finalize (Menu : in out Popup_Menu_Type);
	-- Finalize Menu (for Controlled types; this routine need not
	-- be called explicitly, call Destroy instead.).

    procedure Destroy (Menu : in out Popup_Menu_Type);
	-- Destroy Menu.
	-- Raises:
	--	Not_Valid_Error if Menu is not valid.

end Claw.Menus.Popup;