#include "MemoryManager.h"
#include "spnbox.h"
#include "matrixmath.h"
#include "../pnheaders/matrix.h"
#include "../pnheaders/pns.h"

/*Convert disjunctive constraints to normal constraints, get new D L b m0*/
int disj2normal(pns* plant, matrix *L, int *b, int *LB, int *UB, matrix *DDm, matrix *DDp, matrix *LD, int *CD, int *m1)
{
  pns bin;
  pns pn_compose[L->nr+1];
  matrix D, l, ld, m0m;
  int* cd;
  int* m0;
  int label0[plant->in.nc];
  int c, lb, ub;
  int i;
  MemoryManager Memory;
  
  Memory = CreateMemoryManager(20, 20, 0, 0);

  MAllocateMatrixType(&Memory, 2, &D, plant->in.nr, plant->in.nc);
  SubtractMatrix(&plant->in, &plant->out, &D);
  for(i = 0; i < plant->in.nc; i++)
    label0[i] = plant->t[i].l;
  MAllocateMatrixType(&Memory, 2, &ld, 2, L->nc + L->nr);
  cd = mmalloc(&Memory, 2 * sizeof(int));
  MAllocateMatrixType(&Memory, 2, &l, 1, L->nc);
  pn_compose[0] = copypn(plant); 

  for(i = 0; i < L->nr; i++) {
    CopyBlock(1, L->nc, L, i, 0, &l, 0, 0);
    c = b[i];
    lb = LB[i];
    ub = UB[i];
    m0m = vector2matrix(plant->marking, plant->in.nr, 1);
    disj2pn(&bin, &ld, cd, &D, &m0m, label0, &l, c, lb, ub, i, L->nr);
    CopyBlock(2, L->nc + L->nr, &ld, 0, 0, LD, i * 2, 0);
    CD[2 * i] = cd[0];
    CD[2 * i + 1] = cd[1];
    pn_compose[i+1] = composepn(&pn_compose[i], &bin);
    deallocpn(&bin);
  }
  
  MakeZeroRow(LD, 2 * L->nr);
  for(i = 0; i < L->nr; i++) {
    SetMatrixEl(LD, 2 * L->nr, i + plant->in.nr, -1);
  }
  CD[2 * L->nr] = -1;

  AllocateMatrix(DDm, pn_compose[L->nr].out.nr, pn_compose[L->nr].out.nc);
  CopyMatrix(&pn_compose[L->nr].out, DDm);
  AllocateMatrix(DDp, pn_compose[L->nr].in.nr, pn_compose[L->nr].in.nc);
  CopyMatrix(&pn_compose[L->nr].in, DDp);

  for(i = 0; i < L->nr + L->nc; i++)
    m1[i] = pn_compose[L->nr].marking[i];
  
  for(i = 0; i < L->nr + 1; i++)
    deallocpn(&pn_compose[i]);
  FreeMemory(&Memory);
  printf("Disjunctive constraints converted.\n");
  return 0;
}

