
// CramBrain (MemoTec) by Ivanhoe/Quality^PAT
// Sun Jun 20 10:55:54 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 "CramBrain (MemoTec) by Ivanhoe/Quality^PAT (20.06.1999) * USE YOUR MIND! *"
#define WINDOW_TXT1 "CramBrain (MemoTec) Window"
#define WINDOW_TXT2 "Use your memory & imagination"
#define WINDOW_TXT3 "See you tomorrow!"
#define MAX_LINE_LENGHT 50
#define MAX_QUESTION_LENGHT 20
#define MAX_ANSWER_LENGHT 20
#define MAX_WIDE_CHAR 'W'
#define MAX_WORD_LENGHT 20
#define BLACK 1
#define WHITE 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 datafile[50];
   char testfile[50];
   char fontname[50];
   int fontsize;
   int leftedge;
   int topedge;
   int questions;
   int answertime;
} tooltypes;

int datalenght=0;
struct
{
   char question[MAX_QUESTION_LENGHT];
   char answer[MAX_ANSWER_LENGHT];
   int ile_ok;
} data[500];

// 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 save_test(void);
int get_question_number(void);
void loop(void);

// function

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

   if (argc==9)
   {
 	   sprintf(tooltypes.datafile, "%.*s",strcspn(argv[1],";"),argv[1]);
 	   sprintf(tooltypes.testfile, "%.*s",strcspn(argv[2],";"),argv[2]);
 	   sprintf(tooltypes.fontname, "%.*s",strcspn(argv[3],";"),argv[3]);
      tooltypes.fontsize=atoi(argv[4]);
      tooltypes.leftedge=atoi(argv[5]);
      tooltypes.topedge=atoi(argv[6]);
      tooltypes.questions=atoi(argv[7]);
      tooltypes.answertime=atoi(argv[8]);
   }
   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,nr1;

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

   file=fopen(tooltypes.datafile,"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].question,"%.*s",strcspn(temp,","),temp);
      sprintf(data[datalenght].answer,"%.*s",strlen(temp)-strlen(data[datalenght].question)-2,temp+strcspn(temp,",")+1);

      data[datalenght].ile_ok=0;
   }

   fclose(file);

   file=fopen(tooltypes.testfile,"r");
   if (file!=NULL)
   {
      for (nr1=0;nr1<datalenght;nr1++)
      {
         if (fgets(temp,100,file)==NULL) error_exit("bīėdny plik z danymi testu");

         data[nr1].ile_ok=atoi(temp);
      }
      fclose(file);
   }

   sprintf(temp," %d",datalenght);
   x=new_intuitext(x,-1,temp,BLACK);
   new_intuitext(x,-1," questions 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 save_test(void)
{
   FILE *file;
   int nr1;
   char temp[MAX_LINE_LENGHT];

   file=fopen(tooltypes.testfile,"w");
   if (file!=NULL)
   {
      for (nr1=0;nr1<datalenght;nr1++)
         fprintf(file,"%d\n",data[nr1].ile_ok);

      fclose(file);
   }
   else
   {
      sprintf(temp,"nie mogė zapisaź pliku: %s",tooltypes.testfile);
      error_exit(temp);
   }
}

int get_question_number(void)
{
   int result,security;
   ULONG seconds,micros;

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

   for (security = 0;security < 2 * datalenght; security++)
   {
      result = rand() % datalenght;
      if (data[result].ile_ok != 3) break;
   }

   if (data[result].ile_ok == 3)
   {
      for (result = 0; result < datalenght-1; result++)
         if (data[result].ile_ok != 3) break;

      if (data[result].ile_ok == 3) result=-1;
   }

   return result;
}

void loop(void)
{
   struct IntuiMessage *msg;
   int ile_quest=0,quest_nr=0,x1=0;
   UBYTE txt[MAX_LINE_LENGHT];
   UBYTE answer[MAX_WORD_LENGHT]={NULL};
   ULONG old_time=clock();

   SetWindowTitles(win,WINDOW_TXT2,SCREEN_TXT);

   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))
         {
            save_test();
            SetWindowTitles(win,WINDOW_TXT3,SCREEN_TXT);
            Delay(150);
            safe_exit();
         }
         else if (clas==IDCMP_INACTIVEWINDOW)
         {
            ActivateWindow(win);
            DisplayBeep(scr);
         }

         // * * *

         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 (strcmp(answer,data[quest_nr].answer)==0)
            {
               data[quest_nr].ile_ok++;
               new_intuitext(-1,-1,"CORRECT! ",WHITE);
            }
            else
            {
               if (data[quest_nr].ile_ok>0) data[quest_nr].ile_ok--;
               new_intuitext(new_intuitext(-1,-1,"WRONG! ",WHITE),-1,data[quest_nr].answer,BLACK);
            }

            Delay(30);
         }

         if (ile_quest==0 || clock()>=old_time+tooltypes.answertime ||
            (clas==IDCMP_VANILLAKEY && code==CODE_ENTER))
         {
            ile_quest++;
            if (ile_quest==tooltypes.questions)
            {
               save_test();
               new_intuitext(-1,-1,"that's all today, see you!",BLACK);
               SetWindowTitles(win,WINDOW_TXT3,SCREEN_TXT);
               Delay(150);
               safe_exit();
            }

            quest_nr=get_question_number();
            if (quest_nr==-1)
            {
               save_test();
               new_intuitext(-1,-1,"no more questions!",BLACK);
               SetWindowTitles(win,WINDOW_TXT3,SCREEN_TXT);
               Delay(150);
               safe_exit();
            }

            sprintf(txt,"%d - ",tooltypes.questions-ile_quest);
            x1=new_intuitext(-1,-1,txt,BLACK);
            sprintf(txt,"%s (%d): ",data[quest_nr].question,data[quest_nr].ile_ok);
            x1=new_intuitext(x1,-1,txt,WHITE);
            answer[0]=NULL;
            sprintf(txt,"%s_",answer);
            new_intuitext(x1,-1,txt,BLACK);
            old_time=clock();
         }
      }
   }
}
