#' @title  Bidimensional representation of multidimensional ordinal binary data generated by a specific
#' reversed pair of lexicographic linear extensions
#'
#' @title  Bidimensional representation of multidimensional ordinal binary data generated by a specific
#' reversed pair of lexicographic linear extensions
#'
#' @description Starting from a dataset related to \eqn{n} statistical units, scored against \eqn{k}
#' ordinal 0/1-indicators and partially ordered component-wise into a Boolean lattice \eqn{B_k=(\{0,1\}^k,\leq_{cmp})},
#' it finds the bidimensional data representation generated by a specific reversed pair of lexicographic linear extensions.
#'
#' @param profile Boolean matrix of dimension \eqn{m\times k} of the unique \eqn{m\leq n} different observed profiles.
#' Each observed profile is row of `profile`. Each observed profile is repeated only once in the matrix `profile`.
#'
#' @param weights real vector of length \eqn{m} with the frequencies/weights of each observed profile. Element
#' of position \eqn{j} in vector `weights` is the frequency/weight of the profile in row \eqn{j} of `profile`.
#'
#' @param variablesPriority integer vector of dimension \eqn{k} containing a permutation \eqn{i_1,...,i_k} of \eqn{1,...,k}.
#' This vector specifies the criterion to build the reversed pair of lexicographic linear extensions used to
#' approximate \eqn{B_k}. The first linear extension is built by ordering profiles first according to their
#' scores on \eqn{V_{i_1}}, then to the scores on \eqn{V_{i_{2}}} and so on, until \eqn{V_{i_{k}}}; the second linear extension
#' is built by ordering profiles first according to their scores on \eqn{V_{i_k}}, then to the scores on \eqn{V_{i_{k-1}}} and so on, until \eqn{V_{i_{1}}}.
#'
#' @return a list of 2 elements named `LossVAlue` and `Representation`.
#'
#' `LossVAlue` real number indicating the value of the global error \eqn{L(D^{out}|D^{inp}, p)} corresponding to the representation induced by the chosen `variablesPriority`.
#'
#' `Representation`  a data frame with \eqn{m} values (one value for each observed profile) of 5 variables named `profiles`, `x`, `y`, `weights` and `error`.
#' `$profile` is an integer vector containing the base-10 representation of the \eqn{k}-dimensional Boolean vectors representing observed profiles.
#' `$x` is an integer vector containing the x-coordinates of points representing observed profiles in the bidimensional representation.
#' `$y` is an integer vector containing the y-coordinates of points representing observed profiles in the bidimensional representation.
#' `$weights` is a real vector with the frequencies/weights of each observed profile.
#' `$error` is a real vector with the values of the approximation errors \eqn{L(b|D^{inp}, p)} associated to each observed profile
#' in the bidimensional representation.
#'
#' @examples
#' #SIMULATING OBSERVED BINARY DATA
#' #number of binary variables
#' k <- 6
#' #building observed profiles matrix
#' profiles <- sapply((0:(2^k-1)) ,function(x){ as.integer(intToBits(x))})
#' profiles <- t(profiles[1:k, ])
#' #building the vector of observation frequencies
#' weights <- sample.int(100, nrow(profiles), replace=TRUE)
#' #Chosing (at random) a variable priority
#' vp <- sample.int(k, k, replace=FALSE)
#' result <- BidimentionalPosetRepresentation(profiles, weights, vp)
#'
#' @name BidimentionalPosetRepresentation
#' @export BidimentionalPosetRepresentation
BidimentionalPosetRepresentation <- function(profile, weights, variablesPriority) {
  loss="LB"
  lossFunctions <- c("LB")
  if (!is.matrix(profile) || !all(profile %in% c(0,1))) {
    stop("profile must be a 0/1 matrix")
  }
  mode(profile) <- "integer"
  if (!is.vector(weights)) {
    stop("weights must be a numeric vector")
  }

  if (length(weights) != nrow(profile)) {
    stop("weights length must be equal to profile'rows")
  }
  mode(weights) <- "numeric"
  if (length(which(weights == 0)) > 0) {
    profile <- profile[-which(weights == 0), ]
    weights <- weights[-which(weights == 0)]
  }

  if (!(loss %in% lossFunctions)) {
    stop("loss TO_DO")
  }

  if (length(variablesPriority) != ncol(profile)) {
    stop("variablesPriority length must be equal to profile'rows")
  }

  if (!all(sort(variablesPriority) == (1:ncol(profile)))) {
    stop(paste("variablesPriority must be a permutation of 1:", ncol(profile), sep=""))
  }

  mode(variablesPriority) <- "integer"

  if (!(loss %in% lossFunctions)) {
    stop("loss TO_DO")
  }

  tryCatch({
    result <- .Call("_RunBidimentionalPosetRepresentation", profile, weights, loss, variablesPriority)
    result[["representation"]] <- data.frame(result[["representation"]])
    return (result)
  }, error = function(err) {
    err_split <- strsplit(err[[1]], split = ":")
    stop(err_split[[1]][length(err_split[[1]])])
  }) # END tryCatch
}
