#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N_MAX_PUNTI 1000000
#define STRLEN      1024
#define FILE_PATH   "./filetxt/cerchi.txt"

#define MAX(A,B)    ((A)>(B))?A:B
#define MIN(A,B)    ((A)<(B))?A:B
#define ABS(A)      ((A)<0)?(-A):A

typedef struct _dot {
    float x;
    float y;
} dot;
typedef struct _circ {
    dot centro;
    float r;
} circ;

typedef dot*    pdot;
typedef circ*   pcirc;
typedef FILE*   pfile;

float frandminmax(float min, float max)
{
    return ((((float)rand())/RAND_MAX)*(max-min))+min;
}

int main(void)
{
    unsigned i,i_mc,n_cerchi,n_hit,check;
    float x_min,x_max,y_min,y_max,x_min_mc,x_max_mc,y_min_mc,y_max_mc,r_grande,r_gq,a,b,c,area;
    char s[STRLEN];
    dot baricentro,test;
    pcirc pcerchio,pc,pc_max;
    pfile pf;

    srand(time(NULL));

    if ((pf=fopen(FILE_PATH,"r"))==NULL) goto err_file;
    fscanf(pf,"%s",s);
    n_cerchi=atoi(s);
    if ((pcerchio=(pcirc)malloc(sizeof(circ)*n_cerchi))==NULL) goto err_mem;

    baricentro.x=baricentro.y=0;
    for (i=0;i<n_cerchi;i++) {
        fscanf(pf,"%s",s); baricentro.x+=(pcerchio[i].centro.x=atof(s));
        fscanf(pf,"%s",s); baricentro.y+=(pcerchio[i].centro.y=atof(s));
        fscanf(pf,"%s",s); pcerchio[i].r=atof(s);

        switch (i) {
        case 0:
            x_max=x_min=pcerchio[i].centro.x;
            y_max=y_min=pcerchio[i].centro.y;
            break;
        default:
            x_max=MAX(x_max,(pcerchio[i].centro.x+pcerchio[i].r));
            x_min=MIN(x_min,(pcerchio[i].centro.x-pcerchio[i].r));
            y_max=MAX(y_max,(pcerchio[i].centro.y+pcerchio[i].r));
            y_min=MIN(y_min,(pcerchio[i].centro.y-pcerchio[i].r));
            break;
        }
        printf("Cerchio n.%u. Centro: (%.3f,%.3f). Raggio: %.3f\n",i+1,pcerchio[i].centro.x,pcerchio[i].centro.y,pcerchio[i].r);
    }
    fclose(pf);

    baricentro.x/=n_cerchi; baricentro.y/=n_cerchi;
    r_grande=MAX(MAX(ABS(x_max-baricentro.x),ABS(x_min-baricentro.x)),MAX(ABS(y_max-baricentro.y),ABS(y_min-baricentro.y)));

    r_gq=r_grande*r_grande;
    pc_max=pcerchio+n_cerchi;
    for (i_mc=0,n_hit=0;i_mc<N_MAX_PUNTI;i_mc++) {
        test.x=baricentro.x+(a=frandminmax(-r_grande,r_grande));
        test.y=baricentro.y+(b=frandminmax(-r_grande,r_grande));
        if ((a*a+b*b)<r_gq) {
            pc=pcerchio;
            check=1;
            do {
                a=test.x-pc->centro.x;
                b=test.y-pc->centro.y;
                c=pc->r;
                if ((a*a+b*b)<(c*c)) {
                    n_hit++;
                    check=0;
                }
                pc++;
            } while ((pc<pc_max)&&(check));
        }
    }

    free(pcerchio);
    area=4*r_grande*r_grande*((float)n_hit)/N_MAX_PUNTI; /*area quadrato * rapporto tra hit e totale punti*/

    printf("Baricentro: (%.3f,%.3f)\nx min ret: %.3f\ny min ret: %.3f\nx max ret: %.3f\ny max ret: %.3f\nRaggio circoscritto: %.3f\nNumero Hit: %u\nArea: %.3f\n",baricentro.x,baricentro.y,x_min,y_min,x_max,y_max,r_grande,n_hit,area);
    return EXIT_SUCCESS;

    err_file:
        printf("ERRORE: non e' stato possibile aprire il file.\n");
        return EXIT_FAILURE;
    err_mem:
        printf("ERRORE: memoria insufficiente.\n");
        return EXIT_FAILURE;
}