#define GRDIR_CLEAR     TRUE
//
//  Set to TRUE if you want to clear
//  the DolDoc before each dir listing,
//  to make it look and work more
//  like a modern file manager.


        <1>/* Graphics Not Rendered in HTML */      // <1> code files       (.ZC)





        <2>/* Graphics Not Rendered in HTML */      // <2> header files     (.HH)






        <3>/* Graphics Not Rendered in HTML */      // <3> directories






        <4>/* Graphics Not Rendered in HTML */      // <4> disc files       (.iso, .ISO, .ISO.C)








        <5>/* Graphics Not Rendered in HTML */      // <5> DolDoc files     (.DD)







        <6>/* Graphics Not Rendered in HTML */      // <6> binary files     (.BIN, .BIN.C)








        <7>/* Graphics Not Rendered in HTML */      // <7> InFiles          (.IN)






        <8>/* Graphics Not Rendered in HTML */      // <8> text files       (.TXT)







        <9>/* Graphics Not Rendered in HTML */      // <9> unknown filetype








        <10>/* Graphics Not Rendered in HTML */





CDocEntry *GrDirSprite(CDoc *doc=NULL, U8 *elems, U8 *filename=NULL, I64 align=-1)
{   // Draw a GrDir sprite into DolDoc: align arg is 0,1,2 for left,center,right.
    // make into either Link and PopUp, or Left-Macro,
    // so it can be left/right clicked just like the text links.
    // See DocSprite.

    I64          size;
    U8          *st;
    Bool         unlock;
    CDocEntry   *doc_e;
    CDocBin     *tmpb;

    if (!doc && !(doc = DocPut) || !elems)
        return NULL;

    unlock = DocLock(doc);
    size = SpriteSize(elems);
    tmpb = CAlloc(sizeof(CDocBin), doc->mem_task);
    tmpb->size      = size;
    tmpb->data      = MAlloc(size, doc->mem_task);
    MemCopy(tmpb->data, elems, size);
    tmpb->num       = doc->cur_bin_num;
    tmpb->use_count = 1;
    QueueInsert(tmpb, doc->bin_head.last);


    switch (align)
    {
        case 0:
            "\n$CM+LX-RE,LE=6$";
            break;
        case 1:
            "$CM+CX-RE,LE=2$";
            break;
        case 2:
            "$CM+RX-RE,LE=-1$";
            break;
    }

    if (!IsDir(filename))
        st = MStrPrint("$SP+L+PU,\"\",A=\"%s\",BI=%d$", filename, doc->cur_bin_num++);
    else
        st = MStrPrint("$SP+X,\"\",LM=\"Cd(\\\"%s\\\");GrDir;\n\",BI=%d$", filename, doc->cur_bin_num++);

    doc_e = DocPrint(doc, "%s", st);
    Free(st);
    doc_e->bin_data = tmpb;
    if (doc_e && doc_e->de_flags & DOCEF_TAG && doc_e->tag && *doc_e->tag)
        tmpb->tag = StrNew(doc_e->tag, doc->mem_task);
    if (unlock)
        DocUnlock(doc);

    return doc_e;
}

I64 GrDir(U8 *files_find_mask=NULL)
{
    CDirEntry   *tmpde1, *tmpde2;
    I64          res = 0, i;
    U8          *tag, *st,
                *tmpb, *tmpb0, *tmpb1, *tmpb2,  // sprite pointers
                *tmpf0, *tmpf1, *tmpf2;         // filenames (for sprite links)
    CDrive      *drive;

    tmpb = tmpb0 = tmpb1 = tmpb2 = tmpf0 = tmpf1 = tmpf2 = NULL;

    tmpde1 = FilesFind(files_find_mask);
    if (tmpde1)
    {

        if (GRDIR_CLEAR)
            "$CL$";

        st = MAllocIdent(tmpde1->full_name);
        StrLastRemove(st, "/");
        if (!st[2])
            StrCopy(st + 2, "/");

        "%s>$GREEN$GrDir(\"%s\");$FG$\n\n", st, st;

        for (i = 0, drive = blkdev.drvs; i < DRIVES_NUM; i++, drive++)
        {
            if (drive->drive_signature == DRIVE_SIGNATURE_VAL)
            {
                if ('A' <= Drive2Letter(drive) <= 'S')
                    "$MA,\"Drive %C\",LM=\"Drive('%C');GrDir;\n\"$   ", Drive2Letter(drive), Drive2Letter(drive);
                else // ATAPI
                    "$MA,\"Drive %C\",LM=\"DiskChange('%C');Drive('%C');GrDir;\n\"$   ", Drive2Letter(drive), Drive2Letter(drive), Drive2Letter(drive);
            }
        }

        "\n\n$MA,T=\"Directory\",LM=\"PopUpCd;GrDir;\n\"$ of %s\n\n", st;

        if (tmpde1)
        {
            if (!StrCompare(tmpde1->name, "."))
                tmpde1 = tmpde1->next;
            if (tmpde1)
            {
                tmpf0 = MStrPrint("%C:/", tmpde1->full_name[0]);
                if (!StrCompare(tmpde1->name, ".."))
                {
                    if (StrCompare(tmpf0, st))
                    {
                        GrDirSprite(, <10>, tmpde1->name, 0);
                        tmpde1 = tmpde1->next;
                        "\n\n\n\n\n\n";
                    }
                    else
                        tmpde1 = tmpde1->next;
                }
                Free(tmpf0);
            }
        }

        while (tmpde1)
        {
            tmpde2 = tmpde1->next;

            switch (res % 3)
            {
                case 0:
                    tag = "LX";
                    break;
                case 1:
                    tag = "CX";
                    break;
                case 2:
                    tag = "RX";
                    break;
            }

            if (res % 3 == 0 && res != 0)
            {
                GrDirSprite(, tmpb0, tmpf0, 0);
                GrDirSprite(, tmpb1, tmpf1, 1);
                GrDirSprite(, tmpb2, tmpf2, 2);

                "\n\n\n\n\n\n\n";
                tmpb = tmpb0 = tmpb1 = tmpb2 = NULL;

                Free(tmpf0);
                Free(tmpf1);
                Free(tmpf2);
                tmpf0 = tmpf1 = tmpf2 = NULL;
            }

            if (res % 3 == 2)
                "$CM-LE-RE$";

            if (tmpde1->attr & RS_ATTR_DIR)
            {

                "$MA+%s,T=\"%s\",LM=\"Cd(\\\"%s\\\");GrDir;\n\"$", tag, tmpde1->name, tmpde1->full_name;
                switch (res % 3)
                {
                    case 0:
                        tmpb0 = <3>;
                        tmpf0 = StrNew(tmpde1->full_name);
                        break;
                    case 1:
                        tmpb1 = <3>;
                        tmpf1 = StrNew(tmpde1->full_name);
                        break;
                    case 2:
                        tmpb2 = <3>;
                        tmpf2 = StrNew(tmpde1->full_name);
                        break;
                }

            }
            else
            {
                "$LK+%s+PU,\"%s\",A=\"FI:%s\"$", tag, tmpde1->name, tmpde1->full_name;
                if (!StrCompare(FileExtDot(tmpde1->name), ".ZC"))
                    tmpb = <1>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".DD"))
                    tmpb = <5>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".ISO.C")    ||
                         !StrCompare(FileExtDot(tmpde1->name), ".ISO")      ||
                         !StrCompare(FileExtDot(tmpde1->name), ".iso"))
                    tmpb = <4>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".HH"))
                    tmpb = <2>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".BIN.C")    ||
                         !StrCompare(FileExtDot(tmpde1->name), ".BIN"))
                    tmpb = <6>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".IN"))
                    tmpb = <7>;
                else if (!StrCompare(FileExtDot(tmpde1->name), ".TXT"))
                    tmpb = <8>;
                else
                    // sprite for unknown filetype
                    tmpb = <9>;

                switch (res % 3)
                {
                    case 0:
                        tmpb0 = tmpb;
                        tmpf0 = StrNew(tmpde1->full_name);
                        break;
                    case 1:
                        tmpb1 = tmpb;
                        tmpf1 = StrNew(tmpde1->full_name);
                        break;
                    case 2:
                        tmpb2 = tmpb;
                        tmpf2 = StrNew(tmpde1->full_name);
                        break;
                }
            }

            res++;
            DirEntryDel(tmpde1);
            tmpde1 = tmpde2;
        }

        Free(st);
    }
    else
        "\nNo matching entries!!\n";

    GrDirSprite(, tmpb0, tmpf0, 0);
    GrDirSprite(, tmpb1, tmpf1, 1);
    GrDirSprite(, tmpb2, tmpf2, 2);
    "\n\n\n\n\n\n\n";


    return res;
}

Cd;
GrDir;