#include "lab1.h"
#include <stdio.h>

/* domain of ints from low to high */
Domain *makeDomain(int low,int high) 
{
  int i;
  Domain *d=(Domain*)malloc(sizeof(Domain)); /* allocate domain struct */
  d->nVals = high-low+1; /* set number of values */
  d->val   = (int*)malloc(d->nVals*sizeof(int)); /* allocate values */
  for(i=0;i<d->nVals;i++) /* set values */
    d->val[i]=low+i;

  return d;
}

/* Make new CSP with:
   nv:   number of variables, named 0,1,...,(nv-1)
   doms: array of pointers to domains, nv of them
   nc:   number of constraints
   cons: array of pointers to constraints, nc of them */

CSP *makeCSP(int nv,Domain** doms,int nc,Constraint **cons)
{
  int i;
  CSP *csp=(CSP*)malloc(sizeof(CSP));
  csp->nVars = nv;
  csp->nCons = nc;
  csp->D = doms;
  csp->C = cons;

  return csp;
}

void showCSP(CSP* csp)
{
  int i,j,k;
  printf("Vars:");
  for(i=0;i<csp->nVars;i++)
	 printf(" %d",i);
  printf("\nDomains:");
  for(i=0;i<csp->nVars;i++) {
	 printf("\nVariable %d:",i);
	 for(j=0;j<csp->D[i]->nVals;j++) {
		printf(" %d",csp->D[i]->val[j]);
	 }
  }
  printf("\nConstraints:");
  for(i=0;i<csp->nCons;i++) {
	 printf("\nConstraint %d:\n",i);
	 for(j=0;j<csp->C[i]->nClabs;j++) {
		printf("(",j);
		for(k=0;k<csp->C[i]->clab[j]->nLabs;k++) {
		  printf(" %d,%d",csp->C[i]->clab[j]->var[k],csp->C[i]->clab[j]->val[k]);
		}
		printf(") ",j);
	 }
  }
  printf("\n");
}

/* deallocate a CSP */
void freeCSP(CSP* csp)
{
  int i,j,k;
  for(i=0;i<csp->nVars;i++) {
	 free(csp->D[i]->val);
	 free(csp->D[i]);
  }
  free(csp->D);

  for(i=0;i<csp->nCons;i++) {
	 for(j=0;j<csp->C[i]->nClabs;j++) {
		free(csp->C[i]->clab[j]->var);
		free(csp->C[i]->clab[j]->val);
		free(csp->C[i]->clab[j]);
	 }
	 free(csp->C[i]->clab);
	 free(csp->C[i]);
  }
  free(csp->C);
  free(csp);
	 
  printf("\n");
}

Constraint *makeBinaryConstraint(int(*cons)(int,int),int x,Domain *dx,int y,Domain *dy)
{
  /* The part here is up to you... */
}

/* Binary constraint */

int notequal(int x,int y) { return x!=y; }

/* Create an example CSP */

int main(void)
{
  int i,j,k;
  Domain **D;
  Constraint **C;
  CSP *csp;

  /* 5 domains */
  D=(Domain**)malloc(5*sizeof(Domain*)); 

  /* initialize domains with ints 0..100 */
  for(i=0;i<5;i++) 
    D[i] = makeDomain(0,4); 

  /* 10 constraints */
  C=(Constraint**)malloc(10*sizeof(Constraint*));

  /* Initialize constraints */
  for(k=0,i=0;i<5;i++) {
    for(j=i+1;j<5;j++) {
      /* You have to do this! */
      C[k] = makeBinaryConstraint(notequal,i,D[i],j,D[j]); 
		k++;
    }
  }

  csp = makeCSP(5,D,10,C);
  showCSP(csp);
  freeCSP(csp);
}

