/* Changes by Karl Lukas 06/94: arp.library support has been dropped */

/*  FileReq.c
 *
 *  ASL interface
 */

#include "defs.h"
#include "cb.h"
#include <stdarg.h>
#include <dos/dos.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <clib/dos_protos.h>
#include <reqtools/reqtools.h>

extern char MForceTitle;

struct rtFileRequester *RFReq;
struct ReqToolsBase *ReqToolsBase;

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

void do_aslload(void)
{
    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(void)
{
    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 ))
        {
            BPTR newlock;

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

                Ep->ASLtop = FReq->rf_TopEdge;
                Ep->ASLleft = FReq->rf_LeftEdge;
                Ep->ASLwidth = FReq->rf_Width;
                Ep->ASLheight = FReq->rf_Height;

                strncpy(Ep->Name, FReq->rf_File, 63);
                MForceTitle = 1;

                do_command("saveold");
            }
        }
        else
        {
            CurrentDir(oldlock);
        }
    }
    else
    {
     do_reqsave();
    }
}

void do_aslinsfile(void)
{
    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,       (ULONG)"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 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.
 */

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

    TagItem tagitem[3];

    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 */
        tagitem[0].ti_Tag = RTFI_Dir;
        tagitem[0].ti_Data = (ULONG)dir;
        tagitem[1].ti_Tag = TAG_DONE;
        tagitem[1].ti_Data = 0;

        rtChangeReqAttrA(RFReq, tagitem);

        tagitem[0].ti_Tag = RT_Window;
        tagitem[0].ti_Data = (ULONG)Ep->Win;
        tagitem[1].ti_Tag = RTFI_OkText;
        tagitem[1].ti_Data = (ULONG)"Load";
        tagitem[2].ti_Tag = TAG_DONE;
        tagitem[2].ti_Data = 0;

        if(rtFileRequestA(RFReq, file, (UBYTE *)"DME Load New File", tagitem))
        {
            BPTR newlock;

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

                av[0] = (ubyte *)"n";
                av[1] = (ubyte *) file;
                do_edit();
                return;
            }
        }
        CurrentDir(oldlock);
    }
    else
        title("No reqtools.library");
}


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

    TagItem tagitem[4];

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

    fixdirname(dir);

    if (RFReq)
    {
        tagitem[0].ti_Tag = RTFI_Dir;
        tagitem[0].ti_Data = (ULONG)dir;
        tagitem[1].ti_Tag = TAG_DONE;
        tagitem[1].ti_Data = 0;

        rtChangeReqAttrA(RFReq, tagitem);

        tagitem[0].ti_Tag = RT_Window;
        tagitem[0].ti_Data = (ULONG)Ep->Win;
        tagitem[1].ti_Tag = RTFI_OkText;
        tagitem[1].ti_Data = (ULONG)"Save";
        tagitem[2].ti_Tag = RTFI_Flags;
        tagitem[2].ti_Data = FREQF_SAVE;
        tagitem[3].ti_Tag = TAG_DONE;
        tagitem[3].ti_Data = 0;

        if(rtFileRequestA(RFReq, file, (UBYTE *)"DME Save File", tagitem))
        {

            BPTR newlock;

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

                strncpy(Ep->Name, file, 63);
                MForceTitle = 1;

                do_command("saveold");
            }
        }
        else
        {
            CurrentDir(oldlock);
        }
    }
    else
        title("No reqtools.library");
}

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

    TagItem tagitem[3];

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

    fixdirname(dir);

    if (FReq)
    {
        tagitem[0].ti_Tag = RTFI_Dir;
        tagitem[0].ti_Data = (ULONG)dir;
        tagitem[1].ti_Tag = TAG_DONE;
        tagitem[1].ti_Data = 0;

        rtChangeReqAttrA(RFReq, tagitem);

        tagitem[0].ti_Tag = RT_Window;
        tagitem[0].ti_Data = (ULONG)Ep->Win;
        tagitem[1].ti_Tag = RTFI_OkText;
        tagitem[1].ti_Data = (ULONG)"Save";
        tagitem[2].ti_Tag = TAG_DONE;
        tagitem[2].ti_Data = 0;

        if(rtFileRequestA(RFReq, file, (UBYTE *)"DME Insert File", tagitem))
        {
            CurrentDir(oldlock);
            fixfile( file, RFReq->Dir);
            av[0] = (ubyte *)"i";
            av[1] = (ubyte *)file;
            do_edit();
            return;
        }
        CurrentDir(oldlock);
    }
    else
        title("No reqtools.library");
}

void do_reqfont(void)
{
    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();

                    strcpy(ep->Fontname, fontreq->Attr.ta_Name);
                    ep->Fontsize = fontreq->Attr.ta_YSize;
                }
                else
                {
                    title("Unable to find font");
                }
            }
            rtFreeRequest (fontreq);
        }
    }
    else
    {
        title("Need ASL.LIBRARY or REQTOOLS.LIBRARY for Font Requester!");
    }
}


void do_saveclip(void)
{
   struct IOClipReq *ior;
   struct cbbuf *clipbuf;
   TagItem tagitem[4];
   char fullname[256];
   int len;
   char file[108];
   BPTR fptr;

   if (ior = CBOpen(0))
   {
      if (CBQueryFTXT(ior))
      {
         if (clipbuf = CBReadCHRS(ior))
         {
            /* clipbuf->count; */
            if (RFReq)
            {
                tagitem[0].ti_Tag = RT_Window;
                tagitem[0].ti_Data = (ULONG)Ep->Win;
                tagitem[1].ti_Tag = RTFI_OkText;
                tagitem[1].ti_Data = (ULONG)"Save";
                tagitem[2].ti_Tag = RTFI_Flags;
                tagitem[2].ti_Data = FREQF_SAVE;
                tagitem[3].ti_Tag = TAG_DONE;
                tagitem[3].ti_Data = 0;

                if(rtFileRequestA(RFReq, file, (UBYTE *)"Save clipboard", tagitem))
                {
                   strcpy(fullname, RFReq->Dir);
                   len = strlen(fullname);
                   if (len && (fullname[len - 1] != ':'))
                      strcat(fullname,  "/");
                   strcat(fullname, file);

                   if (fptr = Open(fullname, MODE_NEWFILE))
                   {
                      if (Write(fptr, clipbuf->mem, clipbuf->count) != clipbuf->count)
                         title("Error while writing file");
                      Close(fptr);
                   }
                   else
                     title("Error: Could not open file");
                }
            }
            else
               title("Sorry, no reqtools.library");
            CBFreeBuf(clipbuf);
         }
         else
            title("Reading from clipboard failed");
         CBReadDone(ior);
      }
      else
         title("Clipboard is empty");
      CBClose(ior);
   }
   else
      title("Error: Cannot open clipboard device");
}

