#include "whet.h"
#include "math.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

void 
pa (double e[4], double* t, double* t2) 
{
  register int j;
  j = 0;
lab:e[0] = (e[0] + e[1] + e[2] - e[3]) * *t;
  e[1] = (e[0] + e[1] - e[2] + e[3]) * *t;
  e[2] = (e[0] - e[1] + e[2] + e[3]) * *t;
  e[3] = (-e[0] + e[1] + e[2] + e[3]) / *t2;
  j += 1;
  if (j < 6)
    goto lab;
}

void
p3 (double x, double y, double *z, double* t, double* t2) 
{
  x = *t * (x + y);
  y = *t * (x + y);
  *z = (x + y) / *t2;
}

int getTime(char* time) {
  int len = strlen(time);
  int j = len - 1;
  int k;
  int sec = 0;
  int min = 0;
  int hour = 0;
  k = 0;
  while((k < 2) && (j >= 0)) {
    sec += ((time[j]-'0')*(pow(10, k)));
    k++;
    j--;
  }
  k = 0;
  j--;
  while((k < 2) && (j >= 0)) {
    min += ((time[j]-'0')*(pow(10, k)));
    k++;
    j--;
  }
  k = 0;
  j--;
  while((k < 2) && (j >= 0)) {
    hour += ((time[j]-'0')*(pow(10, k)));
    k++;
    j--;
  }

  return (hour*3600 + min*60 + sec)*1000;
}


float   
DoWhet (long iterations) 
{
    double		x1, x2, x3, x4, x, y, z, t, t1, t2;
    double 		e1[4];
    long		ii, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11;
    int i;
    FILE* f;
    char str[100];
    char str2[100];
    int myPid;
    float result;
    int numIter = 10;

    myPid = getpid();	
 
    // Executa os calculos 10 vezes e tira uma media. 
    for(i = 0; i < numIter; i++) 
    {
  
        /* initialize constants */ 
        t = 0.499975;
        t1 = 0.50025;
        t2 = 2.0;
  
        /* set values of module weights */ 
        n1 = 0 * iterations;
        n2 = 12 * iterations;
        n3 = 14 * iterations;
        n4 = 345 * iterations;
        n6 = 210 * iterations;
        n7 = 32 * iterations;
        n8 = 899 * iterations;
        n9 = 616 * iterations;
        n10 = 0 * iterations;
        n11 = 93 * iterations;
  
        /* MODULE 1:  simple identifiers */ 
        x1 = 1.0;
        x2 = -1.0;
        x3 = -1.0;
        x4 = -1.0;
        ii = 1;
        while (ii < (n1 + 1))
        {
            x1 = (x1 + x2 + x3 - x4) * t;
            x2 = (x1 + x2 - x3 - x4) * t;
            x3 = (x1 - x2 + x3 + x4) * t;
            x4 = (-x1 + x2 + x3 + x4) * t;
            ++ii;
        }
  
        /* MODULE 2:  array elements */ 
        e1[0] = 1.0;
        e1[1] = -1.0;
        e1[2] = -1.0;
        e1[3] = -1.0;
        ii = 1;
        while (ii < (n2 + 1))
        {
            e1[0] = (e1[0] + e1[1] + e1[2] - e1[3]) * t;
            e1[1] = (e1[0] + e1[1] - e1[2] + e1[3]) * t;
            e1[2] = (e1[0] - e1[1] + e1[2] + e1[3]) * t;
            e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3]) * t;
            ++ii;
        }
  
        /* MODULE 3:  array as parameter */ 
        ii = 1;
        while (ii < (n3 + 1))
        {
            pa (e1, &t, &t2);
            ++ii;
        }
  
        /* MODULE 4:  conditional jumps */ 
        j = 1;
        ii = 1;
        while (ii < (n4 + 1))
        {
            if (j == 1)
                j = 2;
            else
                j = 3;
            if (j > 2)
                j = 0;
            else
                j = 1;
            if (j < 1)
                j = 1;
            else
                j = 0;
            ++ii;
        }
  
        /* MODULE 6:  integer arithmetic */ 
        j = 1;
        k = 2;
        l = 3;
        ii = 1;
        while (ii < (n6 + 1))
        {
            j = j * (k - j) * (l - k);
            k = l * k - (l - j) * k;
            l = (l - k) * (k + j);
            e1[l - 2] = j + k + l;	/* C arrays are zero based */
            e1[k - 2] = j * k * l;
            ++ii;
        }
  
        /* MODULE 7:  trig. functions */ 
        x = y = 0.5;
        ii = 1;
        while (ii < (n7 + 1))
        {
            x =
                t * atan (t2 * sin (x) * cos (x) / (cos (x + y) + cos (x - y) - 1.0));
            y =
                t * atan (t2 * sin (y) * cos (y) / (cos (x + y) + cos (x - y) - 1.0));
            ++ii; 
        }
  
        /* MODULE 8:  procedure calls */ 
        x = y = z = 1.0;
        ii = 1;
        while (ii < (n8 + 1))
        {
            p3 (x, y, &z, &t, &t2);
            ++ii;
        }
  
        /* MODULE9:  array references */ 
        j = 1;
        k = 2;
        l = 3;
        e1[0] = 1.0;
        e1[1] = 2.0;
        e1[2] = 3.0;
        ii = 1;
        while (ii < (n9 + 1))
        {
            e1[j] = e1[k];
            e1[k] = e1[l];
            e1[l] = e1[j];
            ++ii;
        }
  
        /* MODULE10:  integer arithmetic */ 
        j = 2;
        k = 3;
        ii = 1;
        while (ii < (n10 + 1))
        {
            j = j + k;
            k = j + k;
            j = k - j;
            k = k - j - j;
            ++ii;
        }
  
        /* MODULE11:  standard functions */ 
        x = 0.75;
        ii = 1;
        while (ii < (n11 + 1))
        {
            x = sqrt (exp (log (x) / t1));
            ++ii;
        }
    }//end-for
//system("ps -o pid -o time -o etime");
    f = popen("ps -o pid -o time", "r");

    // Leitura dos rotulos %PID %CPU 
    fscanf(f, "%s", str);
    fscanf(f, "%s", str);
    // Consumo das informacoes de outros processos
    do {
        fscanf(f, "%s", str);
        fscanf(f, "%s", str2);
    }while(atoi(str) != myPid);

    // Conversao do tempo hh:mm:ss para milisegundos
    result = getTime(str2);
	result /= numIter; 
//printf("Vou retornar: %f", result);
	return result;
}

