/*----------------------------------------------------------------------*
   gensrc.c Version 3.0 -  © Copyright 1990-91 Jaba Development

   Author : Jan van den Baard
   Purpose: What it's all about, the writing of C or Assembler source
 *----------------------------------------------------------------------*/

extern struct Window        *MainWindow;
extern struct Screen        *MainScreen;
extern struct FileSelector  *IODir;
extern struct Menu          *MenuStrip;
extern struct ge_prefs       prefs;
extern struct Gadget         TextGadget;
extern struct GadgetList     Gadgets;
extern struct SharedList     Images;
extern struct BorderList     SBorders;
extern ULONG                 WindowFlags, IDCMPFlags;
extern USHORT                BackFill, GadgetCount, WDBackFill;
extern BOOL                  REQUESTER, WBSCREEN;
extern UBYTE                 name[256], wdt[80], wlb[MAXLABEL];

extern BOOL                  gen_wd, gen_sc, gen_cl;
extern BOOL                  gen_bo, gen_rt, gen_sg;
extern BOOL                  gen_gd, gen_si, gen_mn;

extern UBYTE                 TextLabel[32];
extern UBYTE                 BorderLabel[32];
extern UBYTE                 MenuLabel[32];
extern UBYTE                 SpecialLabel[32];
extern UBYTE                 ScreenLabel[32];
extern UBYTE                 ReqLabel[32];
extern UBYTE                 ColorLabel[32];
extern UBYTE                 ImageLabel[32];
extern UBYTE                 SharedLabel[32];

struct GadgetList            Borders;
BOOL                         GenASM, HaveGad, MultyB;

/*
 * Get the exact border number.
 */
ULONG SBordPos( register struct Border *b )
{
    register struct SharedBorder    *s;
    register ULONG                   pos = NULL;

    for(s = SBorders.Head; s->Border != b; s = s->Succ) {
        if(s->Border->NextBorder) pos += 2;
        else                      pos++;
    }
    return(pos);
}

/*
 * split up the normal and 'BORDERONLY' gadgets in seperate lists
 */
static void split( void )
{
    register struct MyGadget *tmp;

    if(! Gadgets.Head->Succ) return;

    NewList((void *)&Borders);

    while(1) {
        tmp = Gadgets.Head;
        while(1) {
            if(TestBits((ULONG)tmp->SpecialFlags,BORDERONLY)) break;
            if(! Gadgets.Head->Succ) return;
            if(NOT (tmp = tmp->Succ)) return;
        }
        Remove((void *)tmp);
        AddHead((void *)&Borders,(void *)tmp);
    }
}

/*
 * join the normal and 'BORDERONLY' gadgets again
 */
static void join( void )
{
    register struct MyGadget *tmp;

    while((tmp = (struct MyGadget *)RemHead((void *)&Borders)))
         AddTail((void *)&Gadgets,(void *)tmp);
}

/*
 * write the IDCMPFlags
 */
static VOID WriteIFlags( BPTR file )
{
    if(NOT IDCMPFlags) {
        if(GenASM) WriteFormat(file,"0");
        else       WriteFormat(file,"NULL");
        return;
    }
    if(TestBits(IDCMPFlags,SIZEVERIFY))     WriteFormat(file,"SIZEVERIFY+");
    if(TestBits(IDCMPFlags,NEWSIZE))        WriteFormat(file,"NEWSIZE+");
    if(TestBits(IDCMPFlags,REFRESHWINDOW))  WriteFormat(file,"REFRESHWINDOW+");
    if(TestBits(IDCMPFlags,ACTIVEWINDOW))   WriteFormat(file,"ACTIVEWINDOW+");
    if(TestBits(IDCMPFlags,INACTIVEWINDOW)) WriteFormat(file,"INACTIVEWINDOW+");
    if(TestBits(IDCMPFlags,GADGETDOWN))     WriteFormat(file,"GADGETDOWN+");
    if(TestBits(IDCMPFlags,GADGETUP))       WriteFormat(file,"GADGETUP+");
    if(TestBits(IDCMPFlags,CLOSEWINDOW))    WriteFormat(file,"CLOSEWINDOW+");
    if(TestBits(IDCMPFlags,REQSET))         WriteFormat(file,"REQSET+");
    if(TestBits(IDCMPFlags,REQCLEAR))       WriteFormat(file,"REQCLEAR+");
    if(TestBits(IDCMPFlags,REQVERIFY))      WriteFormat(file,"REQVERIFY+");
    if(TestBits(IDCMPFlags,MENUPICK))       WriteFormat(file,"MENUPICK+");
    if(TestBits(IDCMPFlags,MENUVERIFY))     WriteFormat(file,"MENUVERIFY+");
    if(TestBits(IDCMPFlags,MOUSEBUTTONS))   WriteFormat(file,"MOUSEBUTTONS+");
    if(TestBits(IDCMPFlags,MOUSEMOVE))      WriteFormat(file,"MOUSEMOVE+");
    if(TestBits(IDCMPFlags,DELTAMOVE))      WriteFormat(file,"DELTAMOVE+");
    if(TestBits(IDCMPFlags,INTUITICKS))     WriteFormat(file,"INTUITICKS+");
    if(TestBits(IDCMPFlags,NEWPREFS))       WriteFormat(file,"NEWPREFS+");
    if(TestBits(IDCMPFlags,DISKINSERTED))   WriteFormat(file,"DISKINSERTED+");
    if(TestBits(IDCMPFlags,DISKREMOVED))    WriteFormat(file,"DISKREMOVED+");
    if(TestBits(IDCMPFlags,RAWKEY))         WriteFormat(file,"RAWKEY+");
    if(TestBits(IDCMPFlags,VANILLAKEY))     WriteFormat(file,"VANILLAKEY+");
    if(TestBits(IDCMPFlags,WBENCHMESSAGE))  WriteFormat(file,"WBENCHMESSAGE+");
    if(TestBits(IDCMPFlags,LONELYMESSAGE))  WriteFormat(file,"LONELYMESSAGE+");
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the window flags
 */
static VOID WriteWFlags( BPTR file )
{
    if(NOT WindowFlags) {
        if(GenASM) WriteFormat(file,"0");
        else       WriteFormat(file,"NULL");
        return;
    }
    if(TestBits(WindowFlags,WINDOWSIZING))   WriteFormat(file,"WINDOWSIZING+");
    if(TestBits(WindowFlags,WINDOWDRAG))     WriteFormat(file,"WINDOWDRAG+");
    if(TestBits(WindowFlags,WINDOWDEPTH))    WriteFormat(file,"WINDOWDEPTH+");
    if(TestBits(WindowFlags,WINDOWCLOSE))    WriteFormat(file,"WINDOWCLOSE+");
    if(TestBits(WindowFlags,SIZEBRIGHT))     WriteFormat(file,"SIZEBRIGHT+");
    if(TestBits(WindowFlags,SIZEBBOTTOM))    WriteFormat(file,"SIZEBBOTTOM+");
    if(TestBits(WindowFlags,NOCAREREFRESH))  WriteFormat(file,"NOCAREREFRESH+");
    if(TestBits(WindowFlags,SIMPLE_REFRESH)) WriteFormat(file,"SIMPLE_REFRESH+");
    if(TestBits(WindowFlags,SMART_REFRESH))  WriteFormat(file,"SMART_REFRESH+");
    if(TestBits(WindowFlags,SUPER_BITMAP))   WriteFormat(file,"SUPER_BITMAP+");
    if(TestBits(WindowFlags,BACKDROP))       WriteFormat(file,"BACKDROP+");
    if(TestBits(WindowFlags,GIMMEZEROZERO))  WriteFormat(file,"GIMMEZEROZERO+");
    if(TestBits(WindowFlags,BORDERLESS))     WriteFormat(file,"BORDERLESS+");
    if(TestBits(WindowFlags,ACTIVATE))       WriteFormat(file,"ACTIVATE+");
    if(TestBits(WindowFlags,REPORTMOUSE))    WriteFormat(file,"REPORTMOUSE+");
    if(TestBits(WindowFlags,RMBTRAP))        WriteFormat(file,"RMBTRAP+");
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the gadget flags
 */
static VOID WriteFlags( BPTR file, struct MyGadget *gad )
{
    struct Gadget *gadget;
    ULONG          flags;

    gadget = &gad->Gadget;
    flags  = (ULONG)gadget->Flags;

    if(NOT flags) {
        WriteFormat(file,"GADGHCOMP");
        return;
    }
    if((TestBits(flags,GADGHIMAGE)) AND
       (TestBits(flags,GADGHBOX)))           WriteFormat(file,"GADGHNONE+");
    else if(TestBits(flags,GADGHIMAGE))      WriteFormat(file,"GADGHIMAGE+");
    else if(TestBits(flags,GADGHBOX))        WriteFormat(file,"GADGHBOX+");
    else                                     WriteFormat(file,"GADGHCOMP+");
    if(TestBits(flags,GRELBOTTOM))           WriteFormat(file,"GRELBOTTOM+");
    if(TestBits(flags,GRELRIGHT))            WriteFormat(file,"GRELRIGHT+");
    if(TestBits(flags,GRELWIDTH))            WriteFormat(file,"GRELWIDTH+");
    if(TestBits(flags,GRELHEIGHT))           WriteFormat(file,"GRELHEIGHT+");
    if(TestBits(flags,GADGIMAGE))            WriteFormat(file,"GADGIMAGE+");
    if(TestBits(flags,SELECTED))             WriteFormat(file,"SELECTED+");
    if(TestBits((ULONG)gad->SpecialFlags,GADGETOFF)) WriteFormat(file,"GADGDISABLED+");
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the activation gadget flags
 */
static VOID WriteActivation( BPTR file, struct MyGadget *gad )
{
    struct Gadget   *gadget;
    ULONG            act;

    gadget = &gad->Gadget;
    act    = (ULONG)gadget->Activation;

    if(TestBits(act,TOGGLESELECT))      WriteFormat(file,"TOGGLESELECT+");
    if(NOT TestBits(gad->SpecialFlags,NOSIGNAL)) {
        if(TestBits(act,RELVERIFY))     WriteFormat(file,"RELVERIFY+");
        if(TestBits(act,GADGIMMEDIATE)) WriteFormat(file,"GADGIMMEDIATE+");
    }
    if(TestBits(act,RIGHTBORDER))       WriteFormat(file,"RIGHTBORDER+");
    if(TestBits(act,LEFTBORDER))        WriteFormat(file,"LEFTBORDER+");
    if(TestBits(act,TOPBORDER))         WriteFormat(file,"TOPBORDER+");
    if(TestBits(act,BOTTOMBORDER))      WriteFormat(file,"BOTTOMBORDER+");
    if(TestBits(act,STRINGCENTER))      WriteFormat(file,"STRINGCENTER+");
    if(TestBits(act,STRINGRIGHT))       WriteFormat(file,"STRINGRIGHT+");
    if(TestBits(act,LONGINT))           WriteFormat(file,"LONGINT+");
    if(TestBits(act,ALTKEYMAP))         WriteFormat(file,"ALTKEYMAP+");
    if(TestBits(act,BOOLEXTEND))        WriteFormat(file,"BOOLEXTEND+");
    if(TestBits(act,ENDGADGET))         WriteFormat(file,"ENDGADGET+");
    if(TestBits(act,FOLLOWMOUSE))       WriteFormat(file,"FOLLOWMOUSE+");
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the gadget type
 */
static VOID WriteType( BPTR file, struct MyGadget *gad )
{
    struct Gadget   *gadget;
    ULONG            type;

    gadget = &gad->Gadget;
    type   = (ULONG)gadget->GadgetType;

    if(TestBits(type,PROPGADGET))      WriteFormat(file,"PROPGADGET+");
    else if(TestBits(type,STRGADGET))  WriteFormat(file,"STRGADGET+");
    else if(TestBits(type,BOOLGADGET)) WriteFormat(file,"BOOLGADGET+");
    if(TestBits((ULONG)gad->SpecialFlags,GZZGADGET)) WriteFormat(file,"GZZGADGET+");
    if(REQUESTER)                      WriteFormat(file,"REQGADGET+");
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the draw modes
 */
VOID WriteDrMd( BPTR file, ULONG drmd, LONG mode )
{
    if(TestBits(drmd,JAM2)) {
        if(mode) WriteFormat(file,"RP_JAM2+");
        else     WriteFormat(file,"JAM2+");
    } else if(TestBits(drmd,JAM1)) {
        if(mode) WriteFormat(file,"RP_JAM1+");
        else     WriteFormat(file,"JAM1+");
    }

    if(TestBits(drmd,COMPLEMENT)) {
        if(mode) WriteFormat(file,"RP_COMPLEMENT+");
        else     WriteFormat(file,"COMPLEMENT+");
    }

    if(TestBits(drmd,INVERSVID)) {
        if(mode) WriteFormat(file,"RP_INVERSVID+");
        else     WriteFormat(file,"INVERSVID+");
    }
    Seek(file,-1,OFFSET_CURRENT);
}

/*
 * write the propinfo flags
 */
static VOID WritePFlags( BPTR file, struct PropInfo *info )
{
    ULONG flags;

    flags = (ULONG)info->Flags;

    if(TestBits(flags,AUTOKNOB))       WriteFormat(file,"AUTOKNOB+");
    if(TestBits(flags,FREEHORIZ))      WriteFormat(file,"FREEHORIZ+");
    if(TestBits(flags,FREEVERT))       WriteFormat(file,"FREEVERT+");
    if(TestBits(flags,PROPBORDERLESS)) WriteFormat(file,"PROPBORDERLESS+");
    Seek(file,-1,OFFSET_CURRENT);
}

#define RAWINC  prefs.no_flags

/*
 * write the assembler image
 */
static VOID WriteAsmImage( BPTR file, struct Image *image, ULONG account )
{
    register USHORT *data;
    register USHORT  i,ii;
    ULONG            data_size;

    data  = image->ImageData;

    WriteFormat(file,"%sData%ld:\n",&ImageLabel[0],account);
    data_size = (RASSIZE(image->Width,image->Height) * image->Depth);

    for( i = 0 ; i < (data_size >> 1) ; i+=8) {
        WriteFormat(file,"    DC.W    ");
        for( ii = 0; ii < 8; ii++) {
            if(i+ii < (data_size >> 1))
                WriteFormat(file,"$%04lx,",data[i+ii]);
        }
        Seek(file,-1,OFFSET_CURRENT);
        WriteFormat(file,"\n");
    }
    WriteFormat(file,"\n");

    WriteFormat(file,"%s%ld:\n",&ImageLabel[0],account);
    WriteFormat(file,"    DC.W    %ld,%ld\n",image->LeftEdge,image->TopEdge);
    WriteFormat(file,"    DC.W    %ld,%ld\n",image->Width,image->Height);
    WriteFormat(file,"    DC.W    %ld\n",image->Depth);
    WriteFormat(file,"    DC.L    %sData%ld\n",&ImageLabel[0],account);
    WriteFormat(file,"    DC.B    $%02lx\n",image->PlanePick);
    WriteFormat(file,"    DC.B    $%02lx\n",image->PlaneOnOff);
    WriteFormat(file,"    DC.L    0\n\n");
}

/*
 * write the assembler prop info structure
 */
static VOID WriteAsmPinfo( BPTR file, struct MyGadget *gadget )
{
    struct PropInfo *info;

    info = (struct PropInfo *)gadget->Gadget.SpecialInfo;
    WriteFormat(file,"%s_info:\n",&gadget->GadgetLabel);
    WriteFormat(file,"    DC.W    ");

    if(RAWINC) WriteFormat(file,"$%04lx",info->Flags);
    else       WritePFlags(file,info);

    WriteFormat(file,"\n    DC.W    $%04lx\n",info->HorizPot);
    WriteFormat(file,"    DC.W    $%04lx\n",info->VertPot);
    WriteFormat(file,"    DC.W    $%04lx\n",info->HorizBody);
    WriteFormat(file,"    DC.W    $%04lx\n",info->VertBody);
    WriteFormat(file,"    DC.W    0,0,0,0,0,0\n\n");
}

/*
 * write the assembler string info structure
 */
static VOID WriteAsmSinfo( BPTR file, struct MyGadget *gadget )
{
    struct StringInfo *info;

    info = (struct StringInfo *)gadget->Gadget.SpecialInfo;
    WriteFormat(file,"%s_info:\n",&gadget->GadgetLabel);
    WriteFormat(file,"    DC.L    %s_buf\n",&gadget->GadgetLabel);

    if(info->UndoBuffer) WriteFormat(file,"    DC.L    %s_ubuf\n",&gadget->GadgetLabel);
    else                 WriteFormat(file,"    DC.L    0\n");

    WriteFormat(file,"    DC.W    0,%ld\n",info->MaxChars);
    WriteFormat(file,"    DC.W    0,0,0,0,0,0\n");
    WriteFormat(file,"    DC.L    0,0,0\n\n");
    WriteFormat(file,"%s_buf:\n",&gadget->GadgetLabel);

    if(strlen(info->Buffer)) {
        WriteFormat(file,"    DC.B    '%s',0\n",info->Buffer);
        WriteFormat(file,"    DCB.B   %ld,0\n",info->MaxChars - strlen((char *)info->Buffer) -1);
    } else
        WriteFormat(file,"    DCB.B   %ld\n",info->MaxChars);
    WriteFormat(file,"    CNOP    0,2\n\n");

    if(info->UndoBuffer) {
        WriteFormat(file,"%s_ubuf:\n    DCB.B    %ld,0\n",&gadget->GadgetLabel,info->MaxChars);
        WriteFormat(file,"    CNOP    0,2\n\n");
    }
}

/*
 * write the assembler gadget structure
 */
static VOID WriteAsmGadget( BPTR file, struct MyGadget *gadget )
{
    struct Gadget   *gad;
    struct MyGadget *next;

    gad = &gadget->Gadget;

    WriteFormat(file,"%s_ID   EQU     %ld\n\n",&gadget->GadgetLabel,gad->GadgetID);
    WriteFormat(file,"%s:\n",&gadget->GadgetLabel);

    if(gadget == Gadgets.Head) {
        if((TextGadget.GadgetText) OR Borders.Head->Succ) {
            if(NOT REQUESTER) {
                if(gen_sg AND (gen_bo OR gen_rt))
                    WriteFormat(file,"    DC.L    %s\n",&SpecialLabel[0]);
                else
                    WriteFormat(file,"    DC.L    0\n");
            } else
                WriteFormat(file,"    DC.L    0\n");
        } else
            WriteFormat(file,"    DC.L    0\n");
    } else
        WriteFormat(file,"    DC.L    %s\n",&(gadget->Pred->GadgetLabel));

    WriteFormat(file,"    DC.W    %ld,%ld\n",gad->LeftEdge,gad->TopEdge);
    WriteFormat(file,"    DC.W    %ld,%ld\n",gad->Width,gad->Height);
    WriteFormat(file,"    DC.W    ");

    if(RAWINC) WriteFormat(file,"$%04lx",gad->Flags);
    else       WriteFlags(file,gadget);

    WriteFormat(file,"\n    DC.W    ");

    if(RAWINC) WriteFormat(file,"$%04lx",gad->Activation);
    else       WriteActivation(file,gadget);

    WriteFormat(file,"\n    DC.W    ");

    if(RAWINC) WriteFormat(file,"$%04lx",gad->GadgetType);
    else       WriteType(file,gadget);

    if(TestBits((ULONG)gad->Flags,GADGIMAGE))
        WriteFormat(file,"\n    DC.L    %s%ld\n",&ImageLabel[0],bank_account(gad->GadgetRender));
    else if(TestBits((ULONG)gad->GadgetType,PROPGADGET))
        WriteFormat(file,"\n    DC.L    %s_image\n",&gadget->GadgetLabel);
    else if(NOT TestBits((ULONG)gadget->SpecialFlags,NOBORDER))
        WriteFormat(file,"\n    DC.L    %s%ld\n",&SharedLabel[0],SBordPos((struct Border *)gadget->Gadget.GadgetRender));
    else
        WriteFormat(file,"\n    DC.L    0\n");

    if((TestBits((ULONG)gad->Flags,GADGHIMAGE)) AND
       (NOT TestBits((ULONG)gad->Flags,GADGHBOX)) AND
       (NOT TestBits((ULONG)gadget->SpecialFlags,OS20HIGHBORDER)))
        WriteFormat(file,"    DC.L    %s%ld\n",&ImageLabel[0],bank_account(gad->SelectRender));
    else if(TestBits((ULONG)gadget->SpecialFlags,OS20HIGHBORDER))
        WriteFormat(file,"    DC.L    %s%ld\n",&SharedLabel[0],SBordPos((struct Border *)gadget->Gadget.SelectRender));
    else
        WriteFormat(file,"    DC.L    0\n");

    if(gad->GadgetText)
        WriteFormat(file,"    DC.L    %s_text0,0\n",&gadget->GadgetLabel);
    else
        WriteFormat(file,"    DC.L    0,0\n");

    if(gad->SpecialInfo)
        WriteFormat(file,"    DC.L    %s_info\n",&gadget->GadgetLabel);
    else
        WriteFormat(file,"    DC.L    0\n");

    WriteFormat(file,"    DC.W    %s_ID\n    DC.L    0\n\n",&gadget->GadgetLabel);
}

/*
 * write the assembler IntuitText structures
 */
static VOID WriteAsmTexts( BPTR file, struct MyGadget *gadget )
{
    register struct IntuiText *itext;
    register UWORD             i=0;

    if((itext = gadget->Gadget.GadgetText)) {
        WriteFormat(file,"%s_text%ld:\n",&gadget->GadgetLabel,i);
        while(1) {
            WriteFormat(file,"    DC.B    %ld,%ld\n",itext->FrontPen,itext->BackPen);
            WriteFormat(file,"    DC.B    ");

            if(RAWINC) WriteFormat(file,"$%02lx",itext->DrawMode);
            else       WriteDrMd(file,itext->DrawMode,TRUE);

            WriteFormat(file,"\n    DC.W    %ld,%ld\n",itext->LeftEdge,itext->TopEdge);
            WriteFormat(file,"    DC.L    0\n");
            WriteFormat(file,"    DC.L    %s_itext%ld\n",&gadget->GadgetLabel,i);

            if(itext->NextText) WriteFormat(file,"    DC.L    %s_text%ld\n\n",&gadget->GadgetLabel,i+1);
            else                WriteFormat(file,"    DC.L    0\n\n");

            WriteFormat(file,"%s_itext%ld:\n",&gadget->GadgetLabel,i++);
            WriteFormat(file,"    DC.B    '%s',0\n",itext->IText);
            WriteFormat(file,"    CNOP    0,2\n\n");

            if(!(itext = itext->NextText)) break;
            WriteFormat(file,"%s_text%ld\n",&gadget->GadgetLabel,i);
        }
    }
}

/*
 * write the assembler new screen structure
 */
static VOID WriteAsmScreen( BPTR file )
{
    WriteFormat(file,"%s:\n",&ScreenLabel[0]);
    WriteFormat(file,"    DC.W    0,0,%ld,%ld\n",MainScreen->Width,MainScreen->Height);
    WriteFormat(file,"    DC.W    %ld\n",MainScreen->BitMap.Depth);
    WriteFormat(file,"    DC.B    -1,-1\n");

    if(MainScreen->BitMap.Depth == 5) WriteFormat(file,"    DC.W    0\n");
    else {
        if(RAWINC) WriteFormat(file,"    DC.W    $8000\n");
        else       WriteFormat(file,"    DC.W    V_HIRES\n");
    }

    if(RAWINC) WriteFormat(file,"    DC.W    $0001\n");
    else       WriteFormat(file,"    DC.W    CUSTOMSCREEN\n");

    WriteFormat(file,"    DC.L    0,0,0,0\n\n");
}

/*
 * write the assembler window/requester structure
 */
static VOID WriteAsmRW( BPTR file )
{
    if(REQUESTER) {
        WriteFormat(file,"%s:\n    DC.L    0\n",&ReqLabel[0]);
        WriteFormat(file,"    DC.W    %ld,%ld,",(MainWindow->LeftEdge + MainWindow->BorderLeft),
                                                (MainWindow->TopEdge + MainWindow->BorderTop));
        WriteFormat(file,"%ld,%ld\n",MainWindow->GZZWidth,MainWindow->GZZHeight);

        if(HaveGad AND gen_gd)
            WriteFormat(file,"    DC.W    0,0\n    DC.L    %s,",&Gadgets.TailPred->GadgetLabel);
        else
            WriteFormat(file,"    DC.W    0,0\n    DC.L    0");

        if(Borders.Head->Succ AND gen_bo)
            WriteFormat(file,"%s0\n",&BorderLabel[0]);
        else
            WriteFormat(file,"0\n");

        if(TextGadget.GadgetText AND gen_rt)
            WriteFormat(file,"    DC.L    %s0\n",&TextLabel[0]);
        else
            WriteFormat(file,"    DC.L    0\n");

        WriteFormat(file,"    DC.W    0\n    DC.B    %ld\n",BackFill);
        WriteFormat(file,"    DC.L    0\n    DCB.B   32,0\n    DC.L    0,0\n    DCB.B    36,0\n\n");
    } else {
        WriteFormat(file,"%s:\n",&wlb);
        WriteFormat(file,"    DC.W    %ld,%ld,%ld,%ld\n",MainWindow->LeftEdge,MainWindow->TopEdge,
                                                         MainWindow->Width,MainWindow->Height);
        WriteFormat(file,"    DC.B    %ld,%ld\n",MainWindow->DetailPen,MainWindow->BlockPen);
        WriteFormat(file,"    DC.L    ");

        if(RAWINC) WriteFormat(file,"$%08lx",IDCMPFlags);
        else       WriteIFlags(file);

        WriteFormat(file,"\n    DC.L    ");

        if(RAWINC) WriteFormat(file,"$%08lx",WindowFlags);
        else       WriteWFlags(file);

        WriteFormat(file,"\n");

        if(HaveGad AND gen_gd)
            WriteFormat(file,"    DC.L    %s,0\n",Gadgets.TailPred->GadgetLabel);
        else if(Borders.Head->Succ OR TextGadget.GadgetText) {
            if(gen_sg AND (gen_bo OR gen_rt))
                WriteFormat(file,"    DC.L    %s,0\n",&SpecialLabel[0]);
            else
                WriteFormat(file,"    DC.L    0,0\n");
        } else
            WriteFormat(file,"    DC.L    0,0\n");

        if(strlen((char *)&wdt))
            WriteFormat(file,"    DC.L    %s_title\n",&wlb);
        else
            WriteFormat(file,"    DC.L    0\n");

        WriteFormat(file,"    DC.L    0,0\n");
        WriteFormat(file,"    DC.W    %ld,%ld,%ld,%ld,",MainWindow->MinWidth,
                                                        MainWindow->MinHeight,
                                                        MainWindow->MaxWidth,
                                                        MainWindow->MaxHeight);
        if(WBSCREEN) {
            if(RAWINC) WriteFormat(file,"$0001\n\n");
            else       WriteFormat(file,"WBENCHSCREEN\n\n");
        } else {
            if(RAWINC) WriteFormat(file,"$000F\n\n");
            else       WriteFormat(file,"CUSTOMSCREEN\n\n");
        }

        if(strlen((char *)&wdt))
            WriteFormat(file,"%s_title:\n    DC.B    '%s',0\n    CNOP    0,2\n\n",&wlb,&wdt);
    }
}

/*
 * write the assembler window/requester texts
 */
static VOID WriteAsmWDT( BPTR file )
{
    register struct IntuiText *t, *t1;
    register USHORT            i = 0;

    if(NOT TextGadget.GadgetText) return;

    t = t1 = TextGadget.GadgetText;
    WriteFormat(file,"%s%ld:\n",&TextLabel[0],i);

    while(1) {
        WriteFormat(file,"    DC.B    %ld,%ld\n",t->FrontPen,t->BackPen);
        WriteFormat(file,"    DC.B    ");

        if(RAWINC) WriteFormat(file,"$%02lx",t->DrawMode);
        else       WriteDrMd(file,t->DrawMode,TRUE);

        WriteFormat(file,"\n    DC.W    %ld,%ld\n",t->LeftEdge,t->TopEdge);
        WriteFormat(file,"    DC.L    0\n");
        WriteFormat(file,"    DC.L    %sIText%ld\n",&TextLabel[0],i);

        if(t->NextText)
            WriteFormat(file,"    DC.L    %s%ld\n\n",&TextLabel[0],i+1);
        else
            WriteFormat(file,"    DC.L    0\n\n");

        WriteFormat(file,"%sIText%ld:\n",&TextLabel[0],i++);
        WriteFormat(file,"    DC.B    '%s',0\n",t->IText);
        WriteFormat(file,"    CNOP    0,2\n\n");

        if(!(t = t->NextText)) break;

        WriteFormat(file,"%s%ld\n",&TextLabel[0],i);
    }
}

/*
 * write assembler special render gadget
 */
static VOID WriteAsmCRG( BPTR file )
{
    if(TextGadget.GadgetText OR Borders.Head->Succ) {
        if(NOT REQUESTER) {
            WriteFormat(file,"%s:\n",&SpecialLabel[0]);

            if(RAWINC) WriteFormat(file,"    DC.L    0\n    DC.W    0,0,1,1,$0003,0,$0001\n");
            else       WriteFormat(file,"    DC.L    0\n    DC.W    0,0,1,1,GADGHNONE,0,BOOLGADGET\n");

            if(Borders.Head->Succ AND gen_bo)
                 WriteFormat(file,"    DC.L    %s0,",&BorderLabel[0]);
            else
                 WriteFormat(file,"    DC.L    0,");

            if(TextGadget.GadgetText AND gen_rt)
                WriteFormat(file,"0,%s0,",&TextLabel[0]);
            else
                WriteFormat(file,"0,0,");

            WriteFormat(file,"0,0\n    DC.W    0\n    DC.L    0\n\n");
       }
    }
}

/*
 * write the assembler border structures
 */
static VOID WriteAsmB( BPTR file )
{
    register struct MyGadget *g;
    register struct Border   *b;
    register SHORT           *xy;
    register UCOUNT           bc = 0,xyc;

    if(NOT Borders.Head->Succ) return;

    for( g = Borders.Head; g->Succ; g = g->Succ) {
        b = (struct Border *)g->Gadget.GadgetRender;
        while(1) {
            xy = b->XY;
            WriteFormat(file,"%sPairs%ld:\n    DC.W   ",&BorderLabel[0],bc);

            for(xyc = 0;xyc < (b->Count << 1); xyc++)
                WriteFormat(file,"%ld,",xy[xyc]);

            Seek(file,-1,OFFSET_CURRENT);
            WriteFormat(file,"\n");
            bc++;
            if(!(b = b->NextBorder)) break;
        }
    }
    WriteFormat(file,"\n");

    bc = 0;

    for(g = Borders.Head; g->Succ; g = g->Succ) {
        b = (struct Border *)g->Gadget.GadgetRender;
        while(1) {
            WriteFormat(file,"%s%ld:\n",&BorderLabel[0],bc);
            WriteFormat(file,"    DC.W    %ld,%ld\n",g->Gadget.LeftEdge,g->Gadget.TopEdge);

            if(RAWINC) WriteFormat(file,"    DC.B    %ld,0\n    DC.B    $00,%ld\n",b->FrontPen,b->Count);
            else       WriteFormat(file,"    DC.B    %ld,0\n    DC.B    RP_JAM1,%ld\n",b->FrontPen,b->Count);

            WriteFormat(file,"    DC.L    %sPairs%ld,",&BorderLabel[0],bc);
            bc++;
            if(!(b = b->NextBorder)) {
                if(NOT g->Succ->Succ)
                    WriteFormat(file,"0\n\n");
                else
                    WriteFormat(file,"%s%ld\n\n",&BorderLabel[0],bc);
                break;
            } else
                WriteFormat(file,"%s%ld\n\n",&BorderLabel[0],bc);
        }
    }
}

/*
 * Write the Image Bank in Assembler.
 */
static VOID WriteAsmBank( BPTR file )
{
    struct SharedImage  *sim;
    struct Image        *image;

    if(NOT Images.Head->Succ) return;

    WriteFormat(file,"* IMAGE DATA MUST BE LOCATED IN CHIP MEMORY!!!\n\n");

    for(sim = Images.Head; sim->Succ; sim = sim->Succ) {
        if(sim->UseCount)
            WriteAsmImage(file,sim->Image,bank_account(sim->Image));
    }
}


/*
 * write the assembler shared border structures
 */
static VOID WriteAsmSB( BPTR file )
{
    register struct SharedBorder *s;
    register struct Border       *b;
    register SHORT               *xy;
    register UCOUNT               bc = 0,pc = 0,xyc;
    BOOL                          sr = FALSE;

    if(NOT SBorders.Head->Succ)  return;

    for(s = SBorders.Head; s->Succ; s = s->Succ) {
        b = s->Border;
        while(1) {
            if(NOT TestBits((ULONG)s->SpecialFlags,SB_HIGHBORDER)) {
                xy = b->XY;
                WriteFormat(file,"%sPairs%ld:\n    DC.W    ",&SharedLabel[0],bc);

                for(xyc = 0;xyc < (b->Count << 1); xyc++)
                    WriteFormat(file,"%ld,",xy[xyc]);

                Seek(file,-1,OFFSET_CURRENT);
                WriteFormat(file,"\n");
                bc++;
                if(!(b = b->NextBorder)) break;
            } else
                break;
        }
    }
    WriteFormat(file,"\n");

    bc = 0;

    for(s = SBorders.Head; s->Succ; s = s->Succ) {
        b = s->Border;
        while(1) {
            WriteFormat(file,"%s%ld:\n",&SharedLabel[0],bc);
            WriteFormat(file,"    DC.W    %ld,%ld\n",b->LeftEdge,b->TopEdge);

            if(RAWINC) WriteFormat(file,"    DC.B    %ld,0\n    DC.B    $00,%ld\n",b->FrontPen,b->Count);
            else       WriteFormat(file,"    DC.B    %ld,0\n    DC.B    RP_JAM1,%ld\n",b->FrontPen,b->Count);

            if(TestBits((ULONG)s->SpecialFlags,SB_HIGHBORDER)) {
                if(NOT sr) pc -= 2;
                sr = TRUE;
            }

            WriteFormat(file,"    DC.L    %sPairs%ld,",&SharedLabel[0],pc);
            bc++;
            pc++;
            if(!(b = b->NextBorder)) {
                WriteFormat(file,"0\n\n");
                break;
            } else
                WriteFormat(file,"%s%ld\n\n",&SharedLabel[0],bc);
        }
        sr = FALSE;
    }
}

/*
 * write the assembler source code
 */
void WriteAsmGadgets( void )
{
    register struct MyGadget *gadget;
    struct ColorMap          *cm;
    USHORT                   *tab, cc, i, ii;
    char                     *str;
    ULONG                     rc, hg;
    BPTR                      file;

    GenASM  = TRUE;
    HaveGad = is_gadget();

    strcpy((char *)IODir->fr_HeadLine,"Save Asm Source");

    IODir->fr_Screen  = MainScreen;
    IODir->fr_Caller  = MainWindow;

    IODir->fr_Flags  |= FR_NoInfo;

    rc = FileRequest(IODir);

    strcpy((char *)&name,(char *)IODir->fr_DirName);
    strcat((char *)&name,(char *)IODir->fr_FileName);

    if(rc == FREQ_CANCELED) return;
    else if(rc) {
        Error("FileRequester won't open !");
        return;
    }

    cm  = MainScreen->ViewPort.ColorMap;
    tab = (USHORT *)cm->ColorTable;

    if(NOT (file = Open((char *)&name,MODE_NEWFILE))) {
        Error("Can't Open Write File !");
        return;
    }

    SetWindowTitles(MainWindow,(char *)-1L,(char *)"Saving Assembler Source.....");
    buisy();
    disable_window();
    un_gzz();
    cc = (1 << MainScreen->BitMap.Depth);

    WriteFormat(file,"*---------------------------------------------------\n");
    WriteFormat(file,"* Gadgets created with PowerSource V3.0\n");
    WriteFormat(file,"* which is (c) Copyright 1990-91 by Jaba Development\n");
    WriteFormat(file,"* written by Jan van den Baard\n");
    WriteFormat(file,"*---------------------------------------------------\n\n");

    if(NOT WBSCREEN AND gen_cl) {
        WriteFormat(file,"%s:\n",&ColorLabel[0]);
        for( ii = 0; ii < cc; ii += 8) {
            WriteFormat(file,"    DC.W    ");
            for( i = 0; i < 8; i++) {
                if((ii+i) < cc)
                    WriteFormat(file,"$%04lx,",tab[ii+i]);
            }
            Seek(file,-1,OFFSET_CURRENT);
            WriteFormat(file,"\n");
        }
        WriteFormat(file,"\n");
    }

    split();

    if(gen_gd)                        WriteAsmBank(file);
    if(gen_bo)                        WriteAsmB(file);
    if(gen_gd)                        WriteAsmSB(file);
    if(gen_rt)                        WriteAsmWDT(file);
    if(gen_sg AND (gen_bo OR gen_rt)) WriteAsmCRG(file);

    if(HaveGad AND gen_gd) {
        for(gadget = Gadgets.Head; gadget->Succ; gadget = gadget->Succ) {
            if(TestBits((ULONG)gadget->Gadget.GadgetType,PROPGADGET)) {
                WriteAsmPinfo(file,gadget);
                if(NOT TestBits((ULONG)gadget->Gadget.Flags,GADGIMAGE)) {
                    WriteFormat(file,"%s_image:\n",&gadget->GadgetLabel);
                    WriteFormat(file,"    DC.W    0,0,0,0,0\n    DC.L    0\n    DC.B    0,0\n    DC.L    0\n\n");
                }
            }

            if(TestBits((ULONG)gadget->Gadget.GadgetType,STRGADGET))
                WriteAsmSinfo(file,gadget);

            if(gadget->Gadget.GadgetText)
                WriteAsmTexts(file,gadget);

            WriteAsmGadget(file,gadget);

            if(str = IoErrToStr()) {
                enable_window();
                ok();
                Close(file);
                Error(str);
                DeleteFile((char *)&name[0]);
                join();
                do_gzz();
                goto error;
            }
        }
    }

    if(MenuStrip AND gen_mn) WriteAsmMenus(file);

    gadget = Gadgets.TailPred;

    if(NOT WBSCREEN AND gen_sc) WriteAsmScreen(file);
    if(gen_wd)                  WriteAsmRW(file);

    if(gen_si) {
        if(NOT WBSCREEN AND gen_cl) {
            WriteFormat(file,"\nCOLORCOUNT   EQU    %ld",cc);
            WriteFormat(file,"\nCOLORMAP:    DC.L   %s",&ColorLabel[0]);
        }

        if(NOT REQUESTER AND gen_wd) {
            WriteFormat(file,"\nNEWWINDOW:   DC.L   %s",&wlb);
            WriteFormat(file,"\nWDBACKFILL   EQU    %ld",WDBackFill);
        } else if(gen_wd)
            WriteFormat(file,"\nREQUESTER:   DC.L   %s",&ReqLabel[0]);

        if(NOT WBSCREEN AND gen_sc)
            WriteFormat(file,"\nNEWSCREEN:   DC.L   %s",&ScreenLabel[0]);
        if(HaveGad AND gen_gd)
            WriteFormat(file,"\nFIRSTGADGET: DC.L   %s",&Gadgets.TailPred->GadgetLabel);
        if(TextGadget.GadgetText AND gen_rt)
            WriteFormat(file,"\nFIRSTTEXT:   DC.L   %s0",&TextLabel[0]);
        if(Borders.Head->Succ AND gen_bo)
            WriteFormat(file,"\nFIRSTBORDER: DC.L   %s0",&BorderLabel[0]);
        if(MenuStrip AND gen_mn)
            WriteFormat(file,"\nFIRSTMENU:   DC.L   %s0",&MenuLabel[0]);
    }
    WriteFormat(file,"\n\n");

    if(str = IoErrToStr()) {
        enable_window();
        ok();
        Error(str);
        Close(file);
        DeleteFile((char *)&name[0]);
        join();
        do_gzz();
        goto error;
    }

    join();
    do_gzz();
    Close(file);
    enable_window();
    ok();
error:
    refresh();
    return;
}

#define STAT    prefs.static_structures

/*
 * write the C image structure
 */
static VOID WriteCImage( BPTR file, struct Image *image, ULONG account)
{
    register USHORT       *data, i, ii;
    ULONG                  data_size;

    data  = image->ImageData;

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"USHORT %sData%ld[] = {\n",&ImageLabel[0],account);
    data_size = (RASSIZE(image->Width,image->Height) * image->Depth);

    for( i = 0; i < (data_size >> 1); i += 8) {
        for(ii = 0; ii < 8; ii++) {
            if(i+ii < (data_size >> 1))
                WriteFormat(file,"  0x%04lx,",data[i+ii]);
        }
        WriteFormat(file,"\n");
    }
    Seek(file,-2,OFFSET_CURRENT);
    WriteFormat(file," }; \n\n");

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct Image %s%ld = {\n",&ImageLabel[0],account);
    WriteFormat(file,"  %ld,%ld,",image->LeftEdge,image->TopEdge);
    WriteFormat(file,"%ld,%ld,",image->Width,image->Height);
    WriteFormat(file,"%ld,",image->Depth);
    WriteFormat(file,"(USHORT *)&%sData%ld[0],",&ImageLabel[0],account);
    WriteFormat(file,"0x%02lx,",image->PlanePick);
    WriteFormat(file,"0x%02lx,",image->PlaneOnOff);
    WriteFormat(file,"NULL };\n\n");
}

/*
 * write the C PropInfo structure
 */
static VOID WriteCPinfo( BPTR file, struct MyGadget *gadget )
{
    struct PropInfo *info;

    info = (struct PropInfo *)gadget->Gadget.SpecialInfo;

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct PropInfo %s_info = {\n  ",&gadget->GadgetLabel);
    WritePFlags(file,info);
    WriteFormat(file,",0x%04lx,",info->HorizPot);
    WriteFormat(file,"0x%04lx,",info->VertPot);
    WriteFormat(file,"0x%04lx,",info->HorizBody);
    WriteFormat(file,"0x%04lx,",info->VertBody);
    WriteFormat(file,"0,0,0,0,0,0 };\n\n");
}

/*
 * write the C StringInfo structure
 */
static VOID WriteCSinfo( BPTR file, struct MyGadget *gadget )
{
    struct StringInfo *info;

    info = (struct StringInfo *)gadget->Gadget.SpecialInfo;

    if(STAT) WriteFormat(file,"static ");

    if(strlen(info->Buffer))
        WriteFormat(file,"UBYTE %s_buf[%ld] = %lc%s%lc;\n\n",&gadget->GadgetLabel,
                                                             info->MaxChars,'"',
                                                             info->Buffer,'"');
    else
        WriteFormat(file,"UBYTE %s_buf[%ld];\n\n",&gadget->GadgetLabel,info->MaxChars);

    if(info->UndoBuffer) {
        if(STAT) WriteFormat(file,"static ");

        WriteFormat(file,"UBYTE %s_ubuf[%ld];\n\n",&gadget->GadgetLabel,info->MaxChars);
    }

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct StringInfo %s_info = {\n",&gadget->GadgetLabel);
    WriteFormat(file,"  (UBYTE *)&%s_buf[0],",&gadget->GadgetLabel);

    if(info->UndoBuffer)
       WriteFormat(file,"(UBYTE *)&%s_ubuf[0],",&gadget->GadgetLabel);
    else
       WriteFormat(file,"NULL,");

    WriteFormat(file,"0,%ld,",info->MaxChars);
    WriteFormat(file,"0,0,0,0,0,0,");
    WriteFormat(file,"NULL,NULL,NULL };\n\n");
}


/*
 * write the C Gadget structure
 */
static VOID WriteCGadget( BPTR file, struct MyGadget *gadget )
{
    struct Gadget    *gad;
    struct MyGadget  *next;
    struct IntuiText *itext;

    gad = &gadget->Gadget;

    WriteFormat(file,"#define %s_ID    %ld\n\n",&gadget->GadgetLabel,gad->GadgetID);

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct Gadget %s = {\n  ",&gadget->GadgetLabel);

    if(gadget == Gadgets.Head) {
        if(NOT REQUESTER) {
            if(TextGadget.GadgetText OR Borders.Head->Succ) {
                if(gen_sg AND (gen_bo OR gen_rt))
                    WriteFormat(file,"&%s,",&SpecialLabel[0]);
                else
                    WriteFormat(file,"NULL,");
            } else
                WriteFormat(file,"NULL,");
        } else
            WriteFormat(file,"NULL,");
    } else
        WriteFormat(file,"&%s,",&(gadget->Pred->GadgetLabel));

    WriteFormat(file,"%ld,%ld,",gad->LeftEdge,gad->TopEdge);
    WriteFormat(file,"%ld,%ld,\n  ",gad->Width,gad->Height);
    WriteFlags(file,gadget);
    WriteFormat(file,",\n  ");
    WriteActivation(file,gadget);
    WriteFormat(file,",\n  ");
    WriteType(file,gadget);

    if(TestBits((ULONG)gad->Flags,GADGIMAGE))
        WriteFormat(file,",\n  (APTR)&%s%ld,",&ImageLabel[0],bank_account(gad->GadgetRender));
    else if(TestBits((ULONG)gadget->Gadget.GadgetType,PROPGADGET))
        WriteFormat(file,",\n  (APTR)&%s_image,",&gadget->GadgetLabel);
    else if(NOT TestBits((ULONG)gadget->SpecialFlags,NOBORDER))
        WriteFormat(file,",\n  (APTR)&%s[%ld],",&SharedLabel[0],SBordPos((struct Border *)gadget->Gadget.GadgetRender));
    else
        WriteFormat(file,",\n  NULL,");

    if((TestBits((ULONG)gad->Flags,GADGHIMAGE)) AND
       (NOT TestBits((ULONG)gad->Flags,GADGHBOX)) AND
       (NOT TestBits((ULONG)gadget->SpecialFlags,OS20HIGHBORDER)))
        WriteFormat(file,"(APTR)&%s%ld,\n  ",&ImageLabel[0],bank_account(gad->SelectRender));
    else if(TestBits((ULONG)gadget->SpecialFlags,OS20HIGHBORDER))
        WriteFormat(file,"(APTR)&%s[%ld],\n  ",&SharedLabel[0],SBordPos((struct Border *)gadget->Gadget.SelectRender));
    else
        WriteFormat(file,"NULL,\n  ");

    if((itext = gad->GadgetText)) {
        if(itext->NextText)
            WriteFormat(file,"&%s_text[0],NULL,",&gadget->GadgetLabel);
        else
            WriteFormat(file,"&%s_text,NULL,",&gadget->GadgetLabel);
    }
    else
        WriteFormat(file,"NULL,NULL,");

    if(gad->SpecialInfo)
        WriteFormat(file,"(APTR)&%s_info,",&gadget->GadgetLabel);
    else
        WriteFormat(file,"NULL,");

    WriteFormat(file,"%s_ID,NULL };\n\n",&gadget->GadgetLabel);
}

/*
 * write the C IntuiText structures
 */
static VOID WriteCTexts( BPTR file, struct MyGadget *gadget )
{
    register struct IntuiText *itext;
    register USHORT            i=1;

    if((itext = gadget->Gadget.GadgetText)) {
        if(STAT) WriteFormat(file,"static ");

        if(itext->NextText)
            WriteFormat(file,"struct IntuiText %s_text[] = {\n",&gadget->GadgetLabel);
        else
            WriteFormat(file,"struct IntuiText %s_text = {\n",&gadget->GadgetLabel);

        while(1) {
            WriteFormat(file,"  %ld,%ld,",itext->FrontPen,itext->BackPen);
            WriteDrMd(file,itext->DrawMode,FALSE);
            WriteFormat(file,",%ld,%ld,NULL,",itext->LeftEdge,itext->TopEdge);
            WriteFormat(file,"(UBYTE *)%lc%s%lc,",'"',itext->IText,'"');
            if(itext->NextText)
                WriteFormat(file,"&%s_text[%ld],\n",&gadget->GadgetLabel,i++);
            else
                WriteFormat(file,"NULL");

            if(!(itext = itext->NextText)) break;
       }
       WriteFormat(file," };\n\n");
    }
}

/*
 * write the C NewScreen structure
 */
static VOID WriteCScreen( BPTR file )
{
    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct NewScreen %s = {\n",&ScreenLabel[0]);
    WriteFormat(file,"  0,0,%ld,%ld,",MainScreen->Width,MainScreen->Height);
    WriteFormat(file,"%ld,",MainScreen->BitMap.Depth);
    WriteFormat(file,"-1,-1,");

    if(MainScreen->BitMap.Depth == 5) WriteFormat(file,"NULL,");
    else                              WriteFormat(file,"HIRES,");

    WriteFormat(file,"CUSTOMSCREEN,NULL,NULL,NULL,NULL };\n\n");
}

/*
 * write the C window/requester structure
 */
static VOID WriteCRW( BPTR file )
{
    struct IntuiText *t;

    if(REQUESTER) {
        if(STAT) WriteFormat(file,"static ");

        WriteFormat(file,"struct Requester %s = {\n  NULL,",&ReqLabel[0]);
        WriteFormat(file,"%ld,%ld,",(MainWindow->LeftEdge + MainWindow->BorderLeft),
                                    (MainWindow->TopEdge + MainWindow->BorderTop));
        WriteFormat(file,"%ld,%ld,",MainWindow->GZZWidth,MainWindow->GZZHeight);

        if(HaveGad AND gen_gd)
            WriteFormat(file,"0,0,&%s,",&Gadgets.TailPred->GadgetLabel);
        else
            WriteFormat(file,"0,0,NULL,");

        if(Borders.Head->Succ AND gen_bo) {
            if(MultyB)
                WriteFormat(file,"&%s[0],",&BorderLabel[0]);
            else
                WriteFormat(file,"&%s,",&BorderLabel[0]);
        }
        else
            WriteFormat(file,"NULL,");

        if((t = TextGadget.GadgetText) AND gen_rt) {
            if(t->NextText) WriteFormat(file,"&%s[0],",&TextLabel[0]);
            else            WriteFormat(file,"&%s,",&TextLabel[0]);
        }
        else
            WriteFormat(file,"NULL,");

        WriteFormat(file,"NULL,%ld,",BackFill);
        WriteFormat(file,"NULL,NULL,NULL,NULL,NULL };\n\n");
    } else {
        if(STAT) WriteFormat(file,"static ");

        WriteFormat(file,"struct NewWindow %s = {\n  ",&wlb);
        WriteFormat(file,"%ld,%ld,%ld,%ld,",MainWindow->LeftEdge,MainWindow->TopEdge,
                                            MainWindow->Width,MainWindow->Height);
        WriteFormat(file,"%ld,%ld,\n  ",MainWindow->DetailPen,MainWindow->BlockPen);
        WriteIFlags(file);
        WriteFormat(file,",\n  ");
        WriteWFlags(file);
        WriteFormat(file,",\n");

        if(HaveGad AND gen_gd)
            WriteFormat(file,"  &%s,NULL,\n",Gadgets.TailPred->GadgetLabel);
        else if(Borders.Head->Succ OR TextGadget.GadgetText) {
            if(gen_sg AND (gen_bo OR gen_rt))
                WriteFormat(file,"  &%s,NULL,\n",&SpecialLabel[0]);
            else
                WriteFormat(file,"  NULL,NULL,\n");
        } else
            WriteFormat(file,"  NULL,NULL,\n");

        if(strlen((char *)&wdt))
            WriteFormat(file,"  (UBYTE *)%lc%s%lc,NULL,NULL,\n",'"',&wdt,'"');
        else
            WriteFormat(file,"  NULL,NULL,NULL,\n");

        WriteFormat(file,"  %ld,%ld,%ld,%ld,",MainWindow->MinWidth,
                                              MainWindow->MinHeight,
                                              MainWindow->MaxWidth,
                                              MainWindow->MaxHeight);

        if(WBSCREEN) WriteFormat(file,"WBENCHSCREEN };\n\n");
        else         WriteFormat(file,"CUSTOMSCREEN };\n\n");
    }
}

/*
 * write the C window/requester texts structures
 */
static VOID WriteCWDT( BPTR file )
{
    register struct IntuiText *t, *t1;
    register USHORT            i = 1;

    if(NOT TextGadget.GadgetText) return;

    t = TextGadget.GadgetText;

    if(STAT) WriteFormat(file,"static ");

    if(t->NextText)
        WriteFormat(file,"struct IntuiText %s[] = {\n  ",&TextLabel[0]);
    else
        WriteFormat(file,"struct IntuiText %s = {\n  ",&TextLabel[0]);

    while(1) {
        WriteFormat(file,"%ld,%ld,",t->FrontPen,t->BackPen);
        WriteDrMd(file,t->DrawMode,FALSE);
        WriteFormat(file,",%ld,%ld,NULL,",t->LeftEdge,t->TopEdge);
        WriteFormat(file,"(UBYTE *)%lc%s%lc,",'"',t->IText,'"');

        if(t->NextText)
            WriteFormat(file,"&%s[%ld],\n  ",&TextLabel[0],i++);
        else
            WriteFormat(file,"NULL");

        if(!(t = t->NextText)) break;
    }
    WriteFormat(file," };\n\n");
}

/*
 * write the C special render gadget
 */
static VOID WriteCRG( BPTR file )
{
    struct IntuiText *t;

    if(TextGadget.GadgetText OR Borders.Head->Succ) {
        if(NOT REQUESTER) {
            if(STAT) WriteFormat(file,"static ");

            WriteFormat(file,"struct Gadget %s = {\n  ",&SpecialLabel[0]);
            WriteFormat(file,"NULL,0,0,1,1,GADGHNONE,NULL,BOOLGADGET,\n");

            if(Borders.Head->Succ AND gen_bo) {
                if(MultyB)
                    WriteFormat(file,"  (APTR)&%s[0],NULL,",&BorderLabel[0]);
                else
                    WriteFormat(file,"  (APTR)&%s,NULL,",&BorderLabel[0]);
            }
            else
                WriteFormat(file,"  NULL,NULL,");

            if((t = TextGadget.GadgetText) AND gen_rt) {
                if(t->NextText) WriteFormat(file,"&%s[0],",&TextLabel[0]);
                else            WriteFormat(file,"&%s,",&TextLabel[0]);
            }
            else
                WriteFormat(file,"NULL,");

            WriteFormat(file,"NULL,NULL,NULL,NULL };\n\n");
        }
    }
}

/*
 * write the C border structures
 */
static VOID WriteCB( BPTR file )
{
    register struct MyGadget *g;
    register struct Border   *b;
    register SHORT           *xy;
    register UCOUNT           bc = 0,xyc;

    if(NOT Borders.Head->Succ) return;

    for(g = Borders.Head; g->Succ; g = g->Succ) {
        b = (struct Border *)g->Gadget.GadgetRender;
        while(1) {
            if(STAT) WriteFormat(file,"static ");

            xy = b->XY;
            WriteFormat(file,"SHORT %sPairs%ld[] = {\n  ",&BorderLabel[0],bc);

            for(xyc = 0;xyc < (b->Count << 1); xyc++)
                WriteFormat(file,"%ld,",xy[xyc]);

            Seek(file,-1,OFFSET_CURRENT);
            WriteFormat(file," };\n");
            bc++;

            if(!(b = b->NextBorder)) break;
        }
    }
    WriteFormat(file,"\n");

    bc = 0;

    if(STAT) WriteFormat(file,"static ");

    if(b->NextBorder OR g->Succ) {
        WriteFormat(file,"struct Border %s[] = {\n",&BorderLabel[0]);
        MultyB = TRUE;
    } else {
        WriteFormat(file,"struct Border %s = {\n",&BorderLabel[0]);
        MultyB = FALSE;
    }

    for(g = Borders.Head; g->Succ; g = g->Succ) {
        b = (struct Border *)g->Gadget.GadgetRender;
        while(1) {
            WriteFormat(file,"  %ld,%ld,",g->Gadget.LeftEdge,g->Gadget.TopEdge);
            WriteFormat(file,"%ld,0,JAM1,%ld,",b->FrontPen,b->Count);
            WriteFormat(file,"(SHORT *)&%sPairs%ld[0],",&BorderLabel[0],bc);
            bc++;

            if(!(b = b->NextBorder)) {
                if(g->Succ == (struct MyGadget *)&Borders.Tail)
                    WriteFormat(file,"NULL };\n\n");
                else
                    WriteFormat(file,"&%s[%ld],\n",&BorderLabel[0],bc);
                break;
            }
            else
                WriteFormat(file,"&%s[%ld],\n",&BorderLabel[0],bc);
        }
    }
}

/*
 * write the C shared border structures
 */
static VOID WriteCSB( BPTR file )
{
    register struct SharedBorder *s;
    register struct Border       *b;
    register SHORT               *xy;
    register UCOUNT               bc = 0,pc = 0,xyc;
    BOOL                          sr = FALSE;

    if(NOT SBorders.Head->Succ)  return;

    for(s = SBorders.Head; s->Succ; s = s->Succ) {
        b = s->Border;
        while(1) {
            if(NOT TestBits((ULONG)s->SpecialFlags,SB_HIGHBORDER)) {
                if(STAT) WriteFormat(file,"static ");

                xy = b->XY;
                WriteFormat(file,"SHORT %sPairs%ld[] = {\n  ",&SharedLabel[0],bc);

                for(xyc = 0;xyc < (b->Count << 1); xyc++)
                    WriteFormat(file,"%ld,",xy[xyc]);

                Seek(file,-1,OFFSET_CURRENT);
                WriteFormat(file," };\n");
                bc++;

                if(!(b = b->NextBorder)) break;
            } else
                break;
        }
    }
    WriteFormat(file,"\n");

    bc = 0;

    if(STAT) WriteFormat(file,"static ");

    WriteFormat(file,"struct Border %s[] = {\n",&SharedLabel[0]);

    for(s = SBorders.Head; s->Succ; s = s->Succ) {
        b = s->Border;
        while(1) {
            WriteFormat(file,"  %ld,%ld,",b->LeftEdge,b->TopEdge);
            WriteFormat(file,"%ld,0,JAM1,%ld,",b->FrontPen,b->Count);

            if(TestBits((ULONG)s->SpecialFlags,SB_HIGHBORDER)) {
                if(NOT sr) pc -= 2;
                sr = TRUE;
            }

            WriteFormat(file,"(SHORT *)&%sPairs%ld[0],",&SharedLabel[0],pc);
            bc++;
            pc++;

            if(!(b = b->NextBorder)) {
                WriteFormat(file,"NULL,\n");
                break;
            } else
                WriteFormat(file,"&%s[%ld],\n",&SharedLabel[0],bc);
        }
        sr = FALSE;
    }
    Seek(file,-2,OFFSET_CURRENT);
    WriteFormat(file," };\n\n");
}

/*
 * Write the Image Bank in C.
 */
static VOID WriteCBank( BPTR file )
{
    struct SharedImage  *sim;
    struct Image        *image;

    if(NOT Images.Head->Succ) return;

    WriteFormat(file,"/* IMAGE DATA MUST BE LOCATED IN CHIP MEMORY!!! */\n\n");

    for(sim = Images.Head; sim->Succ; sim = sim->Succ) {
        if(sim->UseCount)
            WriteCImage(file,sim->Image,bank_account(sim->Image));
    }
}

/*
 * write the C source code
 */
void  WriteCGadgets( void )
{
    register struct MyGadget *gadget;
    struct ColorMap          *cm;
    USHORT                   *tab, cc, i, ii;
    char                     *str;
    BPTR                      file;
    ULONG                     rc;

    GenASM  = FALSE;
    HaveGad = is_gadget();

    strcpy((char *)IODir->fr_HeadLine,"Save C Source");

    IODir->fr_Screen  = MainScreen;
    IODir->fr_Caller  = MainWindow;

    IODir->fr_Flags  |= FR_NoInfo;

    rc = FileRequest(IODir);

    strcpy((char *)&name,(char *)IODir->fr_DirName);
    strcat((char *)&name,(char *)IODir->fr_FileName);

    if(rc == FREQ_CANCELED) return;
    else if(rc) {
        Error("FileRequester won't open !");
        return;
    }

    cm  = MainScreen->ViewPort.ColorMap;
    tab = (USHORT *)cm->ColorTable;

    if(NOT (file = Open((char *)&name,MODE_NEWFILE))) {
        Error("Can't open write file !");
        return;
    }

    SetWindowTitles(MainWindow,(char *)-1L,(char *)"Saving C Source.....");
    buisy();
    disable_window();
    un_gzz();

    cc = (1 << MainScreen->BitMap.Depth);

    WriteFormat(file,"/*---------------------------------------------------*\n");
    WriteFormat(file,"  Gadgets created with PowerSource V3.0\n");
    WriteFormat(file,"  which is (c) Copyright 1990-91 by Jaba Development\n");
    WriteFormat(file,"  written by Jan van den Baard\n");
    WriteFormat(file," *---------------------------------------------------*/\n\n");

    if(NOT WBSCREEN AND gen_cl) {
        if(STAT) WriteFormat(file,"static ");

        WriteFormat(file,"USHORT %s[] = {\n",&ColorLabel[0]);
        for(ii = 0; ii < cc; ii +=8) {
            for(i = 0; i < 8; i++) {
                if((ii+i) < cc)
                    WriteFormat(file,"  0x%04lx,",tab[ii+i]);
            }
            WriteFormat(file,"\n");
        }
        Seek(file,-2,OFFSET_CURRENT);
        WriteFormat(file," };\n\n");
    }

    split();

    if(gen_gd)                        WriteCBank(file);
    if(gen_bo)                        WriteCB(file);
    if(gen_gd)                        WriteCSB(file);
    if(gen_rt)                        WriteCWDT(file);
    if(gen_sg AND (gen_bo OR gen_rt)) WriteCRG(file);

    if(HaveGad AND gen_gd) {
        for(gadget = Gadgets.Head; gadget->Succ; gadget = gadget->Succ) {
            if(TestBits((ULONG)gadget->Gadget.GadgetType,PROPGADGET)) {
                WriteCPinfo(file,gadget);
                if(NOT TestBits((ULONG)gadget->Gadget.Flags,GADGIMAGE)) {
                    if(STAT) WriteFormat(file,"static ");

                    WriteFormat(file,"struct Image %s_image;\n\n",&gadget->GadgetLabel);
                }
            }

            if(TestBits((ULONG)gadget->Gadget.GadgetType,STRGADGET))
                WriteCSinfo(file,gadget);

            if(gadget->Gadget.GadgetText)
                WriteCTexts(file,gadget);

            WriteCGadget(file,gadget);

            if(str = IoErrToStr()) {
                Close(file);
                enable_window();
                ok();
                Error(str);
                DeleteFile((char *)&name[0]);
                join();
                do_gzz();
                goto error;
            }
        }
    }

    if(MenuStrip AND gen_mn) WriteCMenus(file);

    gadget = Gadgets.TailPred;

    if(NOT WBSCREEN AND gen_sc) WriteCScreen(file);
    if(gen_wd)                  WriteCRW(file);

    if(gen_si) {
        if(NOT WBSCREEN AND gen_cl) {
            WriteFormat(file,"\n#define COLORCOUNT  %ld",cc);
            WriteFormat(file,"\n#define COLORMAP    &%s[0]",&ColorLabel[0]);
        }

        if(NOT REQUESTER AND gen_wd) {
            WriteFormat(file,"\n#define NEWWINDOW   &%s",&wlb);
            WriteFormat(file,"\n#define WDBACKFILL  %ld",WDBackFill);
        } else if(gen_wd)
            WriteFormat(file,"\n#define REQUESTER   &%s",&ReqLabel[0]);

        if(NOT WBSCREEN AND gen_sc)
            WriteFormat(file,"\n#define NEWSCREEN   &%s",&ScreenLabel[0]);
        if(HaveGad AND gen_gd)
            WriteFormat(file,"\n#define FIRSTGADGET &%s",&Gadgets.TailPred->GadgetLabel);
        if(TextGadget.GadgetText AND gen_rt) {
            WriteFormat(file,"\n#define FIRSTTEXT   &");
            if(TextGadget.GadgetText->NextText)
                WriteFormat(file,"%s[0]",&TextLabel[0]);
            else
                WriteFormat(file,"%s",&TextLabel[0]);
        }
        if(Borders.Head->Succ AND gen_bo) {
            WriteFormat(file,"\n#define FIRSTBORDER &");
            if(MultyB)
                WriteFormat(file,"%s[0]",&BorderLabel[0]);
            else
                WriteFormat(file,"%s",&BorderLabel[0]);
        }
        if(MenuStrip AND gen_mn)
            WriteFormat(file,"\n#define FIRSTMENU   &%s[0]",&MenuLabel[0]);
    }
    WriteFormat(file,"\n\n");
    if(str = IoErrToStr()) {
        enable_window();
        ok();
        Error(str);
        Close(file);
        DeleteFile((char *)&name[0]);
        join();
        do_gzz();
        goto error;
    }

    Close(file);
    join();
    do_gzz();
    enable_window();
    ok();
error:
    refresh();
    return;
}
