#include<stdio.h>
  #include<stdlib.h>
  #include<graphics.h>
  #include<conio.h>
  struct process
  {
      int pn,at,pt,tt,wt;
  }p[20],tem[20],*q[20];
   
   
   
  int i,j,k,choice,np,c=0;
  int last=-1;
  int processq[50],z;
  char procg[50],z1;
   
   
  void qinsert(struct process *a)
  {
      last=last+1;
      q[last]=a;
   
  }
  void qdelete(void)
  {
      int l;
      processq[z]=(*q[0]).pn;
      z++;
      for(l=0;l<last;l++)
      q[l]=q[l+1];
      last--;
      if(last<-1)
      printf("error");
   
  }
  void result(void)
  {
      float ttt=0,twt=0;
      printf(" \n\n");
        /*    printf("\t process\tarrival\t  burst     \twating\t  turn around\n");
      printf("\t        \ttime   \t  time      \ttime \t  time      \n\n ");
      for(i=0;i<np;i++)
      {
          printf("\t %d) p%d\t\t%d\t  %d\t       \t%d\t  %d\n",i+1,p[i].pn,p[i].at,p[i].pt,p[i].wt,p[i].tt);
      }  */
   
      for(i=0;i<np;i++)
      {
          ttt=ttt+p[i].tt;
          twt=twt+p[i].wt;
      }
      printf("\n\n\taverage waiting   time    is : %f",twt/np);
      printf("\n\taverage turn around  time is : %f",ttt/np);
  }
  void qset(void)
  {
      struct process temp;
   
      for(k=0;k<np;k++)
          tem[k]=p[k];
      for(i=0;i<np;i++)
      {
          for(j=i;j<np;j++)
          {
              if(tem[i].at>tem[j].at)
              {
                  temp=tem[j];
                  tem[j]=tem[i];
                  tem[i]=temp;
              }
          }
   
      }
   
   
  }
   
   
                                                         
   
  void fcfs(void)
  {
      struct process temp;
      int c=0;
      char fcfsg[30],tempg[30];
      int gdriver = DETECT, gmode, errorcode;
     int left, top, right, bottom;
     int a=0,i,midx,midy,tq1,j;
     initgraph(&gdriver, &gmode, "d:\\tc\\bgi");
     errorcode = graphresult();
     qset();
   for(i=0;i<np;i++)
   {
      tem[i].wt=c-tem[i].at;
      if(tem[i].wt<0)
      {
             c=tem[i].at;
             tem[i].wt=0 ;
      }
      tem[i].tt=tem[i].wt+tem[i].pt;
      c=c+tem[i].pt;
   
   }
   for(i=0;i<np;i++)
   {
   for(j=0;j<np;j++)
   {
   if(p[i].pn==tem[j].pn)
     {
        p[i]=tem[j];
     }
    }
   }
   result();
   if (errorcode != grOk)  /* an error occurred */
     {
        printf("Graphics error: %s\n", grapherrormsg(errorcode));
        printf("Press any key to halt:");
        getch();
        exit(1);
       }
   
     for(i=0;i<c;i++)
     {
     left = getmaxx()/2 +a - 8;
     top = getmaxy() /2 - 10;
     right = getmaxx()/2 +a + 8;
     bottom = getmaxy() / 2 + 10;
   
    rectangle(left,top,right,bottom);
     a+=16;
     }
     j=0;
       i=0;
     fcfsg[0]=0;
     for(i=0;i<c;i++)
     {
      if(tem[j].at>i)
      {
          strcat(fcfsg,"  ");
      }
      else
      {
   
      itoa(tem[j].pn, tempg, 10);
      for(tq1=tem[j].pt;tq1>0;tq1--)
      {
      strcat(fcfsg,tempg);
      strcat(fcfsg," ");
      }
      i=i+tem[j].pt;
      j++;
      }
   
   
     }
   
     midx = getmaxx() / 2;
     midy = getmaxy() / 2;
   
    outtextxy(midx, midy, fcfsg);
  }
  void rr(void)
  {
      int s,x,tq,pt=0;
      char tempg[10];
      int gdriver = DETECT, gmode, errorcode;
     int left, top, right, bottom;
     int a=0,i,midx,midy,tq1;
     /* initialize graphics and local variables */
     initgraph(&gdriver, &gmode, "d:\\tc\\bgi");
   
     /* read result of initialization */
     errorcode = graphresult();
      printf("\n\tEnter the size of timequantom :");
      scanf("%d",&tq);
      qset();
      if(np==1)
      {
          p[0].tt=p[0].pt;
          p[0].wt=0;
          z=1;
          processq[0]=1;
      }
      else
      {
      while(1)
      {
          s=np;
          for(i=0;i<np;i++)
          {
              if(tem[i].pt==0){s--;}
          }
          if(s==0)
              break ;
          for(i=pt;i<np;i++)
          {
              if(tem[i].at<=c)
              {
                qinsert(&tem[i]);
                pt=i+1;
              }
          }
          if(last>=0)
          {
              if((*q[0]).pt<=tq)
              {
                  c=c+(*q[0]).pt;
                  (*q[0]).pt=0;
                  (*q[0]).tt=c-(*q[0]).at;
                  qdelete();
              }
              else
              {
                  c=c+tq;
                  (*q[0]).pt-=tq;
                  for(i=pt;i<np;i++)
                  {
                      if(tem[i].at<=c)
                      {
                          qinsert(&tem[i]);
                          pt=i+1;
                      }
                  }
                  qinsert(q[0]);
                  qdelete();
              }
   
          }
          else
          {
   
              c=c+tq;
              processq[z]=-99;
              z++;
          }
   
      }
      for(i=0;i<np;i++)
      {
          for(j=0;j<np;j++)
          {
              if(p[i].pn==tem[j].pn)
              {
                 p[i].tt=tem[j].tt;
                 p[i].wt=p[i].tt-p[i].pt;
              }
          }
      }
      }
      result();
      printf("\n\nGantt chart:-\n\n");
   
   
     if (errorcode != grOk)
       {
        printf("Graphics error: %s\n", grapherrormsg(errorcode));
        printf("Press any key to halt:");
        getch();
        exit(1); /* terminate with an error code */
     }
   
     for(i=0;i<z*tq;i++)
     {
     left = getmaxx()/2 +a - 8;
     top = getmaxy() /2 - 10;
     right = getmaxx()/2 +a + 8;
     bottom = getmaxy() / 2 + 10;
   
   
        /* draw a rectangle */
     rectangle(left,top,right,bottom);
     a+=16;
     }
     processq[z]='\0';
     i=0;
     while(processq[i]!='\0')
     {
      if(processq[i]==-99)
      {
          for(tq1=tq;tq1>0;tq1--)
          {
              strcat(procg,"  ");
          }
      }
      else
      {
      itoa(processq[i], tempg, 10);
      for(tq1=tq;tq1>0;tq1--)
      {
      strcat(procg,tempg);
      strcat(procg," ");
      }
      }
      i++;
     }
   
     midx = getmaxx() / 2;
     midy = getmaxy() / 2;
     /* output text at the center of the screen */
  /* Note: the C.P. doesn't get changed.     */
     outtextxy(midx, midy, procg);
     /* clean up */
     /*    for(i=0;i<z;i++)
      {
  
         if(processq[i]>0)
          printf("p%d ->",processq[i]);
         else
          printf("_ ->");
      } */
   
   
  }
  void main()
  {
      int ch;
      clrscr();
   
      printf("\n\n\t Enter no of processes   : ");
      scanf("%d",&np);
      printf("\n Enter Data for processes : " );
      for(i=0;i<np;i++)
      {
          printf("\n\n PROCESS (%d) :\n\n arrival time : ",i+1);
          scanf("%d",&p[i].at);
          printf("\n cpu burst time : ");
          scanf("%d",&p[i].pt);
          p[i].pn=i+1;
      }
         //    clrscr();
      printf("\t process\tarrival time\tprocess time\n\n");
      for(i=0;i<np;i++)
      {
   
          printf("\t %d) p%d     \t  %02d        \t  %02d\n",i+1,p[i].pn,p[i].at,p[i].pt);
      }
      printf("Select a method :\n");
      printf("\n1. FCFS");
      printf("\n2. Round Robin");
      printf("\n\nEnter your choice : ");
      scanf("%d",&ch);
      if(ch==1)
      fcfs();
      else if(ch==2)
      rr();
      else
      printf("Invalid..");
      getch();
  }