keggInfo <- function(database)
{
    ## FIXME return an object instead of a character vector
    url <- sprintf("%s/info/%s", .getRootUrl(), database)
    .getUrl(url, .textParser)
}


keggList <- function(database, organism)
{
    database <- paste(database, collapse="+")
    if (missing(organism))
        url <- sprintf("%s/list/%s", .getRootUrl(), database)
    else
        url <- sprintf("%s/list/%s/%s", .getRootUrl(), database, organism)
    if (database == "organism")
        return(.organismListParser(url))
    else if (identical(database, "genome"))
        return(.genomeListParser(url))
    .getUrl(url, .listParser, nameColumn=1, valueColumn=2)
}

keggFind <- function(database, query,
    option=c("formula", "exact_mass", "mol_weight"))
{
    if(missing(database))
        stop("'database' argument is required")
    if (!missing(option))
        option <- match.arg(option)
    if (is.integer(query) && length(query) > 1)
        query <- sprintf("%s-%s", min(query), max(query))
    query <- gsub("\\s", "+", query)
    query <- paste(query, collapse="+")
    url <- sprintf("%s/find/%s/%s", .getRootUrl(), database, query)
    if (!missing(option))
        url <- sprintf("%s/%s", url, option)
    .getUrl(url, .listParser, nameColumn=1, valueColumn=2)
}


keggGet <- function(dbentries,
    option=c("aaseq", "ntseq", "mol", "kcf", "image", "kgml"))
{
    if (length(dbentries) > 10)
        warning(paste("More than 10 inputs supplied, only the first",
            "10 results will be returned."))
    dbentries <- paste(dbentries, collapse="+")
    url <- sprintf("%s/get/%s", .getRootUrl(), dbentries)
    if (!missing(option))
    {
        url <- sprintf("%s/%s", url, option)

        if (option == "image")
            return(content(GET(url), type="image/png"))
        if (option %in% c("aaseq", "ntseq"))
        {
            t <- tempfile()
            cat(.getUrl(url, .textParser), file=t)
            if (option == "aaseq")
                return(readAAStringSet(t))
            else if (option == "ntseq")
                return(readDNAStringSet(t))
        }
        if (option %in% c("mol", "kcf", "kgml"))
            return(.getUrl(url, .textParser))
    }
    if (grepl("^br:", dbentries[1]))
        return(.getUrl(url, .textParser))
    .getUrl(url, .flatFileParser)
}

keggCompounds <- function(pathwayID)
{
    url <- sprintf("%s/link/cpd/%s", .getRootUrl(), pathwayID)
    .getUrl(url, .compoundParser)
}

.keggConv <- function(target, source)
{
    query <-paste(source, collapse = "+")
    url <- sprintf("%s/conv/%s/%s", .getRootUrl(), target, query)
    .getUrl(url, .listParser, nameColumn = 1, valueColumn = 2)
}

keggConv <- function (target, source, querySize = 100)
{
    groups <- .splitInGroups(source, querySize)
    answer <- lapply(groups, .keggConv, target = target)
    as(unlist(answer), "character")
}

keggLink <- function(target, source)
{
    if (missing(source))
    {
        url <- sprintf("%s/link/%s",
            .getGenomeUrl(), target)
        .getUrl(url, .matrixParser, ncol=3)
    } else {
        url <- sprintf("%s/link/%s/%s",
            .getRootUrl(), target, paste(source, collapse="+"))
    .getUrl(url, .listParser, nameColumn=1, valueColumn=2)

    }
    ## FIXME?? keggLink("pathway",c("hsa:10458", "ece:Z5100"))
    ## returns a list with duplicate names
}


listDatabases <- function()
{
    c("pathway", "brite", "module", "ko", "genome", "vg", "ag", "compound",
          "glycan", "reaction", "rclass", "enzyme", "disease", "drug",
          "dgroup", "environ", "genes", "ligand", "kegg")
}

## This is not strictly speaking an API supported by the KEGG REST
## server, but it seems useful, and does not use SOAP, so I'm leaving it in.
color.pathway.by.objects <- function(pathway.id, object.id.list,
    fg.color.list, bg.color.list)
{
    ## example: https://www.kegg.jp/kegg-bin/show_pathway?eco00260/b0002%09%23ff0000,%2300ff00/c00263%09%23ffff00,yellow
    ## also works to include organism code in gene IDs
    ## (but don't include path: in pathway id)
    ## documentation here: https://www.kegg.jp/kegg/webapp/color_url.html

    pathway.id <- sub("^path:", "", pathway.id)
    if (!(length(object.id.list)==length(fg.color.list) &&
          length(fg.color.list) == length(bg.color.list))) {
        stop(paste("object.id.list, fg.color.list, and bg.color.list must",
            "all be the same length."))
    }

    # format identifier/color list as expected by server
    # according to https://www.kegg.jp/kegg/webapp/color_url.html
    payload <- paste(
        object.id.list,
        paste(bg.color.list, fg.color.list, sep=','),
        sep=" ",
        collapse="\n"
    )

    # Return the URL of the KEGG pathway diagram page where client-side
    # coloring is rendered by the browser
    paste0(
        "https://www.kegg.jp/kegg-bin/show_pathway?map=",
        pathway.id,
        "&multi_query=",
        utils::URLencode(payload, reserved = TRUE)
    )
}

