/*  FileReq.c
 *
 *  ASL interface
 */

#include "defs.h"
#include <stdarg.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <libraries/reqtools.h>
#include <clib/reqtools_protos.h>

Prototype void do_arpinsfile (void);
Prototype void do_arpload (void);
Prototype void do_arpsave (void);

Prototype void fixfile (char *, char *);
Prototype void splitpath (char *, char *, char *);

Prototype void fixdirname(char *);

Prototype void do_aslload(void);
Prototype void do_aslsave(void);
Prototype void do_aslinsfile(void);
Prototype void do_aslfont(void);
Prototype void do_reqload(void);
Prototype void do_reqsave(void);
Prototype void do_reqinsfile(void);
Prototype void do_reqfont(void);
Prototype struct ReqToolsBase *ReqToolsBase;
Prototype struct rtFileRequester *RFReq;

struct rtFileRequester *RFReq;
struct ReqToolsBase *ReqToolsBase;

/*
 *  The ASL interface uses the asl.library if it exists, else tries to
 *  use the reqtools, then the ARP interfafce.
 */

void do_aslload()
{
    char file[64];
    char dir[64];

    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);     /* does this EVER return a DIR? */

    fixdirname(dir);

    if (FReq)
    {                /* If we have asl.library & requester */
        if (AslRequestTags((APTR)FReq,
                ASL_Hail,       (UBYTE *)"DME Load New File",
                ASL_OKText,     (UBYTE *)"Load",
                ASL_Window,     Ep->Win,
                ASL_FuncFlags,  FILF_NEWIDCMP,
                ASL_Dir,        dir,
                ASL_File,       file,
                ASL_LeftEdge,   Ep->ASLleft,     /* use config coords */
                ASL_TopEdge,    Ep->ASLtop,
                ASL_Width,      Ep->ASLwidth,
                ASL_Height,     Ep->ASLheight,
                TAG_DONE )) {

            BPTR newlock;

            if (newlock = Lock( FReq->rf_Dir, SHARED_LOCK))
            {
                UnLock(CurrentDir(oldlock));
                Ep->dirlock = (long)newlock;

                Ep->ASLtop = FReq->rf_TopEdge;      /* save coords */
                Ep->ASLleft = FReq->rf_LeftEdge;
                Ep->ASLwidth = FReq->rf_Width;
                Ep->ASLheight = FReq->rf_Height;

                /* fixfile(FReq->rf_File,FReq->rf_Dir); */
                av[0] = (ubyte *)"n";
                av[1] = (ubyte *) FReq->rf_File;
                do_edit();
                return;
            }
        }
        CurrentDir(oldlock);
    }
    else {              /* no asl.library? try reqtools */
        do_reqload();
    }
}


void do_aslsave()
{
    char file[64];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);

    fixdirname(dir);

    if (FReq)
    {
        if (AslRequestTags( (APTR)FReq,
                ASL_Hail,       (UBYTE *)"DME Save File",
                ASL_OKText,     (UBYTE *)"Save",
                ASL_Window,     Ep->Win,
                ASL_FuncFlags,  FILF_NEWIDCMP | FILF_SAVE,
                ASL_Dir,        dir,
                ASL_File,       file,
                ASL_LeftEdge,   Ep->ASLleft,
                ASL_TopEdge,    Ep->ASLtop,
                ASL_Width,      Ep->ASLwidth,
                ASL_Height,     Ep->ASLheight,
                TAG_DONE ))
        {

            CurrentDir(oldlock);
            Ep->ASLtop = FReq->rf_TopEdge;
            Ep->ASLleft = FReq->rf_LeftEdge;
            Ep->ASLwidth = FReq->rf_Width;
            Ep->ASLheight = FReq->rf_Height;
            fixfile( FReq->rf_File, FReq->rf_Dir);
            av[1] = (ubyte *)FReq->rf_File;
            do_saveas();
        }
        else
        {
            CurrentDir(oldlock);
        }
    }
    else
    {
     do_reqsave();
    }
}

void
do_aslinsfile()
{
    char file[64];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);

    fixdirname(dir);

    if (FReq)
    {
        if (AslRequestTags( (APTR)FReq,
                ASL_Hail,       (UBYTE *)"DME Insert File",
                ASL_OKText,     (UBYTE *)"Load",
                ASL_Window,     Ep->Win,
                ASL_FuncFlags,  FILF_NEWIDCMP,
                ASL_Dir,        dir,
                ASL_File,       file,
                ASL_LeftEdge,   Ep->ASLleft,
                ASL_TopEdge,    Ep->ASLtop,
                ASL_Width,      Ep->ASLwidth,
                ASL_Height,     Ep->ASLheight,
                TAG_DONE ))
        {

            CurrentDir(oldlock);
            Ep->ASLtop = FReq->rf_TopEdge;
            Ep->ASLleft = FReq->rf_LeftEdge;
            Ep->ASLwidth = FReq->rf_Width;
            Ep->ASLheight = FReq->rf_Height;
            fixfile( FReq->rf_File, FReq->rf_Dir);
            av[0] = (ubyte *)"i";
            av[1] = (ubyte *)FReq->rf_File;
            do_edit();
            return;
        }
        CurrentDir(oldlock);
    }
    else
    {
        do_reqinsfile();
    }
}

void do_aslfont(void)
{
    if (FReq)
    {
        struct FontRequester *fontreq;

        struct TagItem FontTags[]=
        {
            ASL_Hail,       (UBYTE *)"DME fixed width font",
            ASL_Window,     NULL,
            ASL_FuncFlags,  FILF_NEWIDCMP | FONF_FIXEDWIDTH,
            ASL_MinHeight,  6,
            ASL_MaxHeight,  24,         /* more than reasonable, eh? */
            TAG_DONE,       NULL
        };

        FontTags[1].ti_Data = (ULONG)Ep->Win;

        if (fontreq = (struct FontRequester *)
                      AllocAslRequest(ASL_FontRequest,FontTags) ) {

            if (AslRequest(fontreq, NULL)) {

                /*  Since we have GetFont() already, just pass
                 *   the name and size from fontreq's TextAttr to it.
                 *
                 *  What follows mimics SETFONT (in cmnd3.c)
                 */

                FONT *font = (FONT *)GetFont( fontreq->fo_Attr.ta_Name,
                                             (short) fontreq->fo_Attr.ta_YSize );
                ED *ep = Ep;
                if (font) {
                    text_sync();
                    if (ep->Font)
                        CloseFont(ep->Font);
                    ep->Font = font;
                    SetFont(ep->Win->RPort, font);
                    SetRast(ep->Win->RPort, 0);
                    RefreshWindowFrame(ep->Win);
                    set_window_params();
                    text_redisplay();
                } else {
                    title("Unable to find font");
                }
            }
            FreeAslRequest(fontreq);
        }
    } else {
        do_reqfont();
    }
}

/*  this little kludge gets a DIR: string for the ASL requester
 */

void
fixdirname(char *dir)
{
    if (!strlen(dir)) {                 /* if no DIR; KLUDGE ALERT! */

        if (NameFromLock((BPTR)Ep->dirlock, dir, 64)!=DOSTRUE) {

            dir[0] = 0; /* assumes NameFromLock doeesn't clean up on err(??) */
        }
    }
}


void do_arpinsfile()
{
    char file[64];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
    splitpath(Ep->Name, file, dir);
    if (arpreq("Insert File", file, dir, NULL)) {
        CurrentDir(oldlock);
        fixfile(file, dir);
        av[0] = (ubyte *)"i";
        av[1] = (ubyte *)file;
        do_edit();
        return;
    }
    CurrentDir(oldlock);
}

void do_arpload()
{
    char file[64];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
    splitpath(Ep->Name, file, dir);
    if (arpreq("New File", file, dir, NULL))
    {
        BPTR newlock;
        if (newlock = Lock(dir, SHARED_LOCK))
        {
            UnLock(CurrentDir(oldlock));
            Ep->dirlock = (long)newlock;
            /* fixfile(file,dir); */
            av[0] = (ubyte *)"n";
            av[1] = (ubyte *)file;
            do_edit();
            return;
        }
    }
    CurrentDir(oldlock);
}

void do_arpsave()
{
    char file[64];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
    splitpath(Ep->Name, file, dir);
    if (arpreq("Save File", file, dir, NULL))
    {
        CurrentDir(oldlock);
        fixfile(file,dir);
        av[1] = (ubyte *)file;
        do_saveas();
    }
    else
    {
        CurrentDir(oldlock);
    }
}

void  fixfile(char *file,char *dir)
{
    char *ptr;
    short len = strlen(dir);
    char hasdev = 0;

    /*
     *  do we need to add a slash to the directory spec?
     */

    if (len && dir[len-1] != '/' && dir[len-1] != ':')
    {
        dir[len++] = '/';
        dir[len] = 0;
    }

    /*
     *  Is file spec really a full path spec?
     */

    for (ptr = file; *ptr; ++ptr)
    {
        if (ptr[0] == ':')
            hasdev = 1;
    }
    if (!hasdev)
    {
        movmem(file,file+len,strlen(file)+1);
        movmem(dir,file,len);
    }
}

/*
 *  Search backwards for first ':' or '/' and split path there.
 *  This subroutine may appear to be coded incorrectly to a novice
 *  programmer.  It isn't [now].
 */

void splitpath(char *name,char *file,char *dir)
{
    short i;

    for (i = strlen(name); i >= 0; --i)
    {       /* was (incorrectly) "i > 0" */
        if (name[i] == ':' || name[i] == '/')
            break;
    }
    ++i;
    strcpy(file, name + i);
    movmem(name, dir, i);
    dir[i] = 0;
}

/*
 *  The ASL interface uses the asl.library if it exists, else tries to
 *  use the ARP interfafce.
 */

void do_reqload()
{
    char file[108];
    char dir[64];

    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);     /* does this EVER return a DIR? */

    fixdirname(dir);

    if (RFReq)
    {                /* If we have req.library & requester */
        rtChangeReqAttr(RFReq, RTFI_Dir, dir, TAG_DONE);
        if(rtFileRequest (RFReq, file, (UBYTE *)"DME Load New File",
                RTFI_OkText,    (UBYTE *)"Load",
                RT_Window,      Ep->Win,
                RT_ReqPos,      REQPOS_TOPLEFTSCR,
                RT_LeftOffset,  Ep->ASLleft,
                RT_TopOffset,   Ep->ASLtop,
                RTFI_Height,    Ep->ASLheight,
/*                RTFI_Width,     Ep->ASLwidth, */
                TAG_DONE ))
        {
            BPTR newlock;

            if (newlock = Lock( RFReq->Dir, SHARED_LOCK))
            {
                UnLock(CurrentDir(oldlock));
                Ep->dirlock = (long)newlock;

/*              Ep->ASLtop = RFReq->TopOffset;
                Ep->ASLleft = RFReq->LeftOffset;
                Ep->ASLwidth = RFReq->Width;
                Ep->ASLheight = RFReq->Height; */

                /* fixfile(file,RFReq->Dir); */
                av[0] = (ubyte *)"n";
                av[1] = (ubyte *) file;
                do_edit();
                return;
            }
        }
        CurrentDir(oldlock);
    }
    else
    {              /* no req.library? try ARP */
        do_arpload();
    }
}


void do_reqsave()
{
    char file[108];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);

    fixdirname(dir);

    if (FReq)
    {
        rtChangeReqAttr(RFReq, RTFI_Dir, dir, TAG_DONE);
        if(rtFileRequest (RFReq, file, (UBYTE *)"DME Save File",
                RTFI_OkText,    (UBYTE *)"Save",
                RT_Window,      Ep->Win,
                RTFI_Flags,     FREQF_SAVE,
                RT_ReqPos,      REQPOS_TOPLEFTSCR,
                RT_LeftOffset,  Ep->ASLleft,
                RT_TopOffset,   Ep->ASLtop,
                RTFI_Height,    Ep->ASLheight,
/*                RTFI_Width,     Ep->ASLwidth, */
                TAG_DONE )) {

            CurrentDir(oldlock);
/*          Ep->ASLtop = RFReq->TopOffset;
            Ep->ASLleft = RFReq->LeftOffset;
            Ep->ASLwidth = RFReq->Width;
            Ep->ASLheight = RFReq->Height; */
            fixfile( file, RFReq->Dir);
            av[1] = (ubyte *)file;
            do_saveas();
        }
        else
        {
            CurrentDir(oldlock);
        }
    }
    else
    {
        do_arpsave();
    }
}

void do_reqinsfile()
{
    char file[108];
    char dir[64];
    BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);

    splitpath(Ep->Name, file, dir);

    fixdirname(dir);

    if (FReq)
    {
        rtChangeReqAttr(RFReq, RTFI_Dir, dir, TAG_DONE);
        if(rtFileRequest (RFReq, file, (UBYTE *)"DME Insert File",
                RTFI_OkText,    (UBYTE *)"Load",
                RT_Window,      Ep->Win,
                RT_ReqPos,      REQPOS_TOPLEFTSCR,
                RT_LeftOffset,  Ep->ASLleft,
                RT_TopOffset,   Ep->ASLtop,
                RTFI_Height,    Ep->ASLheight,
/*                RTFI_Width,     Ep->ASLwidth, */
                TAG_DONE ))
        {

            CurrentDir(oldlock);
/*          Ep->ASLtop = RFReq->TopOffset;
            Ep->ASLleft = RFReq->LeftOffset;
            Ep->ASLwidth = RFReq->Width;
            Ep->ASLheight = RFReq->Height; */
            fixfile( file, RFReq->Dir);
            av[0] = (ubyte *)"i";
            av[1] = (ubyte *)file;
            do_edit();
            return;
        }
        CurrentDir(oldlock);
    }
    else
    {
        do_arpinsfile();
    }
}

void do_reqfont()
{
    if (ReqToolsBase)
    {
        struct rtFontRequester *fontreq;

        struct TagItem FontTags[] =
        {
            RT_Window,      NULL,
            RTFO_Flags,     FREQF_FIXEDWIDTH, /* | FILF_NEWIDCMP */
            RTFO_MinHeight, 6,
            RTFO_MaxHeight, 24,
            TAG_DONE
        };

        FontTags[0].ti_Data=(ULONG)Ep->Win;

        if (fontreq = rtAllocRequestA (RT_FONTREQ, NULL))
        {
            if (rtFontRequestA (fontreq, (UBYTE *)"DME fixed width font", FontTags)) {

                /*  Since we have GetFont() already, just pass
                 *   the name and size from fontreq's TextAttr to it.
                 *
                 *  What follows mimics SETFONT (in cmnd3.c)
                 */

                FONT *font = (FONT *)GetFont( fontreq->Attr.ta_Name,
                                             (short) fontreq->Attr.ta_YSize );
                ED *ep = Ep;
                if (font)
                {
                    text_sync();
                    if (ep->Font)
                        CloseFont(ep->Font);

                    ep->Font = font;
                    SetFont(ep->Win->RPort, font);
                    SetRast(ep->Win->RPort, 0);
                    RefreshWindowFrame(ep->Win);
                    set_window_params();
                    text_redisplay();
                }
                else
                {
                    title("Unable to find font");
                }
            }
            rtFreeRequest (fontreq);
        }
    }
    else
    {
        title("Need ASL.LIBRARY or REQTOOLS.LIBRARY for Font Requester!");
    }
}

