

              /*  stor.c  ---   gotta stick'm someplace!  */

#include <exec/memory.h>
#include <ctype.h>
#include "stuff.h"

#define ABS(x) ((x<0)?(-(x)):(x))


        extern struct Screen   *scr;
        extern struct Window   *win;
        extern struct RastPort *reep;
        extern ULONG            thisCol;
        extern    int           curOnion;
        extern    int           togOnion;
        extern struct Gadget    TGads [];
        extern  UWORD           mrQ;
               struct Window   *seqwin;
               struct Window   *clipWin;

    UBYTE sequence [SEQLEN] = (UB) "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16";
    struct SUPERwindow SuperWindows [ maxsupwin ];
    int CurrentWindow = 0;

    SS NewWindow winstamp = {  237,12, ImageWid + 8, MaxDN + 27, 0,1,
        CLOSEWINDOW | MOUSEBUTTONS /* IDCMP */, WINDOWCLOSE |
        WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | RMBTRAP /* Flags */,
        NL,NL,NL,NL,NL,0,0,0,0, CUSTOMSCREEN };


NewSuperWindow ()
{
    REG int okay = 0;
    char nookie [126];


    while (swin (okay) && okay < maxsupwin)  ++okay;
    if (okay >= maxsupwin)  {  ALERT ("Too many windows!");  RET 0;  }
    winstamp.DetailPen  =  okay      % 16;
    winstamp.BlockPen   = (okay + 8) % 16;
    winstamp.Screen     = scr;

    IFN (swin (okay) = OpenWindow (&winstamp))  {
        ALERT ("No Chips Left!  No More Windows!");  RET 0;  }

    SetAPen (zreep (okay) = swin (okay)->RPort, 22L);
    decimal (okay, nookie);
    Move (zreep (okay), 8L, (long) MaxDN + 22L);
    Text (zreep (okay), nookie, (long) strlen (nookie));
    SetAPen (zreep (okay), (long) thisCol);
    newactive (okay);
    return 1;

}


                      void
dealwithit (idx, msg)  struct IntuiMessage *msg;
{

    SWITCH (msg->Class) {
        CS MOUSEBUTTONS:
            if (msg->Code != SELECTUP)    RET;
            if (swin (idx)->MouseY <= 8)  RET;

            if izCtrl (msg->Qualifier & Qmask)  {
                if (idx == curOnion)  {
                    if (togOnion)  Mess ("This IS the Shadow Image!!!");
                    return;  }

                ifn (togOnion)  {  togOnion = 1;  onionOn ();  }
                newOnion (curOnion = idx);  RET;  }

            newactive (idx);
            blow ();
            return;

        CS CLOSEWINDOW:
            deadwindow (idx);
            return;  }

}


                void
newactive (idx)
{

    if swin (CurrentWindow)  SetWindowTitles (swin (CurrentWindow), "  ", -1L);
    if swin (idx)      SetWindowTitles (swin (CurrentWindow = idx), "IT", -1L);

}


            /*   void*/
deadwindow (idx)
{

    if (idx == CurrentWindow)  {  Mess ("You can't close \"It\"!");  RET;  }

    if (idx == curOnion && togOnion)  {
        Mess ("You can't close the Shadow Image!"); RET;}

    if (idx == curOnion)  curOnion = CurrentWindow;
    if (swin (idx))  CloseWindow (swin (idx));
    swin (idx) = NL;
    zreep (idx) = NL;

}


        void
stor ()
{

    ifn (NewSuperWindow ())  return;
    suck ();

    if (curOnion + 2 == CurrentWindow && swin (CurrentWindow - 1))
        newOnion (++curOnion);

}


                void
zapAllWindows ()
{
    REG int k = maxsupwin;


    while (k--)  if (swin (k))  CloseWindow (swin (k));

}


        void
stack ()
{
    REG int k = maxsupwin;


    WindowToFront (swin (CurrentWindow));

    while (k--)
        if (swin (k) && k != CurrentWindow)
            MoveWindow (swin (k),
                (LONG) swin (CurrentWindow)->LeftEdge - swin (k)->LeftEdge,
                (LONG) swin (CurrentWindow)-> TopEdge - swin (k)-> TopEdge);

}


    SS NewWindow clipwinstamp = {  0,0,0,0, 0,1,
        MOUSEBUTTONS /* IDCMP */,
        WINDOWDRAG | SMART_REFRESH | RMBTRAP /* Flags */,
        NL,NL,NL,NL,NL,0,0,0,0, CUSTOMSCREEN };

#define INSIDE(x,j) ((x) >= 36 && (x) < 36 + ImageWid * Ratio && \
                     (j) >= 21 && (j) < 21 + MaxDN * Ratio)

                   void
clipAction (clipQ)  UWORD clipQ;
{
    REG USHORT xx, yy, xxx, yyy;
    ULONG wasCol = thisCol;
    extern int popping;
    int waspopping = popping;

    USHORT lef = clipWin->LeftEdge,  top = clipWin->TopEdge,
           max = clipWin->Width - 3, may = clipWin->Height - 3;


    Mess ("Copying ...");
    offInput ();
    popping = 0;

    LOOP     (xx =  4;  xx < max;  xx += Ratio)
        loop (yy = 12;  yy < may;  yy += Ratio)  {
            xxx = xx + lef;  xxx -= xxx % Ratio;
            yyy = yy + top;  yyy -= yyy % Ratio;
            thisCol = ReadPixel (clipWin->RPort, (long) xx, (long) yy);

            switch (clipQ)  {
              case LSHIFT:
              case RSHIFT:
                if (wasCol == thisCol)  continue;
                break;

              case RALT:
              case LALT:
                if (wasCol != thisCol)  continue;
                break;

              case RCOM:
                if (wasCol == ReadPixel (reep, (long) xxx, (long) yyy))
                    continue;

                break;

              case LCOM:
                if (wasCol != ReadPixel (reep, (long) xxx, (long) yyy))
                    continue;

            }                      /*  could be worse ...  could be PC-DOS  */

            if INSIDE (xxx, yyy)  maybedospot (xxx, yyy);  }     /* uh huh  */

    Mess ("Done Copying");
    onInput ();
    thisCol = wasCol;
    popping = waspopping;

}


        void
doBox ()
{
    extern USHORT Mx, My;
    int cX = Mx - Mx % Ratio - 2, cY = My - My % Ratio - 2, eX, eY;
    void rectal ();
    extern ULONG msgclass;
    extern USHORT msgcode;


    SetDrMd (reep, COMPLEMENT);

    do  {  extern int picking, no_help;
        eX = Mx + Ratio - Mx % Ratio - 2;
        eY = My + Ratio - My % Ratio - 2;
        if (eX < 35)  eX = 35;
        if (eY < 21)  eY = 21;
        if (eX > 36 + ImageWid * Ratio)  eX = 36 + ImageWid * Ratio;
        if (eY > 21 + MaxDN    * Ratio)  eY = 21 + MaxDN    * Ratio;
        rectal (cX, cY, eX, eY);
        picking = no_help = 1;
        ifn (input ())  quit ("bye!");
        picking = no_help = 0;
        rectal (cX, cY, eX, eY);  }
    while (msgclass == MOUSEMOVE ||
        (msgclass == MOUSEBUTTONS && msgcode == SELECTDOWN) /* && izShift (mrQ */);

    if (ABS (cX - eX) < Ratio * 3 || ABS (cY - eY) < Ratio * 3)  goto labull;
    clozeClipWin ();
    clipwinstamp.DetailPen  =  20;
    clipwinstamp.BlockPen   =  29;
    clipwinstamp.Screen     = scr;
    clipwinstamp.LeftEdge   = (cX < eX? cX: eX) -  3;
    clipwinstamp.TopEdge    = (cY < eY? cY: eY) - 12;
    clipwinstamp.Width      = ABS (cX - eX) +  6;
    clipwinstamp.Height     = ABS (cY - eY) + 15;
    clipwinstamp.Title      = (UB) "ClipBoard";

    IFN (clipWin = OpenWindow (&clipwinstamp))  {
        ALERT ("Can't Copy Rectangle!  Lo Mem!");  goto labull;  }

    ClipBlit (reep, (long) (cX < eX? cX: eX), (long) (cY < eY? cY: eY),
        clipWin->RPort, 3L, 12L, (long) ABS(cX-eX), (long) ABS(cY-eY), 0x0c0L);

    Mess ("Move & Click to Copy; Ctrl == Kill");

labull:
    SetDrMd (reep, JAM2);

}


void clozeClipWin ()  {  if (clipWin)  CloseWindow (clipWin);  clipWin = NL;  }


                      void
rectal (x, y, xx, yy)
{

    RectFill (reep, (long) (x < xx? x: xx), (long) (y < yy? y: yy),
                    (long) (x < xx? xx: x), (long) (y < yy? yy: y));

}


            void
offInput ()
{

    ModifyIDCMP (win, NULL);

}


            void
onInput ()
{

    ModifyIDCMP (win, CLOSEWINDOW | MOUSEMOVE | MOUSEBUTTONS |
                      GADGETUP | RAWKEY | INACTIVEWINDOW);

}


    UBYTE timer [6] = (UB) "5";

    SS StringInfo timeinfo = { timer, NL, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5 };

    SS Gadget timegad = { NL,252,12,48,18, GADGHCOMP,STRINGCENTER|
        RELVERIFY|LONGINT,STRGADGET,NL,NL,NL,NL,(APTR) &timeinfo,0,NL};

    SS StringInfo infoname = { sequence, NL, 0, 120 };

    SS Gadget gadname = { &timegad,8,12,240,18, GADGHCOMP,STRINGCENTER|
        RELVERIFY,STRGADGET,NL,NL,NL,NL,(APTR) &infoname,SQSTG,NL};

    SS NewWindow seqwinstamp = { 0, 158, 319, 24, 4,8, CLOSEWINDOW /* IDCMP */,
        WINDOWCLOSE|WINDOWDEPTH|ACTIVATE|WINDOWDRAG|SMART_REFRESH|RMBTRAP /* Flags */,
        &gadname, NL,NL,NL,NL,0,0,0,0, CUSTOMSCREEN };

              void
openSeqWin ()
{

    seqwinstamp.Screen = scr;
    seqwinstamp.Title  = (UB) "Image Sequence ============= Time";
    Mess ("Time == Tenths of Seconds");

    ifn (seqwin = OpenWindow (&seqwinstamp))  {
        ALERT ("Low Chip Mem!  Sorry!");  RET;  }

    Delay (2L);
    ActivateGadget (&gadname, seqwin, NL);            /*  this is a no-no!  */
    SetAPen (seqwin->RPort, 4L);
    Move (seqwin->RPort, 253L, 11L);
    Draw (seqwin->RPort, 253L, 20L);

}


               void
closeSeqWin ()
{

    if (seqwin)  {
        seqwinstamp.TopEdge = seqwin->TopEdge;
        CloseWindow (seqwin);  }

    seqwin = NL;

}                                      /*  user friendliness strikes again  */


        void
roll ()                   /*  make a little movie out of the window images  */
{
    SS NewWindow d = {  0,0, 320, 186, 0,1, MOUSEBUTTONS /* IDCMP */,
        SMART_REFRESH | ACTIVATE | RMBTRAP /* Flags */,
        NL,NL,NL,NL,NL,0,0,0,0, CUSTOMSCREEN };

    REG int evil;
    char *good;
    struct Window *newwin, *realwin;
    struct IntuiMessage *mail;


    d.Screen = scr;

    if (newwin = OpenWindow (&d))
        realwin = newwin;
    else  {
        realwin = win;
        SetAPen (reep, 0L);
        RectFill (reep, 35L, 20L, ImageWid * Ratio + 36L, MaxDN * Ratio + 21L);
        SetAPen (reep, thisCol);  }

    Mess ("L-Mouse == Quit, R-Mouse == Seq");
    offInput ();
    ifn (newwin)  ModifyIDCMP (win, MOUSEBUTTONS);

doThatAgain:
    while (!(mail = (struct IntuiMessage *)  GetMsg (realwin->UserPort)))  {
        good = (char *) sequence;
        while (!isdigit (*good) && *good)  ++good;

        while (good < &sequence [SEQLEN - 1] && *good)  {
            evil = atoi (good);

            if (evil >= 0 && evil < maxsupwin && swin (evil))  {
                ClipBlit (zreep (evil), 4L, 14L, realwin->RPort, 113L, 69L,
                                (LONG) ImageWid, (LONG) MaxDN, (LONG) 0xc0);

                if (mail = (struct IntuiMessage *)
                    GetMsg (realwin->UserPort))  goto f__kPascal;

                Delay (timeinfo.LongInt > 100L? 100L: timeinfo.LongInt);  }

            while ( isdigit (*good) && *good)  ++good;
            while (!isdigit (*good) && *good)  ++good;
        }                                  /*  end of while-therez-numbers  */
    }                                                   /*  end of forever  */

f__kPascal:                     /*  gad what a mess.  Looks like BASIC ...  */
    if (mail->Class == MOUSEBUTTONS &&
       (mail->Code == MENUUP || mail->Code == MENUDOWN))  {
        if (mail->Code == MENUUP)  {  ReplyMsg (mail);  goto doThatAgain;  }
        if (seqwin)  WindowToFront (seqwin);  else  openSeqWin ();
        ReplyMsg (mail);
        goto doThatAgain;  }

    ReplyMsg (mail);

    if (newwin)
        CloseWindow (newwin);
    else  {
        SetAPen (reep, 0L);
        RectFill (reep, 35L, 20L, ImageWid * Ratio + 36L, MaxDN * Ratio + 21L);
        SetAPen (reep, thisCol);
        redrawWorkArea (0);  }

    Mess ("That's All, Folks!");
    onInput ();

}  /*  I don't need a pretentious language like Pascal to pretend it's a mathematical proof, and treat both the computer it lives in and the programmer who suffers for it like naughty children it has to spank all the time.  Those who actually like this sort of thing may also like sticking their heads up their asses and yodelling.  */
