#include <euredit_sys.h>


int main (int argc, char *argv[])
{
    long          rec1 = 0;
    long          nrec = 89;
    long          nvar = 8;
    long          dblk = 89;
    long          ninde = 6;
    long          inde[] = {1,2,4,5,6,7};
    long          dep = 3;
    long          ncat[]={0,2,2,2,3,5,10,11};
    double       *priors = (double *)0;
    double       *data, *idata;
    long          mnc = 5;
    long          mns = 10;
    double        rsd =  0.01;
    int           root;
    long          opt_build = 1; /* if 1, store dependent values at leaf nodes.       */
    long          opt_rand = 1;  /* if 1, use random number to resolve flow problems. */
    long          opt_score;     /* imputation type: 1 - mode; 3 - random.            */
    long          seed[5];
    double       *results, *acc, *dwork;
    int           info = 0;
    long          idblk = 11;
    const char    file[] = "complete.dat";
    const char    ifile[] = "impute.dat";
    const char    sfile[] = "gini_save";
/*  N.B. Categories in data labelled 1,2,3,..,n for n categories. */


    if (!(data = (double *)malloc (dblk*nvar * sizeof (double))))
    {
        printf ("Memory allocation failure.\n");
        exit (2);
    }

    if (!(idata = (double *)malloc (idblk*nvar * sizeof (double))))
    {
        printf ("Memory allocation failure.\n");
        free (data);
        exit (2);
    }

    
    {/* Read data: */
        FILE         *fp;
        long          i, j;
        
        
        if ((fp = fopen (file, "r")) == NULL)
        {
            free (data);
            free (idata);
            printf ("Error cannot open data file: %s.\n", file);
            exit (2);
        }

        for (i=0; i<dblk; ++i)
        {
            for (j=0; j<nvar; ++j)
            {
                fscanf(fp, "%lf", &data[i*nvar+j]);

                /* Add 1 to zero-based categories: */
                if (j==6 || j==7)
                    data[i*nvar+j]++;
            }
            fscanf(fp, "\n");
        }
        fclose(fp);

        
        if ((fp = fopen (ifile, "r")) == NULL)
        {
            free (data);
            free (idata);
            printf ("Error cannot open data file: %s.\n", ifile);
            exit (2);
        }

        for (i=0; i<idblk; ++i)
        {
            for (j=0; j<nvar; ++j)
            {
                fscanf(fp, "%lf", &idata[i*nvar+j]);
            }
            fscanf(fp, "\n");
        }
        fclose(fp);
    }


    gini_tree (rec1, nvar, nrec, dblk, data, NULL, ninde, inde, dep, ncat, priors,
               mns, mnc, rsd, opt_build, &root, &info);

    if (info == -999)
	{
		printf (" Obtain a licence from NAG to run this component.\n");
		free (data);
		exit (2);
	}
	else if (info > 0)
    {
        printf ("gini_tree error code: %i.\n", info);
        free (data);
        exit (2);
    }
    else if (info < 0)
    {
        printf ("gini_tree warning code: %i.\n", info);
    }

    
    tree_save (root, sfile, &info);
    if (info > 0)
    {
        printf ("tree_save error code: %i.\n", info);
        tree_free (root);
        exit (2);
    }
    else if (info < 0)
    {
        printf ("tree_save warning code: %i.\n", info);
    }


    free (data);
       
    
    /* Imputed values: */
    if (!(dwork = (double *)malloc (idblk*2 * sizeof (double))))
    {
        free (idata);
        tree_free (root);
        exit (2);
    }

    results = dwork;
    acc = dwork + idblk;

    set_rand_seed (34, seed);

    /* Imputation using modal class: */
    opt_score = 1;

    tree_score (rec1, nvar, idblk, idblk, idata, NULL, root, opt_rand, opt_score,
                seed, results, acc, &info);
    if (info > 0)
    {
        printf ("tree_score error code: %i.\n", info);
        free (idata);
        free (dwork);
        tree_free (root);
        exit (2);
    }
    else if (info < 0)
    {
        printf ("tree_score warning code: %i.\n", info);
    }

    {
        int i;
        for (i=0; i<idblk; ++i)
            printf ("%li (%E)\n", (long)results[i], acc[i]);
    }

    /* Imputation using random class: */
    opt_score = 3;

    tree_score (rec1, nvar, idblk, idblk, idata, NULL, root, opt_rand, opt_score,
                seed, results, acc, &info);
    if (info > 0)
    {
        printf ("tree_score error code: %i.\n", info);
        free (idata);
        free (dwork);
        tree_free (root);
        exit (2);
    }
    else if (info < 0)
    {
        printf ("tree_score warning code: %i.\n", info);
    }

    {
        int i;
        for (i=0; i<idblk; ++i)
            printf ("%li (%E)\n", (long)results[i], acc[i]);
    }

    free (idata);
    free (dwork);

    return 0;
}
