//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

char *p1="Paleczka1";
char *p2="Paleczka2";
char *p3="Paleczka3";
char *p4="Paleczka4";
char *p5="Paleczka5";

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner),nr1(0),nr2(1),nr3(2),nr4(3),nr5(4)
{

   F[0].lewa=F1lewa;
   F[0].je=F1je;
   F[0].pusty=F1bez;
   F[1].lewa=F2lewa;
   F[1].je=F2je;
   F[1].pusty=F2bez;
   F[2].lewa=F3lewa;
   F[2].je=F3je;
   F[2].pusty=F3bez;
   F[3].lewa=F4lewa;
   F[3].je=F4je;
   F[3].pusty=F4bez;
   F[4].lewa=F5lewa;
   F[4].je=F5je;
   F[4].pusty=F5bez;

   for (int i=0; i<5; i++)
   {
      F[i].lewa->Visible=false;
      F[i].je->Visible=false;
      czas[i]=0;
      ChceJesc[i]=false;
   }


   PALECZKA[0]=CreateSemaphore(NULL,1,1,p1);
   PALECZKA[1]=CreateSemaphore(NULL,1,1,p2);
   PALECZKA[2]=CreateSemaphore(NULL,1,1,p3);
   PALECZKA[3]=CreateSemaphore(NULL,1,1,p4);
   PALECZKA[4]=CreateSemaphore(NULL,1,1,p5);

   dane1.nr=nr1;
   dane1.czas=&(czas[0]);
   dane1.ChceJesc=&(ChceJesc[0]);
   dane1.f=(&F[0]);
   dane1.lewa=Pal5;
   dane1.prawa=Pal1;

   dane2.nr=nr2;
   dane2.czas=&(czas[1]);
   dane2.ChceJesc=&(ChceJesc[1]);
   dane2.f=(&F[1]);
   dane2.lewa=Pal1;
   dane2.prawa=Pal2;

   dane3.nr=nr3;
   dane3.czas=&(czas[2]);
   dane3.ChceJesc=&(ChceJesc[2]);
   dane3.f=(&F[2]);
   dane3.lewa=Pal2;
   dane3.prawa=Pal3;

   dane4.nr=nr4;
   dane4.czas=&(czas[3]);
   dane4.ChceJesc=&(ChceJesc[3]);
   dane4.f=(&F[3]);
   dane4.lewa=Pal3;
   dane4.prawa=Pal4;

   dane5.nr=nr5;
   dane5.czas=&(czas[4]);
   dane5.ChceJesc=&(ChceJesc[4]);
   dane5.f=(&F[4]);
   dane5.lewa=Pal4;
   dane5.prawa=Pal5;

   for(int i=0; i<5; i++)
      ReleaseSemaphore(PALECZKA[i],1,NULL);

}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------


void __fastcall TForm1::F1bezClick(TObject *Sender)
{
   if (!ChceJesc[0])
   {
      czas[0]=StrToInt(InputBox("Filozof będzie jadł!","Wpisz ile sekund potrzebuje na najedzenie się:","5"));
      ChceJesc[0]=true;
      FILOZOF[0]=CreateThread(NULL,0,TFunc,&dane1,0,&TID1);
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::F2bezClick(TObject *Sender)
{
   if (!ChceJesc[1])
   {
      czas[1]=StrToInt(InputBox("Filozof będzie jadł!","Wpisz ile sekund potrzebuje na najedzenie się:","5"));
      ChceJesc[1]=true;
      FILOZOF[1]=CreateThread(NULL,0,TFunc,&dane2,0,&TID2);
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::F3bezClick(TObject *Sender)
{
   if (!ChceJesc[2])
   {
      czas[2]=StrToInt(InputBox("Filozof będzie jadł!","Wpisz ile sekund potrzebuje na najedzenie się:","5"));
      ChceJesc[2]=true;
      FILOZOF[2]=CreateThread(NULL,0,TFunc,&dane3,0,&TID3);
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::F4bezClick(TObject *Sender)
{
   if (!ChceJesc[3])
   {
      czas[3]=StrToInt(InputBox("Filozof będzie jadł!","Wpisz ile sekund potrzebuje na najedzenie się:","5"));
      ChceJesc[3]=true;
      FILOZOF[3]=CreateThread(NULL,0,TFunc,&dane4,0,&TID4);
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::F5bezClick(TObject *Sender)
{
   //if (!ChceJesc[4])
   //{
      czas[4]=StrToInt(InputBox("Filozof będzie jadł!","Wpisz ile sekund potrzebuje na najedzenie się:","5"));
      ChceJesc[4]=true;
      FILOZOF[4]=CreateThread(NULL,0,TFunc,&dane5,0,&TID5);
   //}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
   for (int i=0; i<5; i++)
   {
      TerminateThread(FILOZOF[i],0);
      CloseHandle(FILOZOF[i]);
      CloseHandle(PALECZKA[i]);
   }

}

DWORD WINAPI TFunc(PVOID arg)
{
   DANE dane=*(DANE*)arg;

   AnsiString p,l;
   switch (dane.nr)
   {
      case 0:
         l=(AnsiString)p5;
         p=(AnsiString)p1;
         break;
      case 1:
         l=(AnsiString)p1;
         p=(AnsiString)p2;
         break;
      case 2:
         l=(AnsiString)p2;
         p=(AnsiString)p3;
         break;
      case 3:
         l=(AnsiString)p3;
         p=(AnsiString)p4;
         break;
      case 4:
         l=(AnsiString)p4;
         p=(AnsiString)p5;
         break;
   }
   char* lewy=l.c_str();
   char* prawy=p.c_str();
   HANDLE hSemLewy=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,lewy);
   HANDLE hSemPrawy=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,prawy);
      if ((*(dane.ChceJesc))==true)
      {
          WaitForSingleObject(hSemLewy,INFINITE); // czekamy na lewa paleczka

            // mamy lewa paleczke
            // robimy zeby  nie bylo jej na stole
            dane.lewa->Visible=false;
            // ale musi byc widac ze trzymamy lewa
            dane.f->lewa->Visible=true;
            dane.f->pusty->Visible=false;
            // czekamy na nastepna paleczke

             WaitForSingleObject(hSemPrawy, INFINITE); // czekamy na prawa paleczke
               // teraz jemy
               dane.prawa->Visible=false; // nie ma prawej paleczki
               dane.f->je->Visible=true;
               dane.f->lewa->Visible=false;
               Sleep((*(dane.czas))*1000);  // jemy iles tam sekund
               // najedlismy sie, puszczamy
             // najadl sie i puszczamy semafory
             dane.prawa->Visible=true;
             ReleaseSemaphore(hSemPrawy,1,NULL);
             dane.lewa->Visible=true;
             ReleaseSemaphore(hSemLewy,1,NULL);

             // ustawiamy grafike
             dane.f->pusty->Visible=true;
             dane.f->je->Visible=false;
             // oddajemy paleczki
             *(dane.ChceJesc)=false;
             *(dane.czas)=0;
      }
   return 0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ChceJesc[0]=true;
   ChceJesc[1]=true;
   ChceJesc[2]=true;
   ChceJesc[3]=true;
   ChceJesc[4]=true;
   FILOZOF[0]=CreateThread(NULL,0,TFunc,&dane1,0,&TID1);
   FILOZOF[1]=CreateThread(NULL,0,TFunc,&dane2,0,&TID2);
   FILOZOF[2]=CreateThread(NULL,0,TFunc,&dane3,0,&TID3);
   FILOZOF[3]=CreateThread(NULL,0,TFunc,&dane4,0,&TID4);
   FILOZOF[4]=CreateThread(NULL,0,TFunc,&dane5,0,&TID5);

}
//---------------------------------------------------------------------------

