/* INCLUDE FILES */
#include <stdio.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <exec/ports.h>
#include <exec/interrupts.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>

/* DEFINES */
#define INTUITION_REV 29
#define GRAPHICS_REV 29
#define NL 0
#define ESC 27
#define MIX 1                        /* minimale x-Koordinate des Cursors */
#define MIY 5                        /* minimale y-      -  "  -          */
#define MAY 27                       /* maximale y-      -  "  -          */
#define EOS '\0'
#define LF 10
#define GROESSE 512
#define ROT 3
#define SCHWARZ 2
#define WEISS 1
#define BLAU 0

/* VARIABLEN */
int MAS=14,                             /* Maximale Seitenzahl */
    SEITE=71, sei=71,                   /* Maximale Zeilenzahl */
    MAX=78;                             /* Maximale x-Koordinate des Crsrs*/
struct Library *OpenLibrary();
struct IntuitionBase *IntuitionBase;
struct Window *Fenster, *OpenWindow();
struct Screen *Skrien, *OpenScreen();
struct GfxBase *GfxBase;
struct RastPort *RPforte;
struct IntuiMessage *nachricht, *GetMsg();
extern struct FileHandle *Open();
struct IOStdReq message, *LNachr, *SNachr;
struct MsgPort *LPforte, *SPforte;
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
char einzeichen, buffer[512], titel[232], str[79], hel[79];
extern UBYTE *disk();
UBYTE *a[15] [72],           /* Textspeicher */
      *AllocMem();
ULONG class;
USHORT code, qualif;
/* s,z aktuelle Seite/Zeile se,ze Textende(Seite/Zeile) x,y akt. Cursor-Pos.
   bas,baz Blockanfang(Sei./Zeil.) bes,bez Blockende               */      
SHORT x=0, y=MIY, z=0, s=0, se=0, ze=0, xe, Flagge, meld, ein=FALSE,
      sicher = TRUE, blo=0, bes, bas, bez, baz;

/* TEXTFENSTER */
struct NewWindow nw = {
   0,0,640,230,    /* x1, y1, x2, y2 */
   0,1,             /* detailpen, blockpen */
   CLOSEWINDOW|MENUPICK|MOUSEBUTTONS,            /* IDCMP-Flags */
   SMART_REFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH,
   NULL,            /* erstes Gadget */
   NULL,
   (UBYTE *) "M.S.Text",
   NULL,            /* noch kein Pointer zur Window - Screen */
   NULL,            /* keine Super Bitmap*/
   0,0,0,0,
   WBENCHSCREEN};

/* MENÜVEREINBARUNGEN */
struct IntuiText rahmen_text = {
   SCHWARZ, WEISS,
   JAM1, 5, 0, NL, NL, NL };

#define MENUE_ANZAHL 3

int punkt_weiten[ MENUE_ANZAHL ] = { 111, 151, 127 };

#define MENUE_FLAG ITEMTEXT|ITEMENABLED|HIGHCOMP
#define STRICH_FLAG ITEMTEXT

struct MenuItem m1[13], m2[9], m3[5];
struct IntuiText t1[13], t2[9], t3[5];

char *Menue3_namen[] = {
   "Seitenlänge    ",
   "---------------",
   "Textbreite     ",
   "---------------",
   "Einfügen An/Aus" };

struct Menu Menue3 = {
   NL, 190, 0, 111, 10, MENUENABLED, "Einstellungen", m3 };

char *Menue2_namen[] = {
   "Block markieren   ",
   "Block kopieren    ",
   "Block löschen     ",
   "------------------",
   "Markierung löschen",
   "------------------",
   "Block laden       ",
   "Block speichern   ",
   "Block drucken     " };

struct Menu Menue2 = {
   &Menue3, 91, 0, 79, 10, MENUENABLED, "Editieren", m2 };

char *Menue1_namen[] = {
   "Laden        ",
   "Text anhängen",
   "-------------",
   "Text löschen ",
   "-------------",
   "Speichern    ",
   "-------------",
   "Drucken      ",
   "-------------",
   "Hilfe        ",
   "Info         ",
   "-------------",
   "Ende         "  };

struct Menu Menue1 = {
   &Menue2, 0, 0, 71, 10, MENUENABLED, "Dokument", m1 };

/* VEREINBARUNGEN FÜR NACHRICHTEN */
struct IntuiText request_text = {
   SCHWARZ, WEISS, JAM2, 13, 10, NL, NL, NL };
struct IntuiText ja_text = {
   BLAU, WEISS, JAM1, 7, 3, NL, (UBYTE *) "JA!", NL };
struct IntuiText nein_text = {
   ROT, WEISS, JAM2, 7, 3, NL, (UBYTE *) "NEIN!", NL };

char *FehlerText[] = {
   "Textanfang!",
   "Textende!",
   "Textspeicherende!" };
char *FrageText[] = {
   "Programm ohne Abspeichern beenden?",
   "  Text ohne Abspeichern löschen?  ",
   "  Den alten Text überschreiben?   ",
   "     Abspeichern und Beenden?     " };
char *TitelText[] = {
   "Text Laden",
   "Text Anhängen",
   "Text Speichern",
   "Block Laden",
   "Block Speichern",
   "Text Drucken",
   "Block Drucken",
   "Seitenlänge",
   "Textbreite" };

char *InfoText[] = {
   "M.S.Text wurde 1987/1988 von      ",
   "                                  ",
   "          Martin Steppler         ",
   "       Dr.-Danzebrink-Str.11      ",
   "           D-6400 Fulda           ",
   "                                  ",
   "geschrieben. Informationen über   ",
   "Bugs, Kritik, Beschwerden usw.    ",
   "nehme ich gerne entgegen, und ich ",
   "werde bei mitgesandter Diskette   ",
   "die aktuelle Version zurück-      ",
   "schicken.                         ",
   "                      Martin      " };

struct IntuiText info_text[13];

char *HilfeText[] = {
   "   Tastaturbelegung", " ",
   "   Ctrl-b   Blockanfang/-ende markieren",
   "   Ctrl-c   Block an der Position des Cursors einfügen",
   "   Ctrl-v   Markierung löschen",
   "   Ctrl-x   Block löschen", " ",
   "   Ctrl-j   Zeile löschen",
   "   Ctrl-k   Zeile ab der Position des Cursors löschen",
   "   Ctrl-l   Zeile einfügen", " ",
   "   Ctrl-a   Crsr an den Textanfang",
   "   Ctrl-s   Crsr an das Textende",
   "   Ctrl-d   Crsr an den Anfang der nächsten Textseite",
   "   Ctrl-f   Crsr an den Anfang der vorhergehenden Textseite", 
   "   Shift-Crsr-Up/Down  Crsr links oben/unten bzw. eine Bildschirmseite",
   "                       zurück/vor springen",
   "   Shift-Crsr-Lft/Rgt  Crsr an den Anfang bzw. ans Ende der Zeile", 
   "   Ctrl-q   Text unter aktuellem Namen abspeichern und Programm beenden",
   "   Ctrl-t   Textlänge und Textende anzeigen",
   "   Ctrl-e   Einfügen An/Aus",
   "   Help     Anzeige der Tastaturbelegung",
   "   Esc      Programm ohne Abspeichern verlassen"
};

/* HAUPTPROGRAMM */
main(argc, argv)
int argc;
char *argv[];
{
   struct FileHandle *handle;
   int i=0;
   int len, r, fehler, marke;
   UBYTE c, *basis;

   Allocieren();   /* Textspeicher belegen und Libs öffnen */
   Oeffnen();
   Fenster= (struct Window *)OpenWindow(&nw);
   RPforte=Fenster->RPort;

   for(len=0;len<=12;len++) {
      info_text[len] = request_text;
      info_text[len].IText = (UBYTE *)InfoText[len];
      info_text[len].NextText = &info_text[len+1];
      info_text[len].TopEdge = (len+1)*8;
      if(len>=2 && len<=4)
         info_text[len].FrontPen = ROT;
      if(len==12)
         info_text[len].FrontPen = BLAU;
   }
   info_text[12].NextText = NULL;

   fehler = OeffneConsole(SNachr,LNachr,Fenster);  /* Cons. öffnen */
   if(fehler != 0) {
      printf("Kann Console nicht öffnen!\n");
      exit(FALSE); }

   /* Menüs anlegen */
   NeuesMenue( &Menue1, Menue1_namen,m1,t1,13,punkt_weiten[0] );
   NeuesMenue( &Menue2, Menue2_namen,m2,t2, 9,punkt_weiten[1] );
   NeuesMenue( &Menue3, Menue3_namen,m3,t3, 5,punkt_weiten[2] );

   SetMenuStrip(Fenster, &Menue1);
   MenueUeberwachung(0);

   Vorbereiten(LNachr,&einzeichen);

   len=0; x=MIX; y=MIY; z=0; s=0;
   TitelZeile();     
   Einfuegen();     /* Einfügen An */
   ZSDisplay();     /* akt. Seite, Zeile u. Spalte anzeigen */
   CursorAus();

   if(argc>1)               /* eventuell Text nachladen */
      FastLoad(argv[1]);
   else {
      NamenSetzen("Noch ohne Titel");
      sprintf(titel, "Noch_ohne_Titel");
   }
   CursorAn(); Locate(y,x);

   /* HAUPTSCHLEIFE */
   FOREVER
   {
      c = HolNachr(&einzeichen);      /* Zeichen von Console einlesen */
      if(c<=31 || (c>=127 && c<= 159)) {   /* Falls Steuercode, dann */
         if(blo>0) {                       /* Tastaturabfrage */
            if(c!=1&&c!=2&&c!=3&&c!=4&&c!=6&&       /* Abrage für Block- */
               c!=9&&c!=19&&c!=22&&c!=24&&c!=155)          /* modus */
               continue;
         }
         Tastaturabfrage(c);
         if(meld == TRUE)                  /* Wenn eine Meldung anliegt, */
            Meldung();                     /* wird sie ausgegeben. */
         if(meld == FALSE)                 /* Sonst nur ZSDisplay */
            ZSDisplay();
         meld = FALSE;
         CursorAn(); Locate(y,x);          /* Cursor aktualisieren */
         continue;
      }
      if(blo>0)                          /* Keine Zeicheneingabe im Block- */
         continue;                       /* modus */
      sicher = FALSE;
      sprintf(buffer, "%c", c);
      SString();                /* Ausgabe des Buchstabens im Textfenster */
      Buchstabe(c);             /* Speicherung des Buchstabens */
      XPlusI();                 /* x-Koordinate erhöhen */
      if(meld == TRUE)
        StrKopie(str, buffer);
      ZSDisplay();
      if(meld == TRUE) {
         meld = FALSE;
         StrKopie(buffer, str);
         Meldung();
      }
      Locate(y,x);
   }
}
Menueabfrage(menue, punkt)
int menue, punkt;
{
   UBYTE *fname;

   switch(menue) {
      case 0:                                  /* Dokument */
         switch(punkt) {
            case 0:                            /* Laden */
               if((fname = (UBYTE *)disk(TitelText[0])) != NULL) {
                  if(sicher == TRUE)
                     TLaden(fname);
                  else if(auto_frage(FrageText[2])==TRUE)
                     TLaden(fname);
               }
               break;
            case 1:                            /* Text Anhängen */
               if((fname = (UBYTE *)disk(TitelText[1])) != NULL)
                  TextAnhaengen(fname);
               break;
            case 3:                            /* Text Löschen */
               if(sicher == TRUE) {
                  TLoeschen();
                  break;
               }
               if(auto_frage(FrageText[1]) == TRUE) {
                  TLoeschen();
                  sicher == TRUE;
               }
               break;
            case 5:                            /* Speichern */
               if((fname = (UBYTE *)disk(TitelText[2])) != NULL)
                  Speichern(fname, 0, 0, se, ze);
               break;
            case 7:                                /* Drucken */
               drucken(TitelText[5], 0, 0, se, ze);
               break;
            case 9:                                /* Hilfe */
               Hilfe();
               break;
            case 10:                               /* Info */
               nein_text.IText = (UBYTE *) "GELESEN!";
               AutoRequest(Fenster,&info_text[0],NL,&nein_text,0,0,319,152);
               nein_text.IText = (UBYTE *) "NEIN!";
               break;
            case 12:                               /* Ende */
               if(sicher==TRUE) {
                  Schluss();
                  exit();
               }
               if(auto_frage(FrageText[0])==TRUE) {
                  Schluss();
                  exit();
               }
               break;
         }
         break;
      case 1:                                       /* Editieren */
         switch(punkt) {
            case 0:                                 /* Block markieren */
               BlockMarkieren();
               if(meld==TRUE) {
                  meld=FALSE; Meldung();
               }
               break;
            case 1:                                /* Block kopieren */
               BlockEinfuegen();
               meld=FALSE; Meldung();
               break;
            case 2:                                /* Block Löschen */
               BlockLoeschen();
               meld=FALSE; Meldung();
               break;
            case 4:                             /* Markierung löschen */
               MarkierungLoeschen();
               meld=FALSE; Meldung();
               break;
            case 6:                                 /* Block Laden */
               if((fname = (UBYTE *)disk(TitelText[3])) != NULL) {
                  if(se==MAS && ze==SEITE) {
                     sprintf(buffer, "%s", FehlerText[2]);
                     Meldung();
                  }
                  if(se==s && ze==z) {
                     TextAnhaengen(fname); break;
                  }
                  sprintf(buffer, "%s wird geladen!", fname);
                  Meldung();
                  BLaden(fname);
                  if(meld==TRUE) { Meldung(); meld=FALSE; }
               }
               break;
            case 7:                                 /* Block Speichern */
               if((fname = (UBYTE *)disk(TitelText[4])) != NULL) {
                  Speichern(fname, bas, baz, bes, bez);
                  sicher = FALSE;
               }
               break;
            case 8:                                /* Block Drucken */
               drucken(TitelText[6], bas, baz, bes, bez);
               break;
         }
         break;
      case 2:                                      /* Einstellungen */
         switch(punkt) {
            case 0:                                /* Seitenlänge */
               einstell(TitelText[7], 0, se, ze);
               break;
            case 2:                                /* Textbreite */
               einstell(TitelText[8], 1, se, ze);
               if(x>MAX) x=MAX; break;
            case 4:                                /* Einfügen */
               Einfuegen();
               break;
         }
         break;
   }
}
Tastaturabfrage(c)
UBYTE c;
{
   int marke = TRUE, ss, zz;

   switch(c) {
      case 155:
         c = HolNachr(&einzeichen);
         switch(c) {
            case 68:             /* Crsr left */
               XMinus();
               break;
            case 67:             /* Crsr right */
               XPlus();
               break;
            case 66:             /* Crsr down */
               YZPlus();
               break;
            case 65:             /* Crsr up */
               YZMinus();
               break;
            case 84:            /* Shift up */
               x=1;
               if(y==MIY)
                  CrsrHoch();
               else
                  CrsrTop();
               break;
            case 83:            /* Shift down */
               x=1;
               if(y==MAY) {
                  y=MIY;
                  FastText();
               }
               else
                  CrsrBot();
               break;
            case 32:
               c = HolNachr(&einzeichen);
               switch(c) {
                  case 64:                        /* Shift right */
                     StrEnde();
                     break;
                  case 65:                       /* Shift left */
                     x = 1;
                     break;
               }
               break;
            case 63:
               c = HolNachr(&einzeichen);        /* Help */
               Hilfe();
               break;
         }
         break;
      case 9:                                   /* TAB */
         for(marke=1; marke<=3; marke++) {
            XPlus();
            if(meld == TRUE)
               break;
            if(((x-1)%3) == NL)
               break;
         }
         marke = TRUE;
         break;
      case 13:                                 /* Return */
         CarRet();
         break;
      case 8:                                  /* Backspace */
         BSpace();
         sicher = FALSE;
         break;
      case 127:                                /* Delete */
         Del();
         sicher = FALSE;
         break;
      case 5:
         Einfuegen();                         /* Ctrl-e Einfügen An/Aus */
         break;
      case 10:                                /* Ctrl-j Zeile löschen */
         ZeileLoeschen();
         sicher = FALSE;
         break;
      case 11:                           /* Ctrl-k Rest der Zeile löschen */
         RestLoeschen();
         sicher = FALSE;
         break;
      case 12:                                /* Ctrl-l Zeile einfügen */
         x=MIX;
         CarRet();
         break;
      case 4:                                /* Ctrl-d Seite vorwärts */
         x=MIX; y=MIY;
         s+=1; z=0;
         if(s>se) { s=se; z=ze; marke=FALSE; }
         ss=s; zz=z;
         FastText();
         if(marke==FALSE) zz=z;
         meld=FALSE; s=ss; z=zz; x=MIX; y=MIY; ZSDisplay(); Locate(y,x);
         if(s==se && z==ze) {
            sprintf(buffer, "%s", FehlerText[1]);
            meld = TRUE;
         }
         break;
      case 6:                               /* Ctrl-f Seite rückwärts */
         x=MIX;y=MIY;
         if(z==0) {
            s=s-1;
            if(s<0) {
               s=0; marke=55;
            }
         }
         z=0; ss=s;
         FastText(); meld=FALSE;
         z=0; s=ss; x=MIX; y=MIY; ZSDisplay(); Locate(y,x);
         if(marke==55 || (s==0 && z==0)) {
            marke=meld=TRUE;
            sprintf(buffer, "%s", FehlerText[0]);
         }
         break;
      case 1:                             /* Ctrl-a Textanfang */
         s=z=0; x=MIX; y=MIY;
         FastText();
         s=z=0; x=MIX; y=MIY; ZSDisplay(); Locate(y,x);
         sprintf(buffer, "%s", FehlerText[0]);
         meld=TRUE;
         break;
      case 19:                            /* Ctrl-s Textende */
         s=se; z=ze; x=MIX; y=MIY;
         FastText();
         break;
      case 20:                            /* Ctrl-t Textlänge anzeigen */
         Textlaenge();
         break;
      case 2:                            /* Ctrl-b Block markieren */
         if(blo<3) BlockMarkieren();
         break;
      case 22:                           /* Ctrl-v Markierung löschen */
         if(blo!=0) MarkierungLoeschen();
         break;
      case 24:                           /* Ctrl-x Block löschen */
         if(blo==3) BlockLoeschen();
         break;
      case 3:                            /* Ctrl-c Block kopieren */
         if(blo==3) BlockEinfuegen();
         break;
      case 17:                           /* Ctrl-q Abspeichern u. Schluss */
         if(auto_frage(FrageText[3])==TRUE) {
            if(Speichern(titel, 0,0,se,ze)==TRUE) {
               Schluss();
               exit();
            }
         }
         break;
      case 27:                               /* ESC  Ende */
         if(sicher == TRUE) {
            Schluss();
            exit();
         }
         if(auto_frage(FrageText[0])==TRUE) {
            Schluss();
            exit();
         }
         break;
      default:
         marke = FALSE;
   }
}
Hilfe()                            /* Tastaturbelegung anzeigen */
{
   UBYTE c;
   int len, ss=s, zz=z, yy=y;

   SetAPen(RPforte, 0);
   RectFill(RPforte, 4, 43, 632, 226);
   SetAPen(RPforte, 1);
   for(len=0; len<=22; len++) {
      Move(RPforte, 4, (len+MIY+1)*8+1);
      Text(RPforte, HilfeText[len], strlen(HilfeText[len]));
   }
   c=HolNachr(&einzeichen);
   CrsrTop(); FastText(); meld=FALSE;
   s=ss; z=zz; y=yy;
   ZSDisplay(); CursorAn(); Locate(y,x);
}
