#include <euredit_sys.h>


int main (int argc, char *argv[])
{
	/* Parameters */
	long         srtype[] = {0,-1,-1};
	long         rand_select = 0;
	long         n_match = 5;
	long         match_all = 0;
	long         reuse = 1;
	double       min_wt = 0.0;
	double       wts[] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0};
	double      *R = NULL;
	long         dist_type[] = {1,1,1,1,1,1,1};
	double      *user_dist;
	long         num_obs = 100;
	long         m = 7;
	double      *data;
	long         n_cat[] = {2,2,2,3,5,10,11};
	long         cat_val[] = {1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
		                      1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
		                      1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
		                      1, 2, 3,-1,-1,-1,-1,-1,-1,-1,-1,
		                      1, 2, 3, 4, 5,-1,-1,-1,-1,-1,-1,
		                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,
							  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10};
	long         maxcat = 11;
	double       miss_val = -999.0;
	long         num_imp;
	long        *obs_num;
	long        *var_num;
	double      *rep_val;
	long         info[5];

	long         i, j, num_miss;
	double       id;
	const char   file[] = "categorical.dat";
	FILE        *fp;
	long        *iwork;
	double      *rwork;


	/* Load data */
	if (!(data = (double *)malloc (num_obs*m * sizeof (double))))
	{
		printf (" Memory allocation failure.\n");
		exit (2);
	}

	if ((fp = fopen (file, "r")) == NULL)
    {
		 printf (" Cannot open file named %s for reading.\n", file);
		 free (data);
		 exit (2);
	}

	num_miss = 0;
    for (i=0; i<num_obs; ++i)
    {
		/* Skip the ID value in the first column of data */
		fscanf(fp, "%lf", &id);

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

			if (data[i*m+j] == miss_val) ++num_miss;
        }
        fscanf(fp, "\n");
    }
    fclose(fp);

	if (num_miss < 1)
	{
		printf (" No missing values to impute!.\n");
		free (data);
		exit (2);
	}
	else	
		printf (" Found %li missing values.\n", num_miss);

	/* Memory allocation */
	if (!(iwork = (long *)malloc (2*num_miss * sizeof (long))))
	{
		printf ("Memory allocation error.\n");
		exit (2);
	}
	obs_num = iwork;
	var_num = obs_num + num_miss;

	if (!(rwork = (double *)malloc ((m*maxcat*maxcat+num_miss)*sizeof (double))))
	{
		printf ("Memory allocation error.\n");
		exit (2);
	}
	user_dist = rwork;
	rep_val = user_dist + m*maxcat*maxcat;

	/* Run general imputation algorithm */
    gen_imp (srtype,rand_select,n_match,match_all,reuse,min_wt,wts,R,dist_type,
	         user_dist,num_obs,m,data,n_cat,cat_val,maxcat,miss_val,&num_imp,
             obs_num,var_num,rep_val,info);

	if (info[0] > 0)
	{
		printf("\n Error number %ld (%ld)\n",info[0],info[1]);
		free (data);
		free (iwork);
		free (rwork);
		exit (2);
	}

	printf(" Number of Edits: %ld\n\n", num_imp);
	printf(" <Start of Edits>\n");
    for (i=0; i<num_imp; ++i)
    {
        j = var_num[i];
        if (n_cat[j]==0) 
        {
            printf(" %ld %ld %lf \n",obs_num[i],j,rep_val[i]);
        }
        else
        {
            printf(" %ld %ld %ld \n",obs_num[i],j,(long)rep_val[i]);
        }
    }
	printf(" <End of Edits>\n\n");

	if (info[2]>0)
	{
		printf("\n %ld observations had insufficent matching values \n",info[2]);
	}
	if (info[3]>0)
	{
		printf("\n %ld observations had missing matching values \n",info[3]);
	}
	if (info[4]>0)
	{
		printf("\n %ld values that have not been imputed \n",info[4]);
	}

	free (data);
	free (iwork);
	free (rwork);

	return 0;
}
