#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
 
 

struct parametro{
 float parametro_alfa[100];
 float parametro_r[100];
 };
 

float fatorial(int);
float traffic_cell(float [], float [], float [], float [],int );
float call_blocking(int , float);

FILE *fptr;

void main(void)
{
 struct parametro call_holding;     //para futuras modificacoes
 struct parametro residence_time;

 int numero_canal,j,i;
 int numero_classes, saida = 0;
 float delta , po, pn;
 float handoff_call_arrival[100];
 float laplace_transform[100];
 float call_not_completed[100];
 float calculo;
 float new_handoff[100];
 float channel_occupation_new[100];
 float channel_occupation_handoff[100];
 char ch;
 float new_call_arrival[100];

 fptr=fopen("H:\\arq.out","w");

 textmode(BW40);
 textbackground(CYAN);
 textcolor(BLACK);
 clrscr();

 for(j=0;j<100;j++)
 {
 call_holding.parametro_r[j] = 1;
 residence_time.parametro_r[j]=1;
 }

 printf("Number of channels: ");
 scanf("%d",&numero_canal);
 fflush(stdin);
 printf("\nNumber of types of hanset: ");
 scanf("%d",&numero_classes);
 fflush(stdin);
 printf("\nDelta: ");
 scanf("%f",&delta);
 fflush(stdin);
 printf("\n\n");

 fprintf(fptr,"Number of channels: %d",numero_canal);
 fprintf(fptr,"\nNumber of types of hanset: %d",numero_classes);
 fprintf(fptr,"\nDelta: %f",delta);

 for(j=1;j<=numero_classes;j++)
   {
     printf("\nThe new call arrival rate %d: ",j);
     scanf("%f",&new_call_arrival[j]);
     fflush(stdin);
     fprintf(fptr,"\nThe new call arrival rate %d: %f",j,new_call_arrival[j]);

     printf("\nParameter of the call holding time \nExponencial distribution %d: ",j);
     scanf("%f",&call_holding.parametro_alfa[j]);
     fflush(stdin);
     fprintf(fptr,"\nParameter of the call holding time \nExponencial distribution %d: %f",j,call_holding.parametro_alfa[j]);

     printf("\nThe residence time distribution %d:",j);
     printf("\n\t(E) Exponencial\t(G) Gamma\n\t? ");
     scanf("%c",&ch);
     ch = toupper(ch);
     fflush(stdin);

     switch(ch)
       {
  case 'E':
      fprintf(fptr,"\nThe residence time distribution %d: Eponencial",j);
      printf("\nParameter of the residence time \ndistribution %d: ",j);
      scanf("%f",&residence_time.parametro_alfa[j]);
      fprintf(fptr,"\nParameter of the residence time \ndistribution %d: %f",j,residence_time.parametro_alfa[j]);
      break;
  case 'G':
     fprintf(fptr,"\nThe residence time distribution %d: Gama",j);
     printf("\nParameters of the residence time \ndistribution %d: ",j);
     printf("\nParameter alfa: ");
     scanf("%f",&residence_time.parametro_alfa[j]);
     printf("\nParameter r: ");
     scanf("%f",&residence_time.parametro_r[j]);
     fprintf(fptr,"\nParameters of the residence time \ndistribution %d: %f",j,residence_time.parametro_alfa[j]);
     fprintf(fptr,"\nParameters of the residence time \ndistribution %d: %f",j,residence_time.parametro_r[j]);
     break;
       }

     printf("\nThe initial handoff call arrival \nrate to a cell %d: ",j);
     scanf("%f", &handoff_call_arrival[j]);
     fprintf(fptr,"\nThe initial handoff call arrival \nrate to a cell %d: %f",j,handoff_call_arrival[j]);

     /*****************
     calculo da transformada de Laplace
     ******************/
     calculo = residence_time.parametro_alfa[j]/(residence_time.parametro_alfa[j] + call_holding.parametro_alfa[j]);
     laplace_transform[j] = pow(calculo, residence_time.parametro_r[j]);
 

     /********************
     calculo do channel occupation time of a new call
     *******************/
     channel_occupation_new[j] = (1/call_holding.parametro_alfa[j]) - (residence_time.parametro_alfa[j]/(pow(call_holding.parametro_alfa[j], 2))) * (1 - laplace_transform[j]);

     /*********************
     calculo do channel occupation time of a handoff call
     ********************/
     channel_occupation_handoff[j] = (1/call_holding.parametro_alfa[j]) * ( 1 - laplace_transform[j]);
     } //fim do for
 

     while(saida==0)
     {
 pn = traffic_cell(new_call_arrival, channel_occupation_new, handoff_call_arrival, channel_occupation_handoff,numero_classes);
 po = call_blocking(numero_canal, pn);

 for(j=1; j<=numero_classes; j++)
 {
    new_handoff[j] = (residence_time.parametro_alfa[j] * (1 - po) * ( 1 - laplace_transform[j]) * new_call_arrival[j])/(call_holding.parametro_alfa[j] * (1 - ( 1- po) * laplace_transform[j]));
    if(  fabs( (new_handoff[j] - handoff_call_arrival[j]) / (new_handoff[j]) ) > delta)
    {
       saida = 1;
    }
  }// fecha for
       if(saida==0)
       {
 saida = 1;
       }
       else
       {
 //Para voltar ao laco
 saida = 0;
 for(i=1; i<=numero_classes; i++)
 {
  handoff_call_arrival[i] = new_handoff[i];
 }
       }
      }//fim do while

 clrscr();

 textmode(BW80);
 _setcursortype(_NOCURSOR);

 fprintf(fptr,"\n\n\tResultados:");
 for(j=1, i=1; j<=numero_classes; j++, i++)
 {
    call_not_completed[j] = po * ( 1 + new_handoff[j] / new_call_arrival[j]);
    if(i == 25 )
    {
       getch();
       i=1;
    }
    printf("The new call blocking probability %d: %f\n", j, po);
    fprintf(fptr,"\n\nThe new call blocking probability %d: %f\n", j, po);
    printf("The handoff call arrival rate for type %d: %f\n" , j, new_handoff[j]);
    fprintf(fptr,"The handoff call arrival rate for type %d: %f\n" , j, new_handoff[j]);
    printf("The call incompletion probability for type %d: %f\n\n\n", j, call_not_completed[j]);
    fprintf(fptr,"The call incompletion probability for type %d: %f\n\n\n", j, call_not_completed[j]);
 }

 getch();
}
 

float fatorial(int x)
{
 if(x==0 || x==1)
 return(1);
 else
 return(x*fatorial(x-1));

 }
 

float traffic_cell(float new_call_arrival[],float channel_occupation_new[],float handoff_call_arrival[],float channel_occupation_handoff[],int numero_canal)
{
 int j;
 float soma = 0;

 for(j=1; j <= numero_canal ; j++)
 {
   soma = soma + ((new_call_arrival[j] * channel_occupation_new[j]) + ( handoff_call_arrival[j] * channel_occupation_handoff[j]));
 }

 return(soma);
}
 

float call_blocking(int numero_canal,float pn)
{
  float numerador,denominador=0,j;

 numerador = pow(pn,numero_canal)/fatorial(numero_canal);
 

 for(j=0 ; j <= numero_canal ; j++)
 {
  denominador = denominador + (pow(pn,j)/fatorial(j));
 }

 return(numerador/denominador);
}