#include <string.h>
/*
 *  SUBS.C
 *
 *      (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 *

 */

#include "defs.h"
#include <ctype.h>


typedef struct FileInfoBlock FIB;
typedef struct Process       PROC;


/*
 *  Create DME's text icon.
 */

void makemygadget(struct Gadget *gad)
{
    static unsigned long ga[] = {
        0xFFFFFFFF,     /* 32 pixels across */
        0x80FDCBFD,
        0xFFFDDFFD,
        0x80000001,
        0x80DFDDDF,
        0x80000001,
        0xBC0EF00B,
        0x80000001,
        0xBFC00CDD,
        0x80000001,
        0xA00DF00F,
        0x80000001,
        0x80000001,

        0x80000001,
        0x80FDCBFD,
        0xFFFDDFFD,
        0x80000001,
        0x80DFDDDF,
        0x80000001,
        0xBC0EF00B,
        0x80000001,
        0xBFC00CDD,
        0x80000001,
        0xA00DF00F,
        0x80000001,
        0xFFFFFFFF
    };
    static struct Image image = {
        0, 0, 20, 16, 2, (unsigned short *)ga, 3, 0, NULL
    };
    clrmem(gad, sizeof(struct Gadget));
    gad->Width = 20;
    gad->Height = 17;
    gad->Flags  = GADGIMAGE|GADGHCOMP;
    gad->GadgetType   = BOOLGADGET;
    gad->Activation = RELVERIFY|GADGIMMEDIATE;
    gad->GadgetRender = (APTR)&image;
}

/*
 * return index of first non space.  Returns 0 if no spaces found.
 */

int firstns(char *str)
{
    short i;

    for (i = 0; str[i] && str[i] == ' '; ++i);
    if (str[i] == 0)
        i = 0;
    return((int)i);
}

/*
 *  Return index of last non-space, 0 if no spaces.
 */

int lastns(char *str)
{
    short i;

    for (i = strlen(str) - 1; i > 0 && str[i] == ' '; --i);
    if (i < 0)
        i = 0;
    return((int)i);
}

/*
 *  Return length of word under cursor
 */

int wordlen(char *str)
{
    short i;

    for (i = 0; *str && *str != ' '; ++i, ++str);
    return((int)i);
}

/*
 *  Backtracks the program lock, 0 on failure, 1 on success.
 */

int getpathto(BPTR lock, char *arg0, char *buf)
{
    FIB *fib;
    BPTR parLock = NULL, oldLock, tmpLock;
    int r = 0;
    short lastDir = 0;
    char *s;

    for(s=arg0+strlen(arg0)-1;s>=arg0;s--)
        if(*s == ':' || *s == '/')
            break;
    if(s < arg0)
        s = NULL;
    else {
        if(*s == '/')
            oldLock = CurrentDir(lock);
        strncpy(buf,arg0,s-arg0+1);
        buf[s-arg0+1] = 0;
        tmpLock = lock = Lock(buf,ACCESS_READ);
    }
    buf[0] = 0;
    if (fib = malloc(sizeof(FIB))) {
        r = 1;
        while (lock) {
            fib->fib_FileName[0] = 0;
            if (Examine(lock, fib) == 0)
                r = 0;
            if (parLock) {
                parLock = ParentDir(lock);
                UnLock(lock);
            } else {
                parLock = ParentDir(lock);
                if (fib->fib_DirEntryType > 0)
                    lastDir = 1;
            }
            if (parLock == NULL)
                strins(buf, ":");
            else if(fib->fib_DirEntryType > 0)
                strins(buf, "/");
            strins(buf, fib->fib_FileName);
            lock = parLock;
        }
        free(fib);
    }
    if(s) {
        if(*s == '/')
            CurrentDir(oldLock);
        UnLock(tmpLock);
        strcat(buf,s+1);
    }
    else
        strcat(buf,arg0);
    return(r);
}

/*
 *  Allocation routines and other shortcuts
 */

void *allocb(int bytes)
{
    return(AllocMem(bytes, MEMF_CLEAR|MEMF_PUBLIC));
}

void *allocl(int lwords)
{
    return(AllocMem(lwords<<2, MEMF_CLEAR|MEMF_PUBLIC));
}

void bmovl(void *s, void *d, int n)
{
    movmem(s, d, n << 2);
}

/*
 *  Remove tabs in a buffer
 */

int detab(char *ibuf, char *obuf, int maxlen)
{
    short i, j;

    maxlen -= 2;
    for (i = j = 0; ibuf[i] && j < maxlen; ++i) {
        if (ibuf[i] == 9) {
            do {
                obuf[j++] = ' ';
            } while ((j & 7) && j < maxlen);
        } else {
            obuf[j++] = ibuf[i];
        }
    }
    if (j && obuf[j-1] == '\n')
        --j;
/* Removed by KL
    while (j && obuf[j-1] == ' ')
        --j;
*/
    obuf[j] = 0;
    return((int)j);
}

int xefgets(FILE *fi, char *buf, int max)
{
    static char ebuf[256];
    ebuf[0] = 0;

    if (fgets(ebuf, max, fi))
        return(detab(ebuf, buf, max));
    return(-1);
}

int ncstrcmp(ubyte *s1, ubyte *s2)
{
    ubyte c1, c2;

    for (;;) {
        c1 = *s1;
        c2 = *s2;
        if (isupper(c1)) c1 |= 0x20;
        if (isupper(c2)) c2 |= 0x20;
        if (c1 != c2)
            break;
        if ((c1|c2) == 0)
            return(0);
        ++s1;
        ++s2;
    }
    if (c1 < c2)
        return(-1);
    if (c1 > c2)
        return(1);
}

ED *finded(char *str, int doff)
{
    ED *ed;

    for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) {
        if (strlen(ed->Name) >= doff && ncstrcmp(str, ed->Name+doff) == 0)
            return(ed);
    }
    return(NULL);
}

void mountrequest(int bool)
{
    static APTR original_pr_WindowPtr = NULL;
    register PROC *proc;

    proc = (PROC *)FindTask(0);
    if (!bool && proc->pr_WindowPtr != (APTR)-1) {
        original_pr_WindowPtr = proc->pr_WindowPtr;
        proc->pr_WindowPtr = (APTR)-1;
    }
    if (bool && proc->pr_WindowPtr == (APTR)-1)
        proc->pr_WindowPtr = original_pr_WindowPtr;
}

char *GetDEnv(char *ename)
{
    long envLock = Lock("env:", SHARED_LOCK);
    char *str = NULL;

    if (envLock) {
        long oldLock = CurrentDir(envLock);
        FILE *fi = fopen(ename, "r");
        long siz;
        if (fi) {
            fseek(fi, 0L, 2);
            siz = ftell(fi);
            fseek(fi, 0L, 0);
            if (siz > 0 && (str = malloc(siz + 1))) {
                fread(str, siz, 1, fi);
                str[siz] = 0;
            }
            fclose(fi);
        }
        UnLock(CurrentDir(oldLock));
    }
    return(str);
}

void SetDEnv(char *ename, char *econt)
{
    long envLock = Lock("env:", SHARED_LOCK);

    if (envLock) {
        long oldLock = CurrentDir(envLock);
        FILE *fi = fopen(ename, "w");

        if (fi) {
            fwrite(econt, strlen(econt), 1, fi);
            fclose(fi);
        }
        UnLock(CurrentDir(oldLock));
    }
}


/*
 *  GETFONT()
 *
 *  This function properly searches resident and disk fonts for the
 *  font.
 */

struct Library *DiskfontBase;

FONT *GetFont(char *name, short size)
{
    FONT *font1;
    TA Ta;
    short libwasopen = (DiskfontBase != (void *)NULL);

    Ta.ta_Name  = (UBYTE *)name;
    Ta.ta_YSize = size;
    Ta.ta_Style = 0;
    Ta.ta_Flags = 0;

    font1 = OpenFont(&Ta);
    if (font1 == NULL || font1->tf_YSize != Ta.ta_YSize) {
        FONT *font2;

        if (libwasopen || (DiskfontBase = OpenLibrary("diskfont.library", 0))) {
            if (font2 = OpenDiskFont(&Ta)) {
                if (font1)
                    CloseFont(font1);
                font1 = font2;
            }
            if (libwasopen == 0)
                CloseLibrary(DiskfontBase);
        }
    }
    return(font1);
}

/*
 *  DEAD.C
 */

int DeadKeyConvert(struct IntuiMessage *msg, UBYTE *buf, 
                   int bufsize, struct KeyMap *keymap)
{
    static struct InputEvent ievent = { NULL, IECLASS_RAWKEY };
    if (msg->Class != RAWKEY)
        return(-2);
    ievent.ie_Code = msg->Code;
    ievent.ie_Qualifier = msg->Qualifier;
    ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
    return(RawKeyConvert(&ievent,(char *)buf,bufsize,keymap));
}

void *clrmem(void *ptr, size_t bytes)
{
    setmem(ptr, bytes, 0);
    return(ptr);
}

