#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define BROJ_VOZILA 10
//#define VOZILO //0 automobil, 1 autobus, 2 kamion, 3 hitno vozilo

pthread_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int smer_kretanja=0;
int broj_vozila_smer=0;
int broj_vozila_u_tunelu=0;
int broj_automobila=0;
int broj_autobusa=0;
int broj_kamiona=0;
int broj_hitnih_vozila=0;

void *tunel(void *arg)
{
    int id=*(int *)arg;
    //printf("id %d\n",id);
    int vozilo=rand()%4;
    int smer=rand()%2;
    //int smer_kretanja=rand()%2;
    sleep(rand()%5);
    if(vozilo==0)
    {
        //automobil 
        printf("AUTOMOBIL %d dolazi ispred tunela u smeru %d\n",id,smer);
    } 
    else if(vozilo==1)
    {
        //autobus
        printf("AUTOBUS %d dolazi ispred tunela  u smeru %d\n",id,smer);
    }
    else if(vozilo==2)
    {
        //kamion
        printf("KAMION %d dolazi ispred tunela u smeru %d\n",id,smer);  
    }
    else{
        //hitno vozilo
        printf("HITNO VOZILO %d dolazi ispred tunela  u smeru %d\n",id,smer);
    }
    pthread_mutex_lock(&m);

    while((smer!=smer_kretanja) 
    || (vozilo!=3 && broj_hitnih_vozila>0)
    || (vozilo==0 && broj_automobila>3)
    || (vozilo==1 && broj_autobusa>1)
    || (vozilo==2 && broj_vozila_u_tunelu>0))
        pthread_cond_wait(&cond,&m);
    if(vozilo==0)
    {
        //automobil
        printf("AUTOMOBIL %d ulazi u tunel u smeru %d\n",id,smer);
        broj_automobila++;
        broj_vozila_u_tunelu++;
        broj_vozila_smer++;
    } 
    else if(vozilo==1)
    {
        //autobus
        printf("AUTOBUS %d ulazi u tunel u smeru %d\n",id,smer);
        broj_autobusa++;
        broj_vozila_u_tunelu++;
        broj_vozila_smer++;
    }
    else if(vozilo==2)
    {
        //kamion
        printf("KAMION %d ulazi u tunel u smeru %d\n",id,smer);
        broj_kamiona++;  
        broj_vozila_u_tunelu++;
        broj_vozila_smer++;  
    }
    else{
        //hitno vozilo
        printf("HITNO VOZILO %d ulazi u tunel u smeru %d\n",id,smer);
        broj_hitnih_vozila++;
        broj_vozila_u_tunelu++;
        broj_vozila_smer++;
    }
    pthread_mutex_unlock(&m);

    sleep(rand()%5);
    if(vozilo==0)
    {
        //automobil 
        printf("AUTOMOBIL %d prolazi kroz tunel u smeru %d\n",id,smer);
    } 
    else if(vozilo==1)
    {
        //autobus
        printf("AUTOBUS %d prolazi kroz tunel u smeru %d\n",id,smer);
    }
    else if(vozilo==2)
    {
        //kamion
        printf("KAMION %d prolazi kroz tunel u smeru %d\n",id,smer);   
    }
    else{
        //hitno vozilo
        printf("HITNO VOZILO %d prolazi kroz  tunel u smeru %d\n",id,smer);
    }
    pthread_mutex_lock(&m);
    if(vozilo==0)
    {
        //automobil 
        printf("AUTOMOBIL %d prosao kroz tunel u smeru %d\n",id,smer);
        broj_automobila--;
        broj_vozila_u_tunelu--;
        broj_vozila_smer--;
        pthread_cond_broadcast(&cond);
    } 
    else if(vozilo==1)
    {
        //autobus
        printf("AUTOBUS %d prosao kroz tunel u smeru %d\n",id,smer);
        broj_autobusa--;
        broj_vozila_u_tunelu--;
        broj_vozila_smer--;
        pthread_cond_broadcast(&cond);
    }
    else if(vozilo==2)
    {
        //kamion
        printf("KAMION %d prosao kroz tunel u smeru %d trenutni broj vozila u tunelu\n",id,smer,broj_vozila_u_tunelu); 
        broj_kamiona--; 
        broj_vozila_u_tunelu--;
        broj_vozila_smer--;
        pthread_cond_broadcast(&cond); 
    }
    else{
        //hitno vozilo
        printf("HITNO VOZILO %d prosao kroz  tunel u smeru %d\n",id,smer);
        broj_hitnih_vozila--;
        broj_vozila_smer--;
        pthread_cond_broadcast(&cond);
    }
    if(broj_vozila_smer==0 && smer_kretanja==1){
        smer_kretanja=0;
    }
    if(broj_vozila_smer==0 && smer_kretanja==0){
        smer_kretanja=1;
    }
    pthread_mutex_unlock(&m);

}

int main()
{
    pthread_t niti[BROJ_VOZILA];
    int idx[BROJ_VOZILA];

    for(int i=0;i<BROJ_VOZILA;i++)
    {
        idx[i]=i+1;
        pthread_create(&niti[i],NULL,tunel,&idx[i]);
    }

    for(int i=0;i<BROJ_VOZILA;i++)
    {
        pthread_join(niti[i],NULL);
    }
}