#' Calculate pairwise semantic similarities for a list of gene clusters.
#'
#'
#' @title Pairwise semantic similarities for a list of gene clusters
#' @param clusters A list of gene clusters
#' @template params-measure-combine
#' @param drop Evidence codes to drop; use `NULL` to keep all GO annotations
#' @return similarity matrix
#' @seealso [goSim()] [mgoSim()] [geneSim()] [mgeneSim()] [clusterSim()] [mclusterSim()]
#' @export
#' @examples
#' d <- godata('org.Hs.eg.db', ont = "MF", computeIC = FALSE)
#' cluster1 <- c("835", "5261", "241")
#' cluster2 <- c("578", "582")
#' cluster3 <- c("307", "308", "317")
#' clusters <- list(a = cluster1, b = cluster2, c = cluster3)
#' mclusterSim(clusters, semData = d, measure = "Wang")
#' @author Guangchuang Yu <https://yulab-smu.top>
mclusterSim <- function(clusters, semData, measure="Wang", drop="IEA", combine="BMA") {
    n <- length(clusters)
    cluster_gos <- list()
    for (i in 1:n) {
        cluster_gos[[i]] <- sapply(clusters[[i]], gene2GO, semData, dropCodes = drop)
    }

    uniqueGO <- uniqueGOFrom(cluster_gos)
    go_matrix <- buildGoMatrix(uniqueGO, semData, measure)

    scores <- matrix(NA, nrow=n, ncol=n)
    rownames(scores) <- names(clusters)
    colnames(scores) <- names(clusters)

    for (i in seq_along(clusters)) {
        gos1 <- unlist(cluster_gos[[i]])
        gos1 <- gos1[!is.na(gos1)]
        for (j in seq_len(i)) {
            gos2 <- unlist(cluster_gos[[j]])
            gos2 <- gos2[!is.na(gos2)]
            if (length(gos1) != 0 && length(gos2) !=0)
                scores[i, j] <- subsetCombine(go_matrix, gos1, gos2, combine)
                scores[j, i] <- scores[i, j]
        }
    }
    removeRowNA <- apply(!is.na(scores), 1, sum) > 0
    removeColNA <- apply(!is.na(scores), 2, sum) > 0
    return(scores[removeRowNA, removeColNA, drop = FALSE])
}
