
/*
 *  KTS.C
 *
 *  Additional DME commands written by Kevin T. Seghetti fixed up and
 *  incorporated by Matt Dillon 17 April 1988.
 */

#include "defs.h"
#include <intuition/intuitionbase.h>

Prototype void PMAdd (void);
Prototype void PMRem (void);
Prototype void PMKill (struct _ED *);
Prototype int do_pushmark (void);
Prototype void do_popmark (void);
Prototype void do_swapmark (void);
Prototype void do_purgemark (void);
Prototype void do_ping (void);
Prototype void do_pong (void);
Prototype void do_winsel(void);
Prototype void do_undo (void);
Prototype void do_findfile(void);

#define BLOCKDEPTH  5
#define PINGDEPTH   10

static long BSstack[BLOCKDEPTH];
static long BEstack[BLOCKDEPTH];
static ED   *Bp[BLOCKDEPTH];
static int  CurrDepth = 0;
static char DoSel = 1;

static long PingLine[PINGDEPTH];
static long PingCol[PINGDEPTH];
static ED   *PingWin[PINGDEPTH];

void
PMAdd()
{
}

void
PMRem()
{
}

void
PMKill(ep)
ED *ep;
{
    short i, j;

    for (i = 0; i < PINGDEPTH; ++i) {       /*  remove ping-pong marks  */
        if (PingWin[i] == ep)
            PingWin[i] = NULL;
    }
    for (i = j = 0; i < CurrDepth; ++i) {   /*  remove block marks      */
        Bp[j] = Bp[i];
        if (Bp[i] != ep)
            ++j;
    }
    CurrDepth = j;
}

do_pushmark()
{
    text_sync();
    if (blockok()) {
        if (CurrDepth == BLOCKDEPTH) {
            title("pushmark: stack limit reached");
            return(-1);
        }
        BSstack[CurrDepth] = BSline;
        BEstack[CurrDepth] = BEline;
        Bp[CurrDepth] = BEp;

        ++CurrDepth;
        text_redrawblock(0);
    }
    return(0);
}

void
do_popmark()
{
    text_sync();

    if (!CurrDepth) {           /*  no error message on purpose */
        text_redrawblock(0);    /*  remove any existing block   */
        return;
    }
    text_redrawblock(0);
    --CurrDepth;
    BSline = BSstack[CurrDepth];
    BEline = BEstack[CurrDepth];
    BEp = Bp[CurrDepth];
    if (BEp == NULL || BEline >= BEp->Lines) {
        BEp = NULL;
        BSline = BEline = -1;
    } else
        text_redrawblock(1);
}

void
do_swapmark()
{
    short i;
    long *ptmp;
    long tmp;

    if (do_pushmark() < 0)
        return;
    i = CurrDepth - 2;
    if (i >= 0) {
        ptmp = PingLine + i;
        tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
        ptmp = PingCol + i;
        tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
        ptmp = (long *)PingWin + i;
        tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
    }
    do_popmark();
}

void
do_purgemark()
{
    CurrDepth = 0;
}

void
do_ping()
{
    uword num = atoi(av[1]);

    if (num >= PINGDEPTH) {
        title("ping: out of range");
        return;
    }
    PingLine[num]= Ep->Line;
    PingCol[num] = Ep->Column;
    PingWin[num] = Ep;
    title("Line marked");
}

void
do_pong()
{
    uword num = atoi(av[1]);
    extern IBASE *IntuitionBase;

    text_sync();
    if (num < 0 || num >= PINGDEPTH || !PingWin[num]) {
        title("pong: range error or nothing marked");
        return;
    }
    text_cursor(1);
    text_switch(PingWin[num]->Win);
    text_cursor(0);

    if (DoSel && IntuitionBase->ActiveWindow != Ep->Win) {
        WindowToFront(Ep->Win);
        ActivateWindow(Ep->Win);
    }
    if ((Ep->Line = PingLine[num]) >= Ep->Lines) {
        PingLine[num] = Ep->Line = Ep->Lines - 1;
    }
    Ep->Column = PingCol[num];
    text_load();
    text_sync();
}

void
do_winsel()
{
    if (av[1][0]) {
        switch(av[1][1] & 0x1F) {
        case 'n' & 0x1F:
            DoSel = 1;
            break;
        case 'f' & 0x1F:
            DoSel = 0;
            break;
        case 'o' & 0x1F:
            DoSel ^= 1;
            break;
        }
    }
}

void do_findfile()
{
    ED *ep;
    short i,l = strlen(av[1]);
    /* uword num = atoi(av[1]); */
    extern IBASE *IntuitionBase;

    text_sync();
    for (ep = Ep;ep;ep = (ED *)(ep->Node.mln_Succ)) {
        i = strlen(ep->Name);
        if(i >= l && !strcmp(av[1],ep->Name+i-l) && (i == l || ep->Name[i-l-1] == ':' || ep->Name[i-l-1] == '/'))
            break;
    }
    if(!ep)
        for (ep = (ED *)(Ep->Node.mln_Pred);ep;ep = (ED *)(ep->Node.mln_Pred)) {
            i = strlen(ep->Name);
            if(i >= l && !strcmp(av[1],ep->Name+i-l) && (i == l || ep->Name[i-l-1] == ':' || ep->Name[i-l-1] == '/'))
                break;
        }
    if(!ep) {
        title("No buffer by that name");
        return;
    }

    text_cursor(1);
    text_switch(ep->Win);
    text_cursor(0);

    if (IntuitionBase->ActiveWindow != Ep->Win) {
        WindowToFront(Ep->Win);
        ActivateWindow(Ep->Win);
    }
    text_load();
    text_sync();
}

void
do_undo()
{
    text_load();
    text_redisplaycurrline();
}

