
// ChainTown (MemoTec) by Ivanhoe/Quality^PAT
// Sun Jun 27 20:51:52 1999
// kontakt:
// Szymon Jessa, ul. Warszawska 20/6, 89-600 Chojnice
// lub (w czasie roku akademickiego):
// Szymon Jessa, DS 10, ul. Wyspiaïskiego 7, 80-434 Gdaïsk Wrzeszcz
// email: noco@box43.gnet.pl

// include
#include <stdio.h>
#include <ctype.h>
#include <time.h>

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/diskfont.h>
#include <proto/graphics.h>

#include "sc:source/wbargs.c"

// define
#define SCREEN_TXT "ChainTown (MemoTec) by Ivanhoe/Quality^PAT (27.06.1999) * USE YOUR MIND! *"
#define WINDOW_TXT1 "ChainTown (MemoTec) Window"
#define WINDOW_TXT2 "Use your memory & imagination"
#define WINDOW_TXT3 "See you tomorrow!"
#define DATA_FILE "PROGDIR:ChainTown.dat"
#define MAX_LINE_LENGHT 50
#define MAX_WORD_LENGHT 20
#define MAX_WIDE_CHAR 'W'
#define MAX_QUESTIONS 100
#define BLACK 1
#define WHITE 2
#define REMEMBER 1
#define ANSWER 2
#define CODE_ESC 27
#define CODE_ENTER 13
#define CODE_DEL 8

// variable
struct IntuitionBase *IntuitionBase=NULL;
struct Library *DiskfontBase=NULL;

struct Window *win=NULL;
struct Screen *scr=NULL;
struct RastPort *rp;
struct TextFont *font;
struct TextAttr fontattr;

struct
{
   char fontname[50];
   int fontsize;
   int leftedge;
   int topedge;
   int questions;
   int remembertime;
   int answertime;
} tooltypes;

int datalenght=0;
UBYTE data[2100][20];

// prototype

void main(int argc, char *argv[]);
void safe_exit(void);
void error_exit(UBYTE err[]);
void bag_libraries(void);
void bag_font(void);
void bag_window(void);
void bag_data(void);

int new_intuitext(int x,int y,UBYTE txt[],int col);

void loop(void);

// function

void main(int argc, char *argv[])
{
   if (argc==0)
   {
      argc=_WBArgc;
      argv=_WBArgv;
   }

   if (argc == 8)
   {
 	   sprintf(tooltypes.fontname, "%.*s",strcspn(argv[1],";"),argv[1]);
      tooltypes.fontsize=atoi(argv[2]);
      tooltypes.leftedge=atoi(argv[3]);
      tooltypes.topedge=atoi(argv[4]);
      tooltypes.questions=atoi(argv[5]);
      tooltypes.remembertime=atoi(argv[6]);
      tooltypes.answertime=atoi(argv[7]);
   }
   else
      error_exit("za maîo lub za duûo lini Tool Types ikonki");

   bag_libraries();
   bag_font();
   bag_window();
   bag_data();
   loop();
}

void safe_exit(void)
{
   if (font!=NULL) CloseFont(font);
   if (win!=NULL) CloseWindow(win);
   if (DiskfontBase!=NULL) CloseLibrary(DiskfontBase);
   if (IntuitionBase!=NULL) CloseLibrary((struct Library *) IntuitionBase);
   exit(0);
}

void error_exit(UBYTE err[])
{
   printf("wystâpiî bîâd: %s\n",err);
   safe_exit();
}

void bag_libraries(void)
{
   IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",36);
   if (IntuitionBase==NULL) error_exit("nie mogë otworzyê 'intuition.library' v>=36");

   DiskfontBase=OpenLibrary("diskfont.library",36);
	if (DiskfontBase==NULL) error_exit("nie mogë otworzyê 'diskfont.library' v>=36");
}

void bag_font(void)
{
   fontattr.ta_Name=tooltypes.fontname;
   fontattr.ta_YSize=tooltypes.fontsize;
   fontattr.ta_Style=FS_NORMAL;
   fontattr.ta_Flags=FPF_PROPORTIONAL;

   font=(struct TextFont *)OpenDiskFont(&fontattr);
   if (font==NULL) error_exit("nie mogë otworzyê czcionki");
}

void bag_window(void)
{
   int width,height;
   struct IntuiText intuitext;
   char temp[MAX_LINE_LENGHT];

   scr=LockPubScreen(NULL);
   if (scr==NULL) error_exit("nie mogë otworzyê okna na jakimkolwiek ekranie");

   // dostosowanie wymiarów okna do rodzaju czcionki
   memset(temp,MAX_WIDE_CHAR,MAX_LINE_LENGHT-1);
   temp[MAX_LINE_LENGHT-1]=NULL;

   intuitext.ITextFont=&fontattr;
   intuitext.IText=temp;

   width=IntuiTextLength(&intuitext);
   height=4*font->tf_YSize+10;

   // ewentualne centrowanie okna na ekranie
   if (tooltypes.leftedge==-1) tooltypes.leftedge=(scr->Width-width)/2;
   if (tooltypes.topedge==-1) tooltypes.topedge=(scr->Height-height)/2;

   win=OpenWindowTags(NULL,
       WA_Left,tooltypes.leftedge,
       WA_Top,tooltypes.topedge,
       WA_Width,width,
       WA_Height,height,
       WA_Title,WINDOW_TXT1,
       WA_ScreenTitle,SCREEN_TXT,
       WA_PubScreen,scr,
       WA_GimmeZeroZero,TRUE,
       WA_DragBar,TRUE,
       WA_DepthGadget,TRUE,
       WA_CloseGadget,TRUE,
       WA_Activate,TRUE,
       WA_SmartRefresh,TRUE,
       WA_AutoAdjust,TRUE,
       WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_INTUITICKS | IDCMP_VANILLAKEY | IDCMP_INACTIVEWINDOW,
       TAG_END,0);

   UnlockPubScreen(NULL,scr);

   if (win==NULL) error_exit("nie mogë otworzyê okna");

	rp=win->RPort;
   SetFont(rp,font);
}

void bag_data(void)
{
   FILE *file;
   char temp[100];
   int x;

   x=new_intuitext(-1,-1,"loading data...",WHITE);

   file=fopen(DATA_FILE,"r");

   if (file==NULL) error_exit("nie mogë odczytaê bazy danych");

   for (datalenght=0;;datalenght++)
   {
      if (fgets(temp,100,file)==NULL) break;
      sprintf(data[datalenght],"%.*s",strlen(temp)-1,temp);
   }

   fclose(file);

   sprintf(temp," %d",datalenght);
   x=new_intuitext(x,-1,temp,BLACK);
   new_intuitext(x,-1," words loaded",WHITE);

   Delay(50);
}

int new_intuitext(int x,int y,UBYTE txt[],int col)
{
   struct IntuiText intuitext;

   intuitext.FrontPen=col;
   intuitext.BackPen=BACKGROUNDPEN;
   intuitext.DrawMode=JAM1;
   intuitext.LeftEdge=0;
   intuitext.TopEdge=0;
   intuitext.ITextFont=&fontattr;
   intuitext.IText=txt;
   intuitext.NextText=NULL;

   if (x==-1) x=10;
   if (y==-1) y=font->tf_YSize-2;

   Move(rp,x,y+font->tf_YSize-2);
   ClearEOL(rp);

   PrintIText(rp,&intuitext,x,y);

   return IntuiTextLength(&intuitext)+x;
}

void loop(void)
{
   struct IntuiMessage *msg;
   int mode=REMEMBER,nr1=0;
   int seria[MAX_QUESTIONS];
   ULONG seconds,micros;
   UBYTE txt[MAX_LINE_LENGHT];
   UBYTE answer[MAX_WORD_LENGHT]={NULL};
   ULONG old_time=clock();
   int x1=0;
   int answer_ok=0;

   SetWindowTitles(win,WINDOW_TXT2,SCREEN_TXT);

   CurrentTime(&seconds,&micros);
   srand(seconds+micros);

   for (;;)
   {
      Wait((1<<win->UserPort->mp_SigBit));

      while (msg=(struct IntuiMessage *) GetMsg(win->UserPort))
      {
         ULONG clas=msg->Class;
         UWORD code=msg->Code;
         ReplyMsg((struct Message *) msg);

         if (clas==IDCMP_CLOSEWINDOW || (clas==IDCMP_VANILLAKEY && code==CODE_ESC))
            safe_exit();
         else if (clas==IDCMP_INACTIVEWINDOW)
         {
            ActivateWindow(win);
            DisplayBeep(scr);
         }

         if (mode==REMEMBER &&
            (clock()>=old_time+tooltypes.remembertime ||
            (clas==IDCMP_VANILLAKEY && code==CODE_ENTER)))
         {
            old_time=clock();
            if (nr1<tooltypes.questions)
            {
               seria[nr1]=rand() % datalenght;
               sprintf(txt,"%d of %d is: ",nr1+1,tooltypes.questions);
               new_intuitext(new_intuitext(-1,-1,txt,WHITE),-1,data[seria[nr1]],BLACK);
               nr1++;
            }
            else if (nr1==tooltypes.questions)
            {
               mode=ANSWER;
               nr1=-1;
               new_intuitext(-1,-1,"begin part two...",WHITE);
               old_time=clock()-tooltypes.answertime+1000; // 1s czekania
            }
         }
         else if (mode==ANSWER)
         {
            if (clas==IDCMP_VANILLAKEY && x1!=0)
            {
               if (code==CODE_DEL && strlen(answer)>0)
                  sprintf(answer,"%.*s",strlen(answer)-1,answer);
               else if (!iscntrl(code) && strlen(answer)<MAX_WORD_LENGHT)
                  sprintf(answer,"%s%lc",answer,code);

               sprintf(txt,"%s_",answer);
               new_intuitext(x1,-1,txt,BLACK);
            }

            if (clock()>=old_time+tooltypes.answertime ||
               (clas==IDCMP_VANILLAKEY && code==CODE_ENTER))
            {
               if (nr1>=0)
               {
                  if (strcmp(answer,data[seria[nr1]])==0)
                  {
                     answer_ok++;
                     new_intuitext(-1,-1,"CORRECT! ",WHITE);
                  }
                  else
                     new_intuitext(new_intuitext(-1,-1,"WRONG! ",WHITE),-1,data[seria[nr1]],BLACK);

                  Delay(30);
               }

               nr1++;
               if (nr1==tooltypes.questions) 
               {
                  sprintf(txt,"%d / %d",answer_ok,tooltypes.questions);
                  new_intuitext(new_intuitext(-1,-1,"result: ",WHITE),-1,txt,BLACK);
                  SetWindowTitles(win,WINDOW_TXT3,SCREEN_TXT);
                  Delay(150);
                  safe_exit();
               }
               sprintf(txt,"%d of %d: ",nr1+1,tooltypes.questions);
               x1=new_intuitext(-1,-1,txt,WHITE);
               answer[0]=NULL;
               sprintf(txt,"%s_",answer);
               new_intuitext(x1,-1,txt,BLACK);
               old_time=clock();
            }
         }
      }
   }
}
