/*----------------------------------------------------------------------*
    MenuMain.c version 3.0 - © Copyright 1991 Jaba Development

    Author : Jan van den Baard
    Purpose: The main menu editing loop.
 *----------------------------------------------------------------------*/
extern struct Window        *MainWindow;
extern struct Screen        *MainScreen;
extern struct RastPort      *MainRP;
extern struct Menu           MainMenuStrip[];
extern struct Menu           ItemMenuStrip[];
extern struct Menu           SubMenuStrip[], Titles[];
extern struct MenuItem       TheItem[], SubItem[], MainItem[];
extern struct MemoryChain    Memory;
extern struct MyMenuItem     dummy;
extern struct MyMenu        *MenuStrip, *ParentMenu;
extern struct MyMenuItem    *ParentItem;
extern struct ListItem      *MenusList, *ItemsList, *SubsList;
extern ULONG                 Class;
extern UWORD                 Code, Qualifier, FrontPen, BackPen;
extern UWORD                 MenuCount, ItemCount, SubCount, ActEd;
extern UWORD                 MenuTotal, ItemTotal, SubTotal;

void TestMenus( void )
{
    if(MenuStrip) {
        SetWindowTitles(MainWindow,(char *)-1L,"Menu testing! ESC to quit!");
        sst("Menu testing! ESC to quit!");

        ClearMenuStrip(MainWindow);
        SetMenuStrip(MainWindow,(struct Menu *)MenuStrip);
        while(read_msg(MainWindow));

        while(1) {
            WaitPort(MainWindow->UserPort);
            while(read_msg(MainWindow));
            if(Class == RAWKEY && Code == 0x45)
                break;
        }

        ClearMenuStrip(MainWindow);
        SetMenuStrip(MainWindow,&MainMenuStrip[0]);
        refresh();
    }
}

void SetMainMenus( void )
{
    ClearMenuStrip(MainWindow);
    if(ActEd == MENUED) {
        SetMenuStrip(MainWindow,&MainMenuStrip[0]);
        if(NOT MenuCount) {
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(4)|SHIFTSUB(NOSUB)));
        } else {
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(4)|SHIFTSUB(NOSUB)));
        }
        if(MenuTotal == 31)
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)));
        else
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)));
    } else if(ActEd == ITEMED) {
        SetMenuStrip(MainWindow,&ItemMenuStrip[0]);
        if(NOT ItemCount) {
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(4)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(6)|SHIFTSUB(NOSUB)));
        } else {
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(4)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(6)|SHIFTSUB(NOSUB)));
        }
        if(ItemTotal == 63)
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)));
        else
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)));
    } else {
        SetMenuStrip(MainWindow,&SubMenuStrip[0]);
        if(NOT SubCount) {
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(6)|SHIFTSUB(NOSUB)));
        } else {
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(1)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(2)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(6)|SHIFTSUB(NOSUB)));
        }
        if(MenuTotal == 31)
            OffMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)|SHIFTSUB(0)));
        else
            OnMenu(MainWindow,(SHIFTMENU(0)|SHIFTITEM(0)|SHIFTSUB(0)));
    }
}

void CreateList( void )
{
    struct MyMenu       *menus;
    struct MyMenuItem   *items;
    UWORD               count;

    if(ActEd == MENUED) {
        if(MenuStrip) {
            for(MenuCount = 0, menus = MenuStrip; menus; MenuCount++, menus = menus->NextMenu);
        } else {
            for(count = 1; count < 5; count++)
                MainItem[count].SubItem = NULL;
            MenuCount = MenuTotal = NULL;
            MenusList = NULL;
        }
    } else if(ActEd == ITEMED) {
        if(ParentMenu->FirstItem != &dummy) {
            for(count = 1; count < 5; count++)
                TheItem[count].SubItem = (struct MenuItem *)ParentMenu->FirstItem->ItsListItem;
            for(ItemCount = 0, items = ParentMenu->FirstItem; items; ItemCount++, items = items->NextItem);
            ItemsList = ParentMenu->FirstItem->ItsListItem;
        } else {
            for(count = 1; count < 5; count++)
                TheItem[count].SubItem = NULL;
            ItemCount = ItemTotal = NULL;
            ItemsList = NULL;
        }
    } else if(ActEd == SUBED) {
        if(ParentItem->SubItem) {
            for(count = 1; count < 4; count++)
                SubItem[count].SubItem = (struct MenuItem *)ParentItem->SubItem->ItsListItem;
            for(SubCount = 0, items = ParentItem->SubItem; items; SubCount++, items = items->NextItem);
            SubsList = ParentItem->SubItem->ItsListItem;
        } else {
            for(count = 1; count < 4; count++)
                SubItem[count].SubItem = NULL;
            SubCount = SubTotal = NULL;
            SubsList = NULL;
        }
    }
}

struct Menu Exclusion = {
    NULL,0,0,128,9,MENUENABLED,(BYTE *)"MutualExclude",NULL,0,0,0,0 };

UWORD WaitMenu( void )
{
    UWORD   number;

    while(read_msg(MainWindow));

    while(1) {
        WaitPort(MainWindow->UserPort);
        while(read_msg(MainWindow));
        if(Class == MENUPICK AND Code != MENUNULL) {
            number = Code;
            break;
        } else if(Class == RAWKEY AND Code == ESC) {
            number = MENUNULL;
            break;
        }
    }
    while(read_msg(MainWindow));
    return(number);
}

void SetMutualEx( void )
{
    register struct ListItem  *toexcl, *thatexcl;
    register LONG   exval = NULL;
    register UWORD  inum, bnum;

    if(ActEd == ITEMED)
        Exclusion.FirstItem = &ParentMenu->FirstItem->ItsListItem->AItem;
    else
        Exclusion.FirstItem = &ParentItem->SubItem->ItsListItem->AItem;

    ClearMenuStrip(MainWindow);
    SetMenuStrip(MainWindow,&Exclusion);

    sst("PICK ITEM THAT EXCLUDES....");

    if((inum = WaitMenu()) == MENUNULL)
        goto noShow;

    thatexcl = (struct ListItem *)ItemAddress(&Exclusion,inum);

    sst("DRAG-SELECT ITEMS TO EXCLUDE....");

    if((inum = WaitMenu()) == MENUNULL)
        goto noShow;

    toexcl = (struct ListItem *)ItemAddress(&Exclusion,inum);

    while(toexcl) {
        bnum   = ITEMNUM(inum);
        exval |= (1 << bnum);
        inum   = toexcl->AItem.NextSelect;
        toexcl = (struct ListItem *)ItemAddress(&Exclusion,inum);
    }

    if(ActEd == ITEMED)
        thatexcl->Item->MutualExclude = exval;
    else
        thatexcl->SubItem->MutualExclude = exval;

noShow:
    ClearMenuStrip(MainWindow);
    if(ActEd == ITEMED)
        SetMenuStrip(MainWindow,&ItemMenuStrip[0]);
    else
        SetMenuStrip(MainWindow,&SubMenuStrip[0]);
    refresh();
}

ULONG ReAct( ULONG code )
{
    struct MenuItem *Next;
    struct Menu     *Strip;
    struct ListItem *List;
    UWORD            mnum, inum, snum;

    if(ActEd == MENUED)
        Strip = &MainMenuStrip[0];
    else if(ActEd == ITEMED)
        Strip = &ItemMenuStrip[0];
    else
        Strip = &SubMenuStrip[0];

    while(1) {
        mnum = MENUNUM(code);
        inum = ITEMNUM(code);
        snum = SUBNUM(code);

        if(NOT(Next = ItemAddress(Strip,code)))
            break;

        code = Next->NextSelect;

        switch(mnum) {
            case 0:
                switch(inum) {
                    case 0:
                        if(ActEd == MENUED)
                            EditMenu(NULL,FALSE);
                        else
                            EditItem(NULL,FALSE);
                        break;
                    case 1:
                        if(ActEd == MENUED)
                            EditMenu(Next,FALSE);
                        else
                            EditItem(Next,FALSE);
                        break;
                    case 2:
                        if(ActEd == MENUED)
                            RemoveMenu(Next);
                        else
                            RemoveItem(Next);
                        break;
                    case 3:
                        if(ActEd == MENUED)
                            EditMenu(Next,TRUE);
                        else
                            EditItem(Next,TRUE);
                        break;
                    case 4:
                        if(ActEd == MENUED) {
                            ActEd = ITEMED;
                            ParentMenu = ((struct ListItem *)Next)->Menu;
                            ParentItem = ((struct ListItem *)Next)->Item;
                        } else if(ActEd == ITEMED) {
                            ActEd = SUBED;
                            ParentMenu = ((struct ListItem *)Next)->Menu;
                            ParentItem = ((struct ListItem *)Next)->Item;
                        } else
                            ActEd = ITEMED;
                        CreateList();
                        SetMainMenus();
                        break;
                    case 5:
                        if(ActEd == MENUED)
                            TestMenus();
                        else {
                            ActEd = MENUED;
                            SetMainMenus();
                        }
                        break;
                    case 6:
                        if(ActEd == MENUED)
                            return(TRUE);
                        else
                            SetMutualEx();
                        break;
                }
                break;
            case 1:
                FrontPen = inum;
                break;
            case 2:
                BackPen = inum;
                break;
        }
    }
    return(FALSE);
}

void MenuEditing( void )
{
    BOOL    running = TRUE;

    ActEd = MENUED;

    ClearMenuStrip(MainWindow);
    MainMenuStrip[0].NextMenu = &Titles[2];
    ItemMenuStrip[0].NextMenu = &Titles[2];
    SubMenuStrip[0].NextMenu  = &Titles[2];
    SetMenuStrip(MainWindow,&MainMenuStrip[0]);
    CreateList();
    SetMainMenus();

    do {
        WaitPort(MainWindow->UserPort);
        SetWindowTitles(MainWindow,(char *)-1L,(char *)TITLE);
        while(read_msg(MainWindow)) {
            switch(Class) {
                case MENUPICK:
                    if(ReAct(Code))
                        running = FALSE;
                    break;
            }
        }
    } while(running == TRUE);

    ClearMenuStrip(MainWindow);
    SetMenu(MainWindow);
    return;
}
