
// TwoPoints (MemoTec) by Ivanhoe/Quality^PAT
// Tue Jun 06 21:46:41 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 <math.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 "TwoPoints (MemoTec) by Ivanhoe/Quality^PAT (06.06.1999) * USE YOUR MIND! *"
#define WINDOW_TXT1 "TwoPoints (MemoTec) Window"
#define WINDOW_TXT2 "Use your memory & imagination"
#define WINDOW_TXT3 "See you tomorrow!"
#define MAX_LINE_LENGHT 50
#define BLACK 1
#define WHITE 2
#define CODE_ESC 27

// 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 width;
   int height;
   int questions;
   int answertime;
   int speed;
   int step;
} tooltypes;

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);

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

void get_char(char *znak);
void move_char(char znak);
void loop(void);

// function

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

   if (argc==11)
   {
 	   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.width=atoi(argv[5]);
      tooltypes.height=atoi(argv[6]);
      tooltypes.questions=atoi(argv[7]);
      tooltypes.answertime=atoi(argv[8]);
      tooltypes.speed=atoi(argv[9]);
      tooltypes.step=atoi(argv[10]);
   }
   else
      error_exit("za maîo lub za duûo lini Tool Types ikonki");

   bag_libraries();
   bag_font();
   bag_window();
   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)
{
   scr=LockPubScreen(NULL);
   if (scr==NULL) error_exit("nie mogë otworzyê okna na jakimkolwiek ekranie");

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

   win=OpenWindowTags(NULL,
       WA_Left,tooltypes.leftedge,
       WA_Top,tooltypes.topedge,
       WA_Width,tooltypes.width,
       WA_Height,tooltypes.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_SimpleRefresh,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);
}

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 get_char(char *znak)
{
   SetAPen(rp,WHITE);
   Move(rp,tooltypes.width/2-4,tooltypes.height/2-4);
   Text(rp,"·",1);

   sprintf(znak,"%c",'A'+rand()%21);
}

void move_char(char znak)
{
   static int x=0;
   static int y=0;
   static int alfa=0;
   static char old_znak=0;
   double kat;

   // wymazujemy ostatnio narysowany znak

   if (old_znak!=0)
   {
      kat=(double) (alfa-tooltypes.step)*3.14/180;

      x=sin(kat)*tooltypes.width/2.3;
      y=cos(kat)*tooltypes.height/2.4;

      SetAPen(rp,0);
      Move(rp,tooltypes.width/2+x-4,tooltypes.height/2+y-4);
      Text(rp,&old_znak,1);

      Move(rp,tooltypes.width/2-x-4,tooltypes.height/2-y-4);
      Text(rp,&old_znak,1);
   }

   // rysujemy nowy znak

   kat=(double) alfa*3.14/180;

   x=sin(kat)*tooltypes.width/2.3;
   y=cos(kat)*tooltypes.height/2.4;

   SetAPen(rp,BLACK);
   Move(rp,tooltypes.width/2+x-4,tooltypes.height/2+y-4);
   Text(rp,&znak,1);

   Move(rp,tooltypes.width/2-x-4,tooltypes.height/2-y-4);
   Text(rp,&znak,1);

   alfa=(alfa+tooltypes.step)%360;

   old_znak=znak;
}

void loop(void)
{
   struct IntuiMessage *msg;
   char znak=NULL;
   int old_time,old_speed,ile_ok=0,ok=0,ile_questions=0;
   UBYTE title[MAX_LINE_LENGHT];

   SetWindowTitles(win,WINDOW_TXT2,SCREEN_TXT);

   srand(clock());

   get_char(&znak);
   old_time=clock();
   old_speed=clock();

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

         // * * *

         if (clock()>old_time+tooltypes.answertime || clas==IDCMP_VANILLAKEY)
         {
            if (clas==IDCMP_VANILLAKEY && code==tolower(znak)) ok=1;

            if (ile_questions>0)
            {
               sprintf(title,"question: %d/%d, result: %d/%d = %.2f%%",ile_questions,tooltypes.questions,ile_ok,ile_questions,100*(float)ile_ok/ile_questions);
               SetWindowTitles(win,title,SCREEN_TXT);
            }

            if (ile_questions==tooltypes.questions)
            {
               SetWindowTitles(win,WINDOW_TXT3,SCREEN_TXT);
               new_intuitext(-1,-1,title,BLACK);
               Delay(150);
               safe_exit();
            }

            get_char(&znak);

            if (ok==1)
            {
               SetAPen(rp,BLACK);
               Move(rp,tooltypes.width/2-4,tooltypes.height/2-4);
               Text(rp,"·",1);
               ile_ok++;
               ok=0;
            }

            ile_questions++;
            old_time=clock();
         }

         if (clock()>old_speed+tooltypes.speed)
         {
            move_char(znak);
            old_speed=clock();
         }
      }
   }
}
