/*
** UMRexxFcts.c - Rexx fncts for UrlManager
** Copyright (C) 1996-97 Serge Emond
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "UrlManager.h"

/// exe_AddUrl(args)
// Adds an URL to the list

// TYPE/A (String)
//   Type of Url (only first letter is used)
//
// URL/A  (String)
//   The URL itself
//
// DEPTH/N (Int)
//   The depth of the URL

// RC
//   0   Add OK - URL ID in UMRES
//   1   An url of that name is already in memory
//   2   Error adding url
//   5   Bad Args

void exe_AddUrl(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[3]={NULL, NULL, NULL};
    TEXT ret[12];
    struct Url *up;

    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        up = AddUrl(((STRPTR)opts[0])[0],                           // type
                    (opts[2] ? *((LONG *)opts[2]) : (LONG)(-1)),    // depth
                    (STRPTR)opts[1]);                               // URL

        if ((LONG)up == -1)     // Url already in mem
        {
            Reply(1, NULL);
        }
        else if (up)            // Added OK
        {
            stcul_d(ret, up->id);
            Reply(NULL, ret);
        }
        else                    // Error adding
        {
            Reply(2, NULL);
        }
        FreeArgs(&rda);
    }
}
///

/// exe_CountType (args)

// Returns the type of url id ID in UMRES

// TYPE/A    (string)
//       Type to count

// RC
//   0   OK
//   5   Error parsing args

void exe_CountType(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    TEXT txt[12];

    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        stcul_d(txt, CountType( *(TEXT *)opts[0] ));
        Reply(0, txt);
        FreeArgs(&rda);
    }
}
///

/// exe_FlushAll (args)

// Flush url-list

// RC:
//   0   OK
//   99  Could not allocate memory - I should quit...

void exe_FlushAll(STRPTR p)
{
    if (FlushAll()) Reply(NULL, NULL);
    else Reply(99, NULL);
}
///

/// exe_GetDepth (args)

// Returns the depth of url id ID in UMRES

// ID/A/N    (int)
//       ID of the url we want to know about..

// RC
//   0   OK
//   1   No url of that ID
//   5   Error parsing args

void exe_GetDepth(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    TEXT retd[13];
    struct Url *up;
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID(*(ULONG *)opts[0]))
        {
            stcl_d(retd, up->depth);
            Reply(NULL, retd);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_GetHID (args)
// Puts highest ID number if UMRES

void exe_GetHID(STRPTR p)
{
    TEXT tmp[12];
    stcul_d(tmp, g.hid);
    Reply(NULL, tmp);
}
///

/// exe_GetInMem (args)
// Dumps the number of urls in memory in UMRES

void exe_GetInMem(STRPTR p)
{
    TEXT tmp[12];
    stcul_d(tmp, g.inmem);
    Reply(NULL, tmp);
}
///

/// exe_GetType (args)

// Returns the type of url id ID in UMRES

// ID/A/N    (int)
//       ID of the url we want to know about..

// RC
//   0   OK
//   1   No url of that ID
//   5   Error parsing args

void exe_GetType(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    TEXT rettype[2];
    struct Url *up;
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID(*(ULONG *)opts[0]))
        {
            rettype[0] = up->type;
            rettype[1] = NULL;
            Reply(NULL, rettype);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_GetUrl (args)

// Returns URL associated with an ID.

// ID/A/N    (int)

// RC
//   0   OK
//   1   No url of that ID
//   5   Error parsing args

void exe_GetUrl(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    struct Url *up;
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID(*(ULONG *)opts[0]))
        {
            Reply(NULL, up->name);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_KillPattern (args)

// Kills all urls matching a pattern

// PATTERN/A (string)
//       Pattern matching urls to kill

// RC
//   0   OK  - Number of urls killed in UMRES
//   5   Error parsing args

void exe_KillPattern(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    ULONG cnt;
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        cnt = KillPattern((STRPTR)opts[0]);
        stcul_d(ret, cnt);
        Reply(NULL, ret);
        FreeArgs(&rda);
    }
}
///

/// exe_KillType (args)

// Kills all urls of a type

// TYPE/A    (string)
//       Type to kill - only the first letter will be used

// RC
//   0   OK  - Number of urls killed in UMRES
//   5   Error parsing args

void exe_KillType(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    ULONG cnt;
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        cnt = KillType(toupper(((TEXT *)opts[0])[0]));
        stcul_d(ret, cnt);
        Reply(NULL, ret);
        FreeArgs(&rda);
    }
}
///

/// exe_KillUrl (args)

// Kill url id ID

// ID/A/N    (int)
//       ID of the url we want to kill

// RC
//   0   OK
//   1   No url of that ID
//   5   Error parsing args

void exe_KillUrl(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (KillUrl(*(ULONG *)opts[0])) Reply(NULL, NULL);
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_LoadFile (args)

// Load a file

// FILE/A    (string)
//       Name of the file to get urls from

// RC
//   0   OK - Number of urls added in UMRES
//   1   Error opening/parsing file

void exe_LoadFile(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    ULONG cnt;
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        cnt = LoadFile((STRPTR)opts[0]);
        if (cnt == -1) Reply(1,NULL);
        else
        {
            stcul_d(ret, cnt);
            Reply(NULL, ret);
        }
        FreeArgs(&rda);
    }
}
///

/// exe_MatchName (args)

// Exact match of an URL

// NAME/A    (string)
//       Name to exact-match
// NOCASE/S  (BOOL)
//       If present, case insensitive

// RC
//   0   Found - ID in UMRES
//   1   No match
//   5   Error parsing args

void exe_MatchName(TEXT *p)
{
    struct RDArgs rda;
    struct Url *up;
    LONG opts[2]={NULL, NULL};
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        up = MatchName((TEXT *)opts[0], opts[1]);
        if (up)
        {
            stcul_d(ret, up->id);
            Reply(NULL, ret);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_Quit(args)
// Quit UrlManager

void exe_Quit(STRPTR p)
{
    Reply(NULL, NULL);
    EndAll(NULL);
}
///

/// exe_ReadFile (args)

// Load a file
// FILE/A    (string)
//       Name of the file to get urls from
// TYPE/A    (string)
//       Type of urls we are adding (only the 1st car is used..)
// DEPTH/N   (int)
//       Depth of urls we add.  If absent, depth = -1.

// RC
//   0   OK - Number of urls added in UMRES
//   1   Error openning/parsing file

void exe_ReadFile(STRPTR p)
{
    struct RDArgs rda;
    LONG opts[3]={NULL, NULL, NULL};
    ULONG cnt;
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        cnt = ReadFile((TEXT *)opts[0], toupper(((TEXT *)opts[1])[0]),
                    (opts[2] ? *((LONG *)opts[2]) : (LONG)-1 ));
        if (cnt == -1) Reply(1,NULL);
        else
        {
            stcul_d(ret, cnt);
            Reply(NULL, ret);
        }
        FreeArgs(&rda);
    }
}
///

/// exe_SaveFile (args)

// Save urls to file

// FILE/A        (string)
//       Name of file to save urls to
// TYPE/K        (string)
//       Save only urls of that type (only first car..)
// PATTERN/K     (string)
//       Save only urls matching that AmigaDOS pattern
// APPEND/S      (BOOL)
//       If present, append to file instead of overwriting
// FULL/S        (BOOL)
//       If present, each line of savefile will be:
//           <type> <depth> <url>
//       If absent, each line will contain only the URL

// RC
//   0   Saved OK
//   1   Error saving file
//   5   Error Parsing Args

void exe_SaveFile(TEXT *p)
{
    struct RDArgs rda;
    LONG opts[5]={NULL, NULL, NULL, NULL, NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (!SaveFile((TEXT *)opts[0], (opts[1] ?
                        toupper(((TEXT *)opts[1])[0]) : NULL),
                        (opts[2] ? (TEXT *)opts[2] : NULL),
                        (BOOL)opts[3], (BOOL)opts[4])) Reply(1, NULL);
        else Reply(NULL, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_Search (args)

// Search in the list...

// MINID/A/N     (int)
//       Minimal ID number to search (0 returns the 1st :)
// PATTERN/K     (string)
//       If present, find an url matching that pattern (AmigaDOS pattern)
// TYPE/K        (string)
//       If present, search for a specific type (only the first char ...)

// RC
//   0   Worked OK - ID found in UMRES.  If UMRES = 0, nothing found
//   1   Error parsing args

void exe_Search(STRPTR p)
{
    struct RDArgs rda;
    struct Url *up;
    LONG opts[3]={NULL, NULL, NULL};
    TEXT ret[12];
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        up = Search(*((ULONG *)opts[0]), (STRPTR)opts[1],
                    (opts[2]? toupper(((STRPTR)opts[2])[0]) : NULL));
        if (up)
        {
            stcul_d(ret, up->id);
            Reply(NULL, ret);
        }
        else Reply(NULL, "0");          /* Nothing found */
        FreeArgs(&rda);
    }
}
///

/// exe_SetDepth (args)

// Set the depth of an url

// ID/A/N    (int)
//       ID of url to modify
// DEPTH/A/N (int)
//       New depth

// RC
//   0   Done..
//   1   ID inexistent
//   5   Error parsing args

void exe_SetDepth(STRPTR p)
{
    struct RDArgs rda;
    struct Url *up;
    LONG opts[2]={NULL, NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID((ULONG)*((ULONG *)opts[0])))
        {
            up->depth = *((LONG *)opts[1]);
            Reply(NULL, NULL);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_SetIOSize (args)

// Set size of IO buffer.

// SIZE/A/N      (int)
//       Size of IOBufferSize (1024 if SIZE is < 1024) (default: 4096)

// RC
//   0   OK
//   5   ...

void exe_SetIOSize(TEXT *p)
{
    struct RDArgs rda;
    LONG opts[1]={NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        g.iosize = (*((ULONG *)opts[0]) < MINIOSIZE ? MINIOSIZE : *((ULONG *)opts[0]));
        Reply(NULL, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_SetType (args)

// Set the type of an url

// ID/A/N    (int)
//       ID of url to modify
// TYPE/A    (string)
//       New type (only 1st char is used..)

// RC
//   0   Done..
//   1   ID inexistent
//   5   Error parsing args

void exe_SetType(STRPTR p)
{
    struct RDArgs rda;
    struct Url *up;
    LONG opts[2]={NULL, NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID(*(ULONG *)opts[0]))
        {
            up->type = ((STRPTR)opts[1])[0];
            Reply(NULL, NULL);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// exe_SetUrl (args)

// Set the name of an url

// ID/A/N    (int)
//       ID of url to modify
// URL/A     (string)
//       New URL

// RC
//   0   Done..
//   1   ID inexistent
//   5   Error parsing args

void exe_SetUrl(STRPTR p)
{
    struct RDArgs rda;
    struct Url *up;
    LONG opts[2]={NULL, NULL};
    
    if (!ReadAVar(fcts[g.exenmb].temp, opts, &rda, p)) Reply(5, NULL);
    else
    {
        if (up = GetID((ULONG)*((ULONG *)opts[0])))
        {
            strcpy(up->name, (STRPTR)opts[1]);
            Reply(NULL, NULL);
        }
        else Reply(1, NULL);
        FreeArgs(&rda);
    }
}
///

/// Functions

struct Functions fcts[] = {
    { "ADDURL",         "TYPE/A,URL/A,DEPTH/N", exe_AddUrl },
    { "COUNTTYPE",      "TYPE/A",               exe_CountType },
    { "FLUSHALL",       NULL,                   exe_FlushAll },
    { "GETDEPTH",       "ID/A/N",               exe_GetDepth },
    { "GETHID",         NULL,                   exe_GetHID },
    { "GETINMEM",       NULL,                   exe_GetInMem },
    { "GETTYPE",        "ID/A/N",               exe_GetType },
    { "GETURL",         "ID/A/N",               exe_GetUrl },
    { "KILLPATTERN",    "PATTERN/A",            exe_KillPattern },
    { "KILLTYPE",       "TYPE/A",               exe_KillType },
    { "KILLURL",        "ID/A/N",               exe_KillUrl },
    { "LOADFILE",       "FILE/A",               exe_LoadFile },
    { "MATCHNAME",      "NAME/A,NOCASE/S",      exe_MatchName },
    { "QUIT",           NULL,                   exe_Quit },
    { "READFILE",       "FILE/A,TYPE/A,DEPTH/N",    exe_ReadFile },
    { "SAVEFILE",       "FILE/A,TYPE/K,PATTERN/K,APPEND/S,FULL/S",  exe_SaveFile },
    { "SEARCH",         "MINID/A/N,PATTERN/K,TYPE/K",   exe_Search },
    { "SETDEPTH",       "ID/A/N,DEPTH/A/N",     exe_SetDepth },
    { "SETIOSIZE",      "SIZE/A/N",             exe_SetIOSize },
    { "SETTYPE",        "ID/A/N,TYPE/A",        exe_SetType },
    { "SETURL",         "ID/A/N,URL/A",         exe_SetUrl },
    { NULL,             NULL,   (void *)NULL } };

///

