  /*
  cl_kernel kernel;
  kernel = clCreateKernel(arguments, "nothing");
  
  ((args*)kernel.arguments)->param[0] = (int*)malloc(sizeof(int));
  memcpy(((args*)kernel.arguments)->param[0], &star, sizeof(int));
  
  ((args*)kernel.arguments)->param[1] = one;
  
  clReleaseKernel(kernel);
  
  printf("single kernel works\n");
  */


#include "cl.cvl"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <civlc.h>
#include "multiplekernel.cvl"

int numArgs = 2;
int numKernels = 3;
/*
  This version of the kernel has a flag for each element in the param array
  If the mallocflag is set to 1, it means that it will be freed by clReleaseKernel
*/
typedef struct
{
  void * param[numArgs];
  int mallocflag[numArgs];
}args;
/*
  clCreateKernel in this iteration turns each flag to 0 to start off with, otherwise it gets a symbolic expression
*/
cl_kernel clCreateKernel(args * argument, char * function)
{
  cl_kernel kernel;
  kernel.arguments = argument;
  kernel.method = function;
  
  for(int j = 0; j < numArgs; j++)
  {
    ((args*)kernel.arguments)->mallocflag[j] = 0;
  }
  
  return kernel;
}
/*
  Checks the flag to make sure that it was a local variable that must be freed every step of the way
*/
void clReleaseKernel(cl_kernel kernel)
{
  for (int i = 0; i < numArgs; i++)
  {
    printf("I am argument %d with value %d\n", i, ((args*)kernel.arguments)->mallocflag[i]);
    if (((args*)kernel.arguments)->mallocflag[i] == 1)
    {
      printf("and I pass the flag check\n");
      free(((args*)kernel.arguments)->param[i]);
    }
  }
}

int main(int argc, char** argv)
{
  args * arguments;
  arguments = (args*)malloc(sizeof(args) * numKernels);
  //Must have enough arguments for each kernel
  
  int star = 1;
  
  int * one = (int*)malloc(sizeof(int));
  memcpy(one, &star, sizeof(int));

  //cl_kernel *kernels = (cl_kernel*)malloc(numKernels * sizeof(cl_kernel));
  cl_kernel kernels[numKernels];
  
  printf("%d, %d\n", star, *one);
  
  //For loop to create multiple kernels, the programmer must put the loop himself
  for (int i = 0; i < numKernels; i++)
  {
    kernels[i] = clCreateKernel(arguments+i, "eh");
    

  }
  //For each kernel, put in the variables
  for (int j = 0; j < numKernels; j++)
  {

    ((args*)kernels[j].arguments)->param[0] = (int*)malloc(sizeof(int));
    ((args*)kernels[j].arguments)->mallocflag[0] = 1;
    memcpy(((args*)kernels[j].arguments)->param[0], &star, sizeof(int));
    
    //param[0] is a __local variable, so it gets the flag put to 1 
    
    //printf("I am kernel of index %d, with a value of %d\n", j, ((args*)kernels[j].arguments)->param[0]);
    
    ((args*)kernels[j].arguments)->param[1] = one;
    //This is a __global variable, so it does not get the flag changed in this iteration.
    //TODO: determine if global variables were freed by clReleaseKernel or the programmer.
  }
  
  //printf("assigned properly\n");
  
  for (int k = 0; k < numKernels; k++)
  {
    clReleaseKernel(kernels[k]);
  }
  
  for (int k = 0; k < numKernels; k++)
  {
    //free(((args*)kernels[k].arguments)->param[0]);
  }
  
  
  free(one);
  free(arguments);
  return 0;
}


