library(mvtnorm);

create_single_base_cell_unif <- function(path, prefix, inst_num, grid_rows, grid_cols, perc_nz, threshold) {
#example: create_single_base_cell_unif("./inst/","data", 3, 25, 25, 0.3, 0.5, TRUE)

  for (t in 1:inst_num) {
    xi = matrix(   rep(0, grid_cols), nrow= grid_rows, ncol= grid_cols);
    
    rs = vector(length=grid_rows * grid_cols);
    cs = vector(length=grid_rows * grid_cols);
    
    k = 1;
    for (i in 1:grid_rows) for (j in 1:grid_cols) {
      rs[k] = i; cs[k] = j;
      k = k + 1;
    }
    
    s = sample(1:(grid_rows * grid_cols), round(perc_nz * grid_rows * grid_cols));
    
    for (k in 1:length(s)) xi[rs[ s[k] ], cs[ s[k] ] ] = sample(1: 10, 1);
    xi = xi / sum(xi);
    
    root = s[sample(1:length(s),1)];
    
    numFile=paste( t,".txt" ,sep = "");
    dimFile=paste(grid_rows, grid_cols, sep = "X");
    nameFile=paste(dimFile, numFile, sep = "_");
    nameFile=paste(prefix, nameFile, sep = "_");
    file=paste(path, nameFile, sep = "");
    
    write("nRows:", file,append = FALSE,sep="");
    write(grid_rows, file,append =TRUE,sep="");
    write("nColumns:", file,append = TRUE,sep="");
    write(grid_cols, file,append =TRUE,sep="");
    write("threshold:", file,append = TRUE,sep="");
    write(threshold, file,append =TRUE,sep="");
    write("root:", file,append = TRUE,sep="");
    write(c(rs[root], cs[root]), file,append =TRUE,sep=" ");
    
    write("probability:", file,append = TRUE,sep="");
    
    for (i in 1:grid_rows) write(xi[i,], file, append = TRUE);
    
    write("sensitiveCells:", file,append = TRUE,sep="");
    write(c(rs[root], cs[root]), file,append =TRUE,sep=" ");
    write(xi[rs[root], cs[root]], file,append =TRUE,sep="");
    
  }
    
}

create_single_base_cell_norm <- function(path, prefix, inst_num, grid_rows, grid_cols, perc_nz, threshold) {
#example: create_single_base_cell_norm("./inst/","data", 3, 25, 25, 0.3, 0.5, 3)
  
  for (t in 1:inst_num) {
    
    xi = matrix(   rep(0, grid_cols), nrow= grid_rows, ncol= grid_cols);
    
    # select POI
    poi_i = sample(1:grid_rows,1);
    poi_j = sample(1:grid_rows,1);

    mn = c(poi_i, poi_j);
    sgm = matrix(c(grid_rows/2, 0, 0, grid_cols/2), 2, 2);

    for (i in 1:grid_rows) for (j in 1:grid_cols) xi[i,j] = dmvnorm( c(i,j), mn, sgm );
    
    rs = vector(length=grid_rows * grid_cols);
    cs = vector(length=grid_rows * grid_cols);
    
    # sample 0-valued cells
    k = 1;
    for (i in 1:grid_rows) for (j in 1:grid_cols) {
      rs[k] = i; cs[k] = j;
      k = k + 1;
    }
    s = sample(1:(grid_rows * grid_cols), round((1-perc_nz) * grid_rows * grid_cols));
    for (k in 1:length(s)) xi[rs[ s[k] ], cs[ s[k] ]] = 0.0;
    
    # normalize
    xi = xi / sum(xi);
    
    # sample root
    k = 1;
    for (i in 1:grid_rows) for (j in 1:grid_cols) if (xi[i,j] > 0) {
      rs[k] = i; cs[k] = j;
      k = k + 1;
    }
    root = sample(1,1:k)
    
    numFile=paste( t,".txt" ,sep = "");
    dimFile=paste(grid_rows, grid_cols, sep = "X");
    nameFile=paste(dimFile, numFile, sep = "_");
    nameFile=paste(prefix, nameFile, sep = "_");
    file=paste(path, nameFile, sep = "");
    
    write("nRows:", file,append = FALSE,sep="");
    write(grid_rows, file,append =TRUE,sep="");
    write("nColumns:", file,append = TRUE,sep="");
    write(grid_cols, file,append =TRUE,sep="");
    write("threshold:", file,append = TRUE,sep="");
    write(threshold, file,append =TRUE,sep="");
    write("root:", file,append = TRUE,sep="");
    write(c(rs[root], cs[root]), file,append =TRUE,sep=" ");
    
    write("probability:", file,append = TRUE,sep="");
    
    for (i in 1:grid_rows) write(xi[i,], file, append = TRUE ,sep=" ");
    
    write("sensitiveCells:", file,append = TRUE,sep="");
    write(c(rs[root], cs[root]), file,append =TRUE,sep=" ");
    #write(xi[rs[root], cs[root]], file,append =TRUE,sep="");
    
  }
  
}

overlaps <- function (base_i, base_j, size_base_reg) {
  for(k in 1:length(base_i)) for (l in 1:length(base_i)) 
    if (  l != k && 
          (abs(base_i[l] - base_i[k]) < size_base_reg || 
           abs(base_j[l] - base_j[k]) < size_base_reg
          )
    ) return(TRUE);
  
  return(FALSE);
}

is_inside <- function (i, j, base_i, base_j, size_base_reg) {
  for(k in 1:length(base_i)) 
    if (  i < base_i[k] + size_base_reg &&
          j < base_j[k] + size_base_reg &&
          i >= base_i[k] &&
          j >= base_j[k]
    ) return(TRUE);
  
  return(FALSE);
}


create_multi_base_cell_norm <- function(path, prefix, inst_num, grid_rows, grid_cols, perc_nz, threshold, n_base_reg, size_base_reg) {
#example: create_multi_base_cell_norm("./inst/","data", 3, 25, 25, 0.3, 0.5, 3, 2, 2)
  
  for (t in 1:inst_num) {
    
    xi = matrix(   rep(0, grid_cols), nrow= grid_rows, ncol= grid_cols);
    
    # select POI
    poi_i = sample(1:grid_rows,1);
    poi_j = sample(1:grid_rows,1);
    
    mn = c(poi_i, poi_j);
    sgm = matrix(c(grid_rows/2, 0, 0, grid_cols/2), 2, 2);
    
    for (i in 1:grid_rows) for (j in 1:grid_cols) xi[i,j] = dmvnorm( c(i,j), mn, sgm );
    
    # sample base regions
    repeat{
      base_i = sample(1:(grid_rows - size_base_reg + 1),n_base_reg);
      base_j = sample(1:(grid_cols - size_base_reg + 1),n_base_reg);
      if (! overlaps(base_i, base_j, size_base_reg) ) break;
    }
    
    # sample 0-valued cells
    rs = vector(length=grid_rows * grid_cols);
    cs = vector(length=grid_rows * grid_cols);
    
    k = 0;
    for (i in 1:grid_rows) for (j in 1:grid_cols) if (! is_inside(i,j, base_i, base_j, size_base_reg ) ){
      k = k + 1;
      rs[k] = i; cs[k] = j;
    }
    
    s = sample(1:k, round((1-perc_nz) * grid_rows * grid_cols));
    for (k in 1:length(s)) xi[rs[ s[k] ], cs[ s[k] ]] = 0.0;
    
    xi = xi / sum(xi);
    
    numFile=paste( t,".txt" ,sep = "");
    dimFile=paste(grid_rows, grid_cols, sep = "X");
    nameFile=paste(dimFile, numFile, sep = "_");
    nameFile=paste(prefix, nameFile, sep = "_");
    file=paste(path, nameFile, sep = "");
    
    write("nRows:", file,append = FALSE,sep="");
    write(grid_rows, file,append =TRUE,sep="");
    write("nColumns:", file,append = TRUE,sep="");
    write(grid_cols, file,append =TRUE,sep="");
    write("threshold:", file,append = TRUE,sep="");
    write(threshold, file,append =TRUE,sep="");
    write("nBaseRegions:", file,append = TRUE,sep="");
    write(n_base_reg, file,append =TRUE,sep="");
    write("sizeBaseRegions:", file,append = TRUE,sep="");
    write(size_base_reg, file,append =TRUE,sep="");
    write("upperLeftCornersBaseRegions:", file,append = TRUE,sep="");
    for (k in 1:n_base_reg) write(c(base_i[k], base_j[k]), file,append =TRUE,sep=" ");
    write("baseCells:", file,append = TRUE,sep="");
    for (k in 1:n_base_reg) {
      i = sample(0:(size_base_reg - 1),1);
      j = sample(0:(size_base_reg - 1),1);
      write(c(base_i[k] + i, base_j[k] + j), file,append =TRUE,sep=" ");
    }
    
    write("probability:", file,append = TRUE,sep="");
    for (i in 1:grid_rows) write(xi[i,], file, append = TRUE ,sep=" ");
    
  }
  
}