/*

Directory Opus 4
Original GPL release version 4.12
Copyright 1993-2000 Jonathan Potter

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

All users of Directory Opus 4 (including versions distributed
under the GPL) are entitled to upgrade to the latest version of
Directory Opus version 5 at a reduced price. Please see
http://www.gpsoft.com.au for more information.

The release of Directory Opus 4 under the GPL in NO WAY affects
the existing commercial status of Directory Opus 5.

*/

#include "config.h"

#define NUM_TYPES 5

editfunction(func,type,data)
struct dopusfunction *func;
int type;
APTR data;
{
    int a,selitem,x,y,b,ofp,obp,curtype=0,tof,waitbits;
    ULONG class;
    USHORT code,qual,gadgetid;
    struct Gadget *gad;
    char
        flagsel[NUMFLAGS],*funclist[MAXFUNCS+1],functype[MAXFUNCS],
        *displist[MAXFUNCS+1],buf[256],buf1[256],*ptr,t;
    struct DOpusRemember *key=NULL;
    struct DOpusListView *view;
    struct fileclass fclass;
    struct dopusfiletype *ftype;
    struct dopushotkey *hotkey;

    if (type==CFG_FILETYPE) ftype=(struct dopusfiletype *)data;
    else if (type==CFG_HOTKEYS) hotkey=(struct dopushotkey *)data;

    add_appobject(1);

    for (a=0;a<NUMFLAGS;a++) {
        if (type!=CFG_HOTKEYS ||
            gadflagvals[a]==FF_OUTPUTWIN ||
            gadflagvals[a]==FF_NOQUOTE ||
            gadflagvals[a]==FF_SHELLSTARTUP ||
            gadflagvals[a]==FF_DOPUSSTARTUP) flagsel[a]=0;
        else flagsel[a]=LVARRAY_DISABLED;
    }

    selitem=-1;
    displist[0]=LAllocRemember(&key,60*(MAXFUNCS+1),MEMF_CLEAR);
    for (a=1;a<=MAXFUNCS;a++) {
        if (displist[0]) displist[a]=displist[a-1]+60;
        else displist[a]=NULL;
    }
    ofp=func->fpen; obp=func->bpen;
    editfuncgadgets[1].Flags&=~SELECTED;
    edit_actionbuf[0]=0;
    makehelpname(cfg_string[STR_EDIT]);

    AddGadgetBorders(&key,
        &editfuncgadgets[2],
        4,
        screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
    AddGadgetBorders(&key,
        &editfuncgadgets[9],
        1,
        screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
    AddGadgetBorders(&key,
        &editfuncgadgets[10],
        3,
        screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
    AddGadgetBorders(&key,
        &editfuncgadgets[14],
        1,
        screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);

startedit:
    edit_funcbuf[0]=0;
    SetAPen(rp,screen_pens[1].pen);
    ClearMenuStrip(Window);
    FSSetMenuStrip(Window,&editmenu);
    editlists[1].next=NULL;
    if (type==CFG_HOTKEYS) {
        namesinfo.MaxChars=40;
        strcpy(edit_namebuf,hotkey->name);
        editfuncgadgets[1].NextGadget=&editfuncgadgets[2];
        editfuncgadgets[12].NextGadget=NULL;
        editfuncgadgets[0].LeftEdge=x_off+132;
        editfuncgadgets[0].TopEdge=y_off+22;
        editfuncgadgets[0].Width=320;
        AddGadgets(Window,
            editfuncgadgets,
            editfuncgads2,
            13,
            screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen,1);
    }
    else if (type==CFG_GADGET || type==CFG_MENU) {
        namesinfo.MaxChars=64;
        if (((struct newdopusfunction *)func)->name)
            strcpy(edit_namebuf,((struct newdopusfunction *)func)->name);
        else edit_namebuf[0]=0;
        editfuncgadgets[1].NextGadget=&editfuncgadgets[2];
        editfuncgadgets[12].NextGadget=NULL;
        editfuncgadgets[0].LeftEdge=x_off+188;
        editfuncgadgets[0].TopEdge=y_off+42;
        editfuncgadgets[0].Width=292;
        AddGadgets(Window,
            editfuncgadgets,
            editfuncgads2,
            13,
            screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen,1);
    }
    else if (type==CFG_FILETYPE) {
        curtype=fixfunctypelist(ftype);
        editfuncgadgets[12].NextGadget=&editfuncgadgets[13];
        if (curtype==-1) curtype=0;
        editlists[1].next=&editlists[2];
        editlists[2].topitem=curtype;
        editlists[2].itemselected=curtype;
        AddGadgets(Window,
            &editfuncgadgets[2],
            &editfuncgads2[2],
            13,
            screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen,1);
    }
    setupeditdisplay(func,type,data,curtype,displist,funclist,functype,flagsel,1);
    doglassimage(&editfuncgadgets[10]);
    if (type==CFG_GADGET || type==CFG_MENU) {
        setupcolourbox(rp,x_off+150,y_off+15,func->fpen,func->bpen);
        SetAPen(rp,screen_pens[1].pen);
        do_gad_label(cfg_string[STR_SHORTCUT_KEY],x_off+121,y_off+62);
        showfuncob(rp,edit_namebuf,func->fpen,func->bpen,type,x_off+244,y_off+5);
        showkey(func->key,func->qual,x_off+130,y_off+55,374,10);
    }
    else if (type==CFG_HOTKEYS) {
        SetAPen(rp,screen_pens[1].pen);
        do_gad_label(cfg_string[STR_HOTKEY_USCORE],x_off+121,y_off+62);
        showkey(hotkey->code,hotkey->qualifier,x_off+130,y_off+55,374,10);
    }
    if (type!=CFG_FILETYPE)
        fixrmbimage(&sampleclearrmb,&editfuncgadgets[1],2,-1,-1);

    editgadsoff();

    waitbits=1<<Window->UserPort->mp_SigBit;
    if (appobject) waitbits|=1<<appport->mp_SigBit;

    FOREVER {
        if (appobject) {
            tof=0;
            while (appmsg=(struct AppMessage *)GetMsg(appport)) {
                ActivateWindow(Window);
                if (appmsg->am_ID==MY_APPOBJECT && appmsg->am_NumArgs>0) {
                    for (a=0;a<appmsg->am_NumArgs;a++) {
                        if ((*appmsg->am_ArgList[a].wa_Name)) {
                            if (selitem>-1) {
                                freestring(funclist[selitem]); funclist[selitem]=NULL;
                                if (edit_funcbuf[0]) makenewentry(funclist,functype,displist,selitem);
                                else if (selitem<editlists[0].count)
                                    deleteentry(funclist,functype,displist,selitem);
                                endedit(); selitem=-1;
                            }
                            if (editlists[0].count<MAXFUNCS) {
                                selitem=editlists[0].count;
                                editgadson(0);
                                functype[selitem]=2;
                                PathName(appmsg->am_ArgList[a].wa_Lock,edit_funcbuf,256);
                                TackOn(edit_funcbuf,appmsg->am_ArgList[a].wa_Name,256);
                                editlists[0].itemselected=-1;
                                setupforedit(functype[selitem],(a==(appmsg->am_NumArgs-1)));
                                tof=1;
                            }
                            else DisplayBeep(NULL);
                        }
                    }
                }
                ReplyMsg((struct Message *)appmsg);
            }
            if (tof && Screen) ScreenToFront(Screen);
        }
        while (IMsg=getintuimsg()) {
            if ((view=ListViewIDCMP(editlists,IMsg))==(struct DOpusListView *)-1) {
                class=IMsg->Class; code=IMsg->Code; qual=IMsg->Qualifier;
                x=IMsg->MouseX; y=IMsg->MouseY;
                if (class==GADGETUP || class==GADGETDOWN) {
                    gad=(struct Gadget *)IMsg->IAddress;
                    gadgetid=gad->GadgetID;
                }
                ReplyMsg((struct Message *)IMsg);
                switch (class) {
                    case IDCMP_MENUPICK:
                        if (code==MENUNULL) break;
                        switch (ITEMNUM(code)) {
                            case 0:
                            case 1:
                                if (type==CFG_FILETYPE) {
                                    LStrnCpy(edit_namebuf,ftype->type,22);
                                    edit_namebuf[22]=0;
                                    lsprintf(buf," (%ld)",curtype+1);
                                    StrConcat(edit_namebuf,buf,28);
                                }
                                copytoclip(func,funclist,functype,flagsel);
                                if (ITEMNUM(code)==1) break;
                            case 2:
                                if (ITEMNUM(code)==2 && !(pasteclip(func,funclist,functype,displist,flagsel)))
                                    break;
                            case 4:
                                if (ITEMNUM(code)!=2)
                                    erasefunction(func,funclist,displist,flagsel);
                                if (type==CFG_GADGET || type==CFG_MENU) {
                                    edit_namebuf[255]=0;
                                    showfuncob(rp,edit_namebuf,func->fpen,func->bpen,type,x_off+244,y_off+5);
                                    showkey(func->key,func->qual,x_off+130,y_off+55,374,10);
                                    setupcolourbox(rp,x_off+150,y_off+15,func->fpen,func->bpen);
                                    RefreshStrGad(&editfuncgadgets[0],Window);
                                }
                                else if (type==CFG_HOTKEYS) {
                                    edit_namebuf[39]=0;
                                    showkey(hotkey->code,hotkey->qualifier,x_off+130,y_off+55,374,10);
                                    RefreshStrGad(&editfuncgadgets[0],Window);
                                }
                                RefreshListView(editlists,3);
                                RefreshGList(&editfuncgadgets[6],Window,NULL,3);
                                break;
                            case 6:
                                if (request(cfg_string[STR_REALLY_CLEAR_CLIPS])) {
                                    LFreeRemember(&clipkey);
                                    firstclip=NULL;
                                    DeleteFile("t:configopus.clip");
                                }
                                break;
                        }
                        break;

                    case IDCMP_RAWKEY:
                        if ((code>=0x60 && code<=0x67) || code&0x80) break;
                        if ((type!=CFG_GADGET && type!=CFG_MENU && type!=CFG_HOTKEYS) ||
                            !(editfuncgadgets[1].Flags&SELECTED)) {
                            buf[0]=0;
                            RawkeyToStr(code,qual,NULL,buf,10);
                            switch (LToUpper(buf[0])) {
                                case 'N':
                                    if (type==CFG_GADGET || type==CFG_MENU || type==CFG_HOTKEYS)
                                        ActivateStrGad(&editfuncgadgets[0],Window);
                                    break;
                                case 'H':
                                    if (type!=CFG_HOTKEYS) break;
                                case 'K':
                                    if (type==CFG_GADGET || type==CFG_MENU || type==CFG_HOTKEYS) {
                                        fixrmbimage(&sampleclearrmb,NULL,0,-1,-1);
                                        editfuncgadgets[1].Flags|=SELECTED;
                                        select_gadget(&editfuncgadgets[1],1);
                                        fixrmbimage(&sampleclearrmb,NULL,1,-1,-1);
                                    }
                                    break;
                                case 'S':
                                    ActivateStrGad(&editfuncgadgets[6],Window);
                                    break;
                                case 'P':
                                    ActivateStrGad(&editfuncgadgets[7],Window);
                                    break;
                                case 'C':
                                    ActivateStrGad(&editfuncgadgets[8],Window);
                                    break;
                                case 'E':
                                    if (type==CFG_FILETYPE)
                                        ActivateStrGad(&editfuncgadgets[13],Window);
                                    break;
                            }
                            break;
                        }
                        qual&=IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND|
                            IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT|
                            IEQUALIFIER_LALT|IEQUALIFIER_RALT;
                        if (type==CFG_HOTKEYS) {
                            hotkey->code=code; hotkey->qualifier=qual;
                        }
                        else {
                            func->key=code; func->qual=qual;
                        }
                        showkey(code,qual,x_off+130,y_off+55,374,10);
                        break;

                    case IDCMP_MOUSEBUTTONS:
                        if (code==SELECTDOWN) {
                            if (type==CFG_GADGET || type==CFG_MENU) {
                                a=func->fpen; b=func->bpen;
                                docolourgad(rp,x_off+150,y_off+15,x,y,edit_namebuf,&a,&b,type);
                                func->fpen=a; func->bpen=b;
                            }
                        }
                        else if (code==MENUDOWN) {
                            if (type!=CFG_FILETYPE && (fixrmbimage(&sampleclearrmb,NULL,0,x,y))) {
                                a=DoRMBGadget(&sampleclearrmb,Window);
                                fixrmbimage(&sampleclearrmb,NULL,1,-1,-1);
                                if (a==0) {
                                    if (type==CFG_HOTKEYS) {
                                        hotkey->code=0;
                                        hotkey->qualifier=0;
                                    }
                                    else {
                                        func->key=0xff;
                                        func->qual=0;
                                    }
                                    showkey(0,0,x_off+130,y_off+55,374,10);
                                }
                                editfuncgadgets[1].Flags&=~SELECTED;
                                help_ok=1;
                                break;
                            }
                        }
                        break;

                    case IDCMP_GADGETUP:
                        switch (gadgetid) {
                            case EDIT_CANCEL:
                            case EDIT_OKAY:
                                if (gadgetid==EDIT_CANCEL) {
                                    func->fpen=ofp; func->bpen=obp;
                                }
                                else fixeditfunction(func,flagsel,funclist,functype,selitem,type,data,curtype);
                                freefunclist(funclist);
                                editgadson(1);
                                if (type==CFG_FILETYPE) freefunction(func);
                                LFreeRemember(&key);
                                RemoveListView(editlists,3);
                                ClearMenuStrip(Window);
                                FSSetMenuStrip(Window,&projectmenu);
                                makehelpname((char *)-1);
                                rem_appobject(1);
                                help_ok=1;
                                return((gadgetid==EDIT_OKAY));

                            case EDIT_EDITCLASS:
                                if (type!=CFG_FILETYPE) break;
                                fixeditfunction(func,flagsel,funclist,functype,selitem,type,data,curtype);
                                freefunclist(funclist);
                                editgadson(1);
                                RemoveListView(editlists,3);
                                fclass.last=fclass.next=NULL;
                                strcpy(fclass.type,ftype->type);
                                strcpy(fclass.typeid,ftype->typeid);
                                if (fclass.recognition=getcopy(ftype->recognition,-1,NULL)) {
                                    if (editclass(&fclass,-1)) {
                                        ftype->recognition=getcopy(fclass.recognition,-1,&typekey);
                                        strcpy(ftype->type,fclass.type);
                                        strcpy(ftype->typeid,fclass.typeid);
                                    }
                                    freestring(fclass.recognition);
                                }
                                cleanconfigscreen();
                                filetypetitle(ftype);
                                goto startedit;

                            case EDIT_NAME:
                                if (type!=CFG_HOTKEYS)
                                    showfuncob(rp,edit_namebuf,func->fpen,func->bpen,type,x_off+244,y_off+5);
                                if (code!=0x9) getnextgadget(gad);
                                break;

                            case EDIT_STACK:
                                CheckNumGad(&editfuncgadgets[6],Window,4000,999999);
                                if (code!=0x9) getnextgadget(gad);
                                break;

                            case EDIT_PRIORITY:
                                CheckNumGad(&editfuncgadgets[7],Window,-127,127);
                                if (code!=0x9) getnextgadget(gad);
                                break;

                            case EDIT_DELAY:
                                CheckNumGad(&editfuncgadgets[8],Window,-1,60);
                                if (code!=0x9) getnextgadget(gad);
                                break;

                            case EDIT_TYPE:
                                checkswapgad();
                                if (qual&IEQUALIFIER_LSHIFT || qual&IEQUALIFIER_RSHIFT) {
                                    if (type==CFG_HOTKEYS) {
                                        if ((--functype[selitem])<1) functype[selitem]=NUM_TYPES-1;
                                    }
                                    else if ((--functype[selitem])<0) functype[selitem]=NUM_TYPES-1;
                                }
                                else if ((++functype[selitem])>=NUM_TYPES)
                                    functype[selitem]=(type==CFG_HOTKEYS)?1:0;
                                SetAPen(rp,screen_pens[1].pen);
                                DoCycleGadget(&editfuncgadgets[9],Window,functypestr,functype[selitem]);
                                ActivateStrGad(&editfuncgadgets[11],Window);
                                break;

                            case EDIT_FUNC:
                            case EDIT_DUPLICATE:
                            case EDIT_NEWENTRY:
                                if (selitem>-1) {
                                    freestring(funclist[selitem]); funclist[selitem]=NULL;
                                    if (edit_funcbuf[0]) makenewentry(funclist,functype,displist,selitem);
                                    else if (selitem<editlists[0].count)
                                        deleteentry(funclist,functype,displist,selitem);
                                }
                                if (gadgetid==EDIT_DUPLICATE && edit_funcbuf[0] &&
                                    editlists[0].count<MAXFUNCS) {
                                    strcpy(edit_funcbuf,funclist[selitem]);
                                    functype[editlists[0].count]=functype[selitem];
                                    selitem=editlists[0].count;
                                    editlists[0].topitem+=MAXFUNCS;
                                    editlists[0].itemselected=-1;
                                    setupforedit(functype[selitem],1);
                                }
                                else if (gadgetid==EDIT_NEWENTRY && editlists[0].count<MAXFUNCS) {
                                    if (selitem>-1) {
                                        for (a=MAXFUNCS-1;a>selitem;a--) {
                                            funclist[a]=funclist[a-1];
                                            functype[a]=functype[a-1];
                                            makedispfunc(funclist[a],functype[a],displist[a]);
                                        }
                                        ++editlists[0].count;
                                        funclist[selitem]=getcopy(" ",2,NULL);
                                        makedispfunc(funclist[selitem],(type==CFG_HOTKEYS)?1:0,displist[selitem]);
                                    }
                                    else selitem=editlists[0].count;
                                    editgadson(0);
                                    functype[selitem]=(type==CFG_HOTKEYS)?1:0;
                                    edit_funcbuf[0]=0;
                                    editlists[0].itemselected=-1;
                                    setupforedit(functype[selitem],1);
                                }
                                else {
                                    endedit(); selitem=-1;
                                }
                                break;

                            case EDIT_DELETE:
                                if (selitem<editlists[0].count)
                                    deleteentry(funclist,functype,displist,selitem);
                                endedit(); selitem=-1;
                                break;

                            case EDIT_ARGREQ:
                                cmdlist.topitem=0;
                            case EDIT_REQUESTER:
                                if (funcrequester(
                                    (gadgetid==EDIT_ARGREQ)?FREQ_ARGREQ:functype[selitem],buf,
                                    (gadgetid==EDIT_ARGREQ)?cfg_string[STR_ARGUMENT_CONTROL_SEQUENCES]:
                                        cfg_string[STR_AVAILABLE_COMMANDS])) {
                                    strcpy(buf1,&edit_funcbuf[funcsinfo.BufferPos]);
                                    edit_funcbuf[funcsinfo.BufferPos]=0;
                                    StrConcat(edit_funcbuf,buf,256);
                                    if (gadgetid==EDIT_ARGREQ || functype[selitem]!=FT_INTERNAL)
                                        StrConcat(edit_funcbuf," ",256);
                                    StrConcat(edit_funcbuf,buf1,256);
                                    a=funcsinfo.BufferPos+strlen(buf)+1;
                                    RefreshStrGad(&editfuncgadgets[11],Window);
                                    funcsinfo.BufferPos=(a>255)?255:a;
                                }
                                if (!version2) Delay(5);
                                ActivateGadget(&editfuncgadgets[11],Window,NULL);
                                break;

                            case EDIT_FILETYPEACTION:
                                if (code!=0x9) getnextgadget(gad);
                                break;

                            case EDIT_SAMPLE:
                                help_ok=(editfuncgadgets[1].Flags&GFLG_SELECTED)?0:1;
                                break;
                        }
                        break;
                }
            }
            else if (view) {
                switch (view->listid) {
                    case EDIT_FUNCTIONS:
                        if (editfuncgadgets[4].Flags&SELECTED) {
                            a=view->itemselected;
                            SwapMem((char *)displist[selitem],(char *)displist[a],60);
                            ptr=funclist[selitem]; funclist[selitem]=funclist[a]; funclist[a]=ptr;
                            t=functype[selitem]; functype[selitem]=functype[a]; functype[a]=t;
                            RefreshListView(&editlists[1],1);
                            endedit(); selitem=-1;
                        }
                        else {
                            if (selitem>-1) {
                                freestring(funclist[selitem]); funclist[selitem]=NULL;
                                if (edit_funcbuf[0]) makenewentry(funclist,functype,displist,selitem);
                                else if (selitem<editlists[0].count)
                                    deleteentry(funclist,functype,displist,selitem);
                            }
                            selitem=view->itemselected;
                            editgadson(1);
                            strcpy(edit_funcbuf,funclist[selitem]);
                            setupforedit(functype[selitem],1);
                        }
                        break;
                    case EDIT_FLAGS:
                        flagsel[view->itemselected]^=LVARRAY_SELECTED;
                        checkmutflags(flagsel,view->itemselected);
                        RefreshListView(&editlists[1],1);
                        break;
                    case EDIT_FUNCTIONTYPE:
                        if (type!=CFG_FILETYPE) break;
                        if (curtype==view->itemselected || view->itemselected>=FILETYPE_FUNCNUM)
                            break;
                        fixeditfunction(func,flagsel,funclist,functype,selitem,type,data,curtype);
                        if (selitem>-1) {
                            endedit(); selitem=-1;
                        }
                        curtype=view->itemselected;
                        freefunclist(funclist);
                        setupeditdisplay(func,type,data,curtype,displist,funclist,functype,flagsel,0);
                        break;
                }
            }
        }
        Wait(waitbits);
    }
}

void setuplist(list,x,y)
struct DOpusListView *list;
int x,y;
{
    list->window=Window;
    list->slidercol=screen_pens[1].pen;
    list->sliderbgcol=screen_pens[0].pen;
    list->textcol=screen_pens[1].pen;
    list->boxhi=screen_pens[config->gadgettopcol].pen;
    list->boxlo=screen_pens[config->gadgetbotcol].pen;
    list->arrowfg=screen_pens[1].pen;
    list->arrowbg=screen_pens[0].pen;
    list->itemfg=screen_pens[1].pen;
    list->itembg=screen_pens[0].pen;
    if (x>-1) {
        list->x=x_off+x;
        list->y=y_off+y;
    }
}

void makefunclist(func,funclist,functype)
char *func,**funclist,*functype;
{
    int len,a,pos,num,gottype;
    char buf[256],buf1[256];

    gottype=-1; pos=num=0;
    if (func) {
        len=strlen(func);
        for (a=0;a<=len;a++) {
            if (gottype==-1) {
                switch (func[a]) {
                    case FC_CHDIR: gottype=FT_CHDIR; break;
                    case FC_INTERNAL: gottype=FT_INTERNAL; break;
                    case FC_WORKBENCH: gottype=FT_WORKBENCH; break;
                    case FC_BATCH: gottype=FT_BATCH; break;
                    case FC_AREXX: gottype=FT_AREXX; break;
                    case FC_REQUESTER: gottype=FT_REQUESTER; break;
                    default:
                        if (!isspace(func[a]) && func[a]!='|') {
                            gottype=FT_EXECUTABLE;
                            --a;
                        }
                        break;
                }
                continue;
            }
            if ((gottype==FT_CHDIR && func[a]=='!') ||
                pos==255 || func[a]==0 || (func[a]=='|' && func[a+1]=='|')) {
                buf[pos]=0;
                if (gottype==FT_CHDIR) {
                    StrCombine(buf1,"CD ",buf,256);
                    strcpy(buf,buf1);
                    gottype=FT_EXECUTABLE;
                }
                if (funclist[num]=getcopy(buf,-1,NULL)) {
                    functype[num]=gottype;
                    ++num;
                    if (num==MAXFUNCS) break;
                }
                pos=0; gottype=-1;
            }
            else buf[pos++]=func[a];
        }
    }
    for (a=num;a<MAXFUNCS;a++) funclist[a]=NULL;
}

void makedispfunc(func,type,disp)
char *func,type,*disp;
{
    if (!disp) return;
    if (!func || !func[0] || type<0 || type>=NUM_TYPES) disp[0]=0;
    else {
        strcpy(disp,functypestr[type]);
        StrConcat(disp,spacestring,13);
        StrConcat(disp,func,58);
    }
}

char *compilefunclist(funclist,functype,key)
char **funclist,*functype;
struct DOpusRemember **key;
{
    int a,size,num;
    char *buf,typec,buf2[2];

    size=1; num=0;
    for (a=0;a<MAXFUNCS;a++) {
        if (!funclist[a] || !funclist[a][0]) break;
        if (a>0) size+=2;
        size+=strlen(funclist[a]);
        if (functype[a]!=FT_EXECUTABLE) ++size;
        ++num;
    }
    if (key) buf=LAllocRemember(key,size,MEMF_CLEAR);
    else buf=AllocMem(size,MEMF_CLEAR);
    if (!buf) return(NULL);
    buf2[1]=0;
    for (a=0;a<num;a++) {
        switch (functype[a]) {
            case FT_INTERNAL: typec=FC_INTERNAL; break;
            case FT_WORKBENCH: typec=FC_WORKBENCH; break;
            case FT_BATCH: typec=FC_BATCH; break;
            case FT_AREXX: typec=FC_AREXX; break;
            case FT_REQUESTER: typec=FC_REQUESTER; break;
            default: typec=0; break;
        }
        if (typec) {
            buf2[0]=typec;
            strcat(buf,buf2);
        }
        strcat(buf,funclist[a]);
        if (a<(num-1)) strcat(buf,"||");
    }
    return(buf);
}

void freefunclist(funclist)
char **funclist;
{
    int a;

    for (a=0;a<MAXFUNCS;a++) {
        freestring(funclist[a]); funclist[a]=NULL;
    }
}

void docolourbox(r,x,y,fg,num)
struct RastPort *r;
int x,y,fg,num;
{
    int a,b,ac,dn,w,h,x1,y1;
    char *ptr;

    switch ((b=(1<<((screen_depth > 4) ? 4 : screen_depth)))) {
        case 4: ac=2; dn=2; break;
        case 8: ac=4; dn=2; break;
        case 16: ac=4; dn=4; break;
        default: return;
    }

    Do3DBox(r,x,y,84,22,screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
    SetAPen(r,screen_pens[1].pen);

    a=strlen((ptr=(fg)?cfg_string[STR_FOREGROUND]:cfg_string[STR_BACKGROUND]));
    Move(r,x+42-(a*4),y-4);
    Text(r,ptr,a);

    w=80/ac; h=20/dn;
    x+=2; x1=x; y1=y+1;
    for (a=0;a<b;a++) {
        SetAPen(r,screen_pens[a].pen);
        RectFill(r,x1,y1,x1+w-1,y1+h-1);
        colour_box_xy[num][a][0]=x1;
        colour_box_xy[num][a][1]=y1;
        colour_box_xy[num][a][2]=x1+w-1;
        colour_box_xy[num][a][3]=y1+h-1;
        x1+=w;
        if ((x1-x)==80) {
            x1=x;
            y1+=h;
        }
    }
    colour_box_num=b;
}

void docoloursel(r,x,y,pen)
struct RastPort *r;
int x,y,pen;
{
    int a,ac,dn,w,h,x1,y1;

    a=1<<((screen_depth > 4) ? 4 : screen_depth);
    while (pen>=a && pen>-1) pen-=a;
    if (pen<0) return;

    switch (a) {
        case 4: ac=2; dn=2; break;
        case 8: ac=4; dn=2; break;
        case 16: ac=4; dn=4; break;
        default: return;
    }
    w=80/ac; h=20/dn;
    x+=2; x1=x; y1=y+1;
    for (a=0;a<pen;a++) {
        x1+=w;
        if ((x1-x)==80) {
            x1=x;
            y1+=h;
        }
    }
    drawcompbox(r,x1,y1,w,h);
}

void drawcompbox(r,x1,y1,w,h)
struct RastPort *r;
int x1,y1,w,h;
{
    SetDrMd(r,COMPLEMENT);
    Move(r,x1+2,y1+1); Draw(r,x1+w-3,y1+1);
    Draw(r,x1+w-3,y1+h-2); Draw(r,x1+2,y1+h-2);
    Draw(r,x1+2,y1+2); Draw(r,x1+3,y1+2); Draw(r,x1+3,y1+h-3);
    Move(r,x1+w-4,y1+2); Draw(r,x1+w-4,y1+h-3);
    SetDrMd(r,JAM2);
}

void showkey(key,qual,x,y,w,h)
USHORT key,qual;
int x,y,w,h;
{
    char buf[60];
    int a,l;

    Do3DBox(rp,x,y,w,h,screen_pens[config->gadgetbotcol].pen,screen_pens[config->gadgettopcol].pen);
    SetAPen(rp,screen_pens[0].pen);
    RectFill(rp,x,y,x+w-1,y+h-1);
    SetAPen(rp,screen_pens[1].pen);
    if (key==0) key=255;
    if (RawkeyToStr(key,qual,buf,NULL,60)) {
        l=w/8;
        Move(rp,x+2,y+((h-8)/2)+6);
        a=strlen(buf);
        Text(rp,buf,(a<l)?a:l);
    }
}

void showfuncob(r,name,fp,bp,type,x,y)
struct RastPort *r;
char *name;
int fp,bp,type,x,y;
{
    int a,op;

    op=r->FgPen;
    if (type==CFG_GADGET || type==CFG_DRIVE)
        Do3DBox(r,x+10,y+12,124,8,screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
    SetAPen(r,screen_pens[bp].pen);
    a=strlen(name);
    if (type==CFG_GADGET || type==CFG_DRIVE) {
        if (a>15) a=15;
        RectFill(r,x+10,y+12,x+133,y+19);
        x+=8+((128-(a*8))/2);
    }
    else {
        if (a>14) a=14;
        RectFill(r,x+16,y+12,x+127,y+19);
        x+=16;
    }
    SetDrMd(r,JAM1);
    SetAPen(r,screen_pens[fp].pen);
    Move(r,x,y+18); Text(r,name,a);
    SetDrMd(r,JAM2);
    SetAPen(r,op);
}

void makeselflags(flags,buf)
int flags;
char *buf;
{
    int a;

    for (a=0;a<NUMFLAGS;a++) {
        if (flags&gadflagvals[a]) buf[a]|=LVARRAY_SELECTED;
        else buf[a]&=~LVARRAY_SELECTED;
    }
}

getselflags(buf)
char *buf;
{
    int a,flags=0;

    for (a=0;a<NUMFLAGS;a++) if (buf[a]&LVARRAY_SELECTED) flags|=gadflagvals[a];
    return(flags);
}

void checkmutflags(flags,sel)
char *flags;
int sel;
{
    switch (sel) {
        case SFB_OUTPUTWIN:
            if (flags[SFB_RUNASYNC]&LVARRAY_SELECTED) flags[SFB_WB2F]|=LVARRAY_SELECTED;
            flags[SFB_OUTPUTFILE]&=~LVARRAY_SELECTED;
            if (!(flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED) && flags[SFB_RUNASYNC]&LVARRAY_SELECTED) {
                flags[SFB_WB2F]&=~LVARRAY_SELECTED;
                flags[SFB_DOPUS2F]&=~LVARRAY_SELECTED;
            }
            if (flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED && flags[SFB_AUTOICONIFY]&LVARRAY_SELECTED)
                flags[SFB_WB2F]|=LVARRAY_SELECTED;
            break;
        case SFB_OUTPUTFILE:
            if (flags[SFB_OUTPUTFILE]&LVARRAY_SELECTED) {
                flags[SFB_OUTPUTWIN]&=~LVARRAY_SELECTED;
                if (flags[SFB_RUNASYNC]&LVARRAY_SELECTED) {
                    flags[SFB_WB2F]&=~LVARRAY_SELECTED;
                    flags[SFB_DOPUS2F]&=~LVARRAY_SELECTED;
                }
            }
            flags[SFB_RUNASYNC]&=~LVARRAY_SELECTED;
            flags[SFB_AUTOICONIFY]&=~LVARRAY_SELECTED;
            break;
        case SFB_WB2F:
            if (!(flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED) && flags[SFB_RUNASYNC]&LVARRAY_SELECTED)
                flags[SFB_DOPUS2F]&=~LVARRAY_SELECTED;
            else if (flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED) {
                if (!(flags[SFB_WB2F]&LVARRAY_SELECTED)) flags[SFB_RUNASYNC]&=~LVARRAY_SELECTED;
                flags[SFB_AUTOICONIFY]&=~LVARRAY_SELECTED;
            }
            break;
        case SFB_DOPUS2F:
            if (!(flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED)) {
                if (flags[SFB_RUNASYNC]&LVARRAY_SELECTED) {
                    flags[SFB_WB2F]&=~LVARRAY_SELECTED;
                    flags[SFB_DOPUS2F]&=~LVARRAY_SELECTED;
                }
                else if (flags[SFB_DOPUS2F]&LVARRAY_SELECTED)
                    flags[SFB_RUNASYNC]&=~LVARRAY_SELECTED;
            }
            break;
        case SFB_RUNASYNC:
            if (flags[SFB_OUTPUTFILE]&LVARRAY_SELECTED) {
                flags[SFB_OUTPUTFILE]&=~LVARRAY_SELECTED;
                flags[SFB_OUTPUTWIN]|=LVARRAY_SELECTED;
            }
            if (flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED) flags[SFB_WB2F]|=LVARRAY_SELECTED;
            flags[SFB_RELOADFILE]&=~LVARRAY_SELECTED;
            if (flags[SFB_RUNASYNC]&LVARRAY_SELECTED && !(flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED)) {
                flags[SFB_WB2F]&=~LVARRAY_SELECTED;
                flags[SFB_DOPUS2F]&=~LVARRAY_SELECTED;
            }
            if (!(flags[SFB_RUNASYNC]&LVARRAY_SELECTED))
                flags[SFB_AUTOICONIFY]&=~LVARRAY_SELECTED;
            flags[SFB_OUTPUTFILE]&=~LVARRAY_SELECTED;
            flags[SFB_RESCANSOURCE]&=~LVARRAY_SELECTED;
            flags[SFB_RESCANDEST]&=~LVARRAY_SELECTED;
            break;
        case SFB_CDSOURCE:
            flags[SFB_CDDEST]&=~LVARRAY_SELECTED;
            break;
        case SFB_CDDEST:
            flags[SFB_CDSOURCE]&=~LVARRAY_SELECTED;
            break;
        case SFB_RELOADFILE:
            flags[SFB_RUNASYNC]&=~LVARRAY_SELECTED;
            flags[SFB_AUTOICONIFY]&=~LVARRAY_SELECTED;
            break;
        case SFB_AUTOICONIFY:
            if (!(flags[SFB_RUNASYNC]&LVARRAY_SELECTED)) flags[SFB_RUNASYNC]|=LVARRAY_SELECTED;
            if (flags[SFB_OUTPUTFILE]&LVARRAY_SELECTED) flags[SFB_OUTPUTWIN]|=LVARRAY_SELECTED;
            if (flags[SFB_OUTPUTWIN]&LVARRAY_SELECTED) flags[SFB_WB2F]|=LVARRAY_SELECTED;
            flags[SFB_OUTPUTFILE]&=~LVARRAY_SELECTED;
            flags[SFB_RESCANSOURCE]&=~LVARRAY_SELECTED;
            flags[SFB_RESCANDEST]&=~LVARRAY_SELECTED;
            flags[SFB_RELOADFILE]&=~LVARRAY_SELECTED;
            break;
        case SFB_RESCANSOURCE:
        case SFB_RESCANDEST:
            flags[SFB_RUNASYNC]&=~LVARRAY_SELECTED;
            flags[SFB_AUTOICONIFY]&=~LVARRAY_SELECTED;
            break;
    }
}

void editgadsoff()
{
    int a;

    SetAPen(rp,screen_pens[1].pen);
    DoCycleGadget(&editfuncgadgets[9],Window,functypestr,NUM_TYPES);
    for (a=2;a<6;a++) {
        if (a>2 || editlists[0].count>=MAXFUNCS)
            DisableGadget(&editfuncgadgets[a],rp,4,2);
    }
    for (a=9;a<13;a++) DisableGadget(&editfuncgadgets[a],rp,(a==10 || a==12)?3:((a==9)?4:0),(a==11)?0:2);
}

void editgadson(sel)
int sel;
{
    int a;

    for (a=2;a<6;a++) {
        if ((a==3 || a==4) && !sel) continue;
        if ((a==2 || a==3) && editlists[0].count>=MAXFUNCS) continue;
        EnableGadget(&editfuncgadgets[a],rp,4,2);
    }
    for (a=9;a<13;a++)
        EnableGadget(&editfuncgadgets[a],rp,(a==10 || a==12)?3:((a==9)?4:0),(a==11)?0:2);
}

void deleteentry(funclist,functype,displist,selitem)
char **funclist,*functype,**displist;
int selitem;
{
    int a;

    if (selitem>-1) {
        if (selitem<MAXFUNCS-1) {
            CopyMem(&funclist[selitem+1],&funclist[selitem],(MAXFUNCS-1-selitem)*4);
            CopyMem(&functype[selitem+1],&functype[selitem],(MAXFUNCS-1-selitem));
            for (a=selitem;a<MAXFUNCS-1;a++)
                makedispfunc(funclist[a],functype[a],displist[a]);
        }
        funclist[MAXFUNCS-1]=NULL;
        displist[MAXFUNCS-1][0]=0;
    }
}

void endedit()
{
    checkswapgad();
    edit_funcbuf[0]=0;
    RefreshStrGad(&editfuncgadgets[11],Window);
    editlists[0].itemselected=-1;
    RefreshListView(&editlists[0],1);
    editgadson(1);
    editgadsoff();
}

void setupforedit(type,act)
int type,act;
{
    checkswapgad();
    RefreshListView(&editlists[0],1);
    SetAPen(rp,screen_pens[1].pen);
    DoCycleGadget(&editfuncgadgets[9],Window,functypestr,type);
    RefreshStrGad(&editfuncgadgets[11],Window);
    if (act) ActivateStrGad(&editfuncgadgets[11],Window);
}

void checkswapgad()
{
    if (editfuncgadgets[4].Flags&SELECTED) {
        editfuncgadgets[4].Flags&=~SELECTED;
        select_gadget(&editfuncgadgets[4],0);
    }
}

funcrequester(type,buf,title)
int type;
char *buf,*title;
{
    struct Window *wind;
    ULONG class;
    USHORT gadgetid;
    struct DOpusListView *view;
    char *ptr;
    int ret=0;

    switch (type) {
        case FT_INTERNAL:
        case FREQ_ARGREQ:
        case FREQ_FILETYPE:
        case FREQ_FILECLASS:
            setup_list_window(&requestwin,&cmdlist,&cmdcancelgad,1);
            requestwin.Title=title;
            if (!(wind=openwindow(&requestwin))) return(0);
            setuplist(&cmdlist,-1,-1);
            switch (type) {
                case FREQ_FILETYPE:
                    cmdlist.items=classopslist;
                    break;
                case FREQ_FILECLASS:
                    cmdlist.items=fileclasslist;
                    break;
                case FREQ_ARGREQ:
                    cmdlist.items=arglist;
                    break;
                case FT_INTERNAL:
                    cmdlist.items=commandlist;
                    break;
            }
            cmdlist.window=wind;
            if (!(AddListView(&cmdlist,1))) {
                CloseWindow(wind);
                return(0);
            }
            SetAPen(wind->RPort,screen_pens[1].pen);
            AddGadgets(wind,
                &cmdcancelgad,
                &editfuncgads[4],
                1,
                screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen,1);

            busy();

            FOREVER {
                Wait(1<<wind->UserPort->mp_SigBit);
                while (IMsg=(struct IntuiMessage *)GetMsg(wind->UserPort)) {
                    if ((view=ListViewIDCMP(&cmdlist,IMsg))==(struct DOpusListView *)-1) {
                        class=IMsg->Class;
                        if (class==IDCMP_GADGETUP || class==IDCMP_GADGETDOWN)
                            gadgetid=((struct Gadget *)IMsg->IAddress)->GadgetID;
                        ReplyMsg((struct Message *)IMsg);
                        if (class==IDCMP_GADGETUP && gadgetid==0) {
                            RemoveListView(&cmdlist,1);
                            CloseWindow(wind);
                            unbusy();
                            return(0);
                        }
                    }
                    else if (view) {
                        if (buf) {
                            strcpy(buf,cmdlist.items[view->itemselected]);
                            ptr=buf;
                            while (*(ptr)) {
                                if (*(ptr)==' ') {
                                    *ptr=0;
                                    break;
                                }
                                ++ptr;
                            }
                        }
                        RemoveListView(&cmdlist,1);
                        CloseWindow(wind);
                        unbusy();
                        return(view->itemselected+1);
                    }
                }
            }
            break;

        default:
            filereq.flags=0;
            filereq.title=cfg_string[STR_SELECT_DESIRED_FILE];

            switch (type) {
                case FT_EXECUTABLE:
                case FT_WORKBENCH:
                case FT_BATCH:
                case FT_AREXX:
                    filebuf[0]=0;
                    if (CheckExist(defdir[type],NULL)) strcpy(dirbuf,defdir[type]);
                    else dirbuf[0]=0;
                    break;
                case FREQ_GENERIC:
                    strcpy(dirbuf,buf);
                    if ((ptr=BaseName(dirbuf))>dirbuf) {
                        strcpy(filebuf,ptr);
                        *ptr=0;
                    }
                    else {
                        LStrnCpy(filebuf,buf,FILEBUF_SIZE-1);
                        dirbuf[0]=0;
                    }
                    break;
                case FREQ_PATHREQ:
                    filereq.flags=DFRF_DIRREQ;
                    filereq.title=cfg_string[STR_SELECT_DESIRED_DIRECTORY];
                    break;
            }

            filereq.window=Window;
            if (!dirbuf[0]) {
                BPTR lock;

                if (lock=Lock("",ACCESS_READ)) {
                    PathName(lock,dirbuf,256);
                    UnLock(lock);
                }
            }
            busy();
            if (FileRequest(&filereq)) {
                strcpy(buf,dirbuf);
                TackOn(buf,filebuf,256);
                ret=1;
            }
            unbusy();
            break;
    }
    return(ret);
}

void makenewentry(funclist,functype,displist,selitem)
char **funclist,*functype,**displist;
int selitem;
{
    funclist[selitem]=getcopy(edit_funcbuf,-1,NULL);
    if (displist) {
        makedispfunc(funclist[selitem],functype[selitem],displist[selitem]);
        if (selitem>=editlists[0].count && editlists[0].topitem>=editlists[0].count-5)
            ++editlists[0].topitem;
    }
}

void setupcolourbox(r,x,y,fp,bp)
struct RastPort *r;
int x,y,fp,bp;
{
    docolourbox(r,x,y,1,0);
    docoloursel(r,x,y,fp);
    docolourbox(r,x+248,y,0,1);
    docoloursel(r,x+248,y,bp);
    Do3DBox(r,x+94,y-10,144,32,screen_pens[config->gadgetbotcol].pen,screen_pens[config->gadgettopcol].pen);
}

void getfiletypefunc(func,ftype,type)
struct dopusfunction *func;
struct dopusfiletype *ftype;
int type;
{
    type=ftype_funcmap[type];

    func->which=ftype->which[type];
    func->stack=ftype->stack[type];
    func->pri=ftype->pri[type];
    func->delay=ftype->delay[type];
    freestring(func->function);
    func->function=getcopy(ftype->function[type],-1,NULL);
    strcpy(edit_actionbuf,ftype->actionstring[type]);
}

void makefiletypefunc(func,ftype,type)
struct dopusfunction *func;
struct dopusfiletype *ftype;
int type;
{
    type=ftype_funcmap[type];

    ftype->which[type]=func->which;
    ftype->stack[type]=func->stack;
    ftype->pri[type]=func->pri;
    ftype->delay[type]=func->delay;
    freestring(ftype->function[type]);
    ftype->function[type]=getcopy(func->function,-1,NULL);
    strcpy(ftype->actionstring[type],edit_actionbuf);
}

void fixeditfunction(func,flagsel,funclist,functype,selitem,type,data,curtype)
struct dopusfunction *func;
char *flagsel,**funclist,*functype;
int selitem,type;
APTR data;
int curtype;
{
    struct dopusfiletype *ftype;
    struct dopushotkey *hotkey;

    if (type==CFG_FILETYPE) ftype=(struct dopusfiletype *)data;
    else if (type==CFG_HOTKEYS) hotkey=(struct dopushotkey *)data;

    if (selitem>-1 && edit_funcbuf[0]) {
        freestring(funclist[selitem]); funclist[selitem]=NULL;
        makenewentry(funclist,functype,NULL,selitem);
    }
    freefunction(func);
    func->function=compilefunclist(funclist,functype,NULL);
    func->which=getselflags(flagsel);
    func->stack=atoi(edit_stackbuf);
    if (func->stack<4000) func->stack=4000;
    func->pri=atoi(edit_prioritybuf);
//    if (func->pri<-127) func->pri=-127;
//    else if (func->pri>127) func->pri=127;
    func->delay=atoi(edit_delaybuf);
    if (func->delay<-1) func->delay=-1;
    else if (func->delay>60) func->delay=60;
    if (type==CFG_FILETYPE) {
        makefiletypefunc(func,ftype,curtype);
        fixfunctypelist(ftype);
        RefreshListView(&editlists[2],1);
    }
    else if (type==CFG_HOTKEYS) strcpy(hotkey->name,edit_namebuf);
    else {
        freestring(((struct newdopusfunction *)func)->name);
        ((struct newdopusfunction *)func)->name=getcopy(edit_namebuf,-1,0);
    }
}

void setupeditdisplay(func,type,data,curtype,displist,funclist,functype,flagsel,add)
struct dopusfunction *func;
int type;
APTR data;
int curtype;
char **displist,**funclist,*functype,*flagsel;
int add;
{
    int a;
    struct dopusfiletype *ftype;

    if (type==CFG_FILETYPE) ftype=(struct dopusfiletype *)data;

    for (a=0;a<2;a++) {
        setuplist(&editlists[a],130,69+(a*60));
        editlists[a].itemselected=-1;
        editlists[a].topitem=0;
    }
    if (type==CFG_FILETYPE) {
        setuplist(&editlists[2],173,4);
        getfiletypefunc(func,ftype,curtype);
    }
    else if (type==CFG_HOTKEYS) editlists[1].topitem=5;
    makefunclist(func->function,funclist,functype);
    for (a=0;a<MAXFUNCS;a++) makedispfunc(funclist[a],functype[a],displist[a]);
    displist[MAXFUNCS]=funclist[MAXFUNCS]=NULL;
    editlists[0].items=displist;
    makeselflags(func->which,flagsel);
    editlists[1].selectarray=flagsel;
    if (add) {
        AddListView(editlists,3);
        initsidegads(editfuncgads,0,0);
    }
    else RefreshListView(editlists,3);
    edit_funcbuf[0]=0;
    lsprintf(edit_stackbuf,"%ld",func->stack);
    lsprintf(edit_prioritybuf,"%ld",func->pri);
    lsprintf(edit_delaybuf,"%ld",func->delay);
    RefreshGList(&editfuncgadgets[6],Window,NULL,3);
    if (type==CFG_FILETYPE) RefreshGList(&editfuncgadgets[13],Window,NULL,1);
}

void erasefunction(func,funclist,displist,flagsel)
struct dopusfunction *func;
char **funclist,**displist,*flagsel;
{
    int a;

    freefunclist(funclist);
    for (a=0;a<MAXFUNCS;a++) displist[a][0]=0;
    strcpy(edit_stackbuf,"4000");
    edit_prioritybuf[0]='0'; edit_prioritybuf[1]=0;
    edit_delaybuf[0]='2'; edit_delaybuf[1]=0;
    edit_namebuf[0]=0;
    if (func) {
        func->key=0; func->qual=0;
    }
    makeselflags(0,flagsel);
}

fixfunctypelist(ftype)
struct dopusfiletype *ftype;
{
    int a,type=-1,b;

    for (a=0;a<FILETYPE_FUNCNUM;a++) {
        if (!functypelist[a]) break;
        b=ftype_funcmap[a];
        if (ftype->function[b] && ftype->function[b][0]) {
            if (type==-1) type=a;
            functypelist[a][1]='*';
        }
        else functypelist[a][1]=' ';
    }
    if (type==-1) type=0;
    return(type);
}

void add_appobject(type)
int type;
{
    if (WorkbenchBase && appport) {
        if (Screen && type) {
            appobject=
                (void *)AddAppIconA(MY_APPOBJECT,0,
                    cfg_string[STR_DROP_A_TOOL_HERE],
                    appport,
                    NULL,&dropboxobj,NULL);
        }
        else if (!Screen) {
            appobject=
                (void *)AddAppWindowA(MY_APPOBJECT,0,
                    Window,appport,NULL);
        }
    }
}

void rem_appobject(type)
int type;
{
    if (WorkbenchBase && appobject) {
        if (Screen && type) RemoveAppIcon(appobject);
        else if (!Screen) RemoveAppWindow(appobject);
        while (appmsg=(struct AppMessage *)GetMsg(appport))
            ReplyMsg((struct Message *)appmsg);
    }
    appobject=NULL;
}

void do_gad_label(txt,x,y)
char *txt;
int x,y;
{
    char buf[140];
    int len,a,uspos=-1;

    for (len=0,a=0;txt[len] && a<139;len++) {
        if (txt[len]=='_' && uspos==-1) {
            uspos=a;
            continue;
        }
        buf[a++]=txt[len];
    }
    buf[a]=0;

    x-=a*8;
    UScoreText(rp,buf,x,y,uspos);
}
