## name_tree.r

parse_name_tree <- function(name_tree, sep="$", showWarnings=TRUE) {
  setnamesIfBlank_(name_tree, allow_partial_changes=FALSE)
  if (showWarnings && any(grepl(sprintf("(^|%s)\\[\\[\\d", sep), name_tree)))
    warning ("'[[x]]' detected as a name in the name_tree. The indecies, when parsed, will be non-functional in the standard form")
  ##RETURN
  strsplit(name_tree, escapeRegEx(sep))
}

find_name_in_name_tree <- function(what, name_tree=name_tree_of_list(ll, sep=sep), ll, ignore.case=FALSE, value=!missing(ll), sep="$") {
## value:  if TRUE: return the names in name_tree that match
##         if FALSE: return the logical vector of whether or not each name_tree matched
## if name_tree is missing, value defaults to TRUE (ie, ll is given). Otherwise, value defaults to FALSE
  
  if (missing(name_tree) && missing(ll))
    stop ("Either 'name_tree' or 'll' must be given explicitly")

  if (length(what) > 1)
    stop ("How would you like to handle a vectorized 'what' -- one single return or multiple returns?")


  pat.sep <- escapeRegEx(sep)
  pat <- sprintf("(^|%s)%s($|%s)", pat.sep, what, pat.sep)
  ret <- grepl(pat, name_tree, ignore.case=ignore.case)
  if (isTRUE(value))
    return(name_tree[ret])
  return(ret)
}

name_tree_of_list <- function(ll, parent_name=NULL, endnode_names_included=FALSE, is_top=TRUE, sep="$") {
## Creates a single string for each endnode showing the parent-node names, separated by sep
## if endnode_names_included is TRUE, and the ending vector has names, those names will be included
##                                     if the ending vector does NOT have names, the string will end in sep
## if endnode_names_included is FALSE, results are same as if ending vector did not have names, however there will not be a trailing sep

  nms <- names(ll)

  if (!is.list(ll)) {
    if (endnode_names_included)
      return(paste(parent_name, nms, sep=sep))
    return(parent_name)
  }

  # if (!is.list(ll))
  #   return(paste(parent_name, nms, sep="$"))

  # browser(text = "name_tree")
  if (is.null(nms))
    nms <- sprintf("[[%i]]", seq_along(ll))

  next_parent_name <- paste(parent_name, nms, sep=if(!is_top) sep else "")

  ret <- mapply(name_tree_of_list, ll=ll, parent_name=next_parent_name, endnode_names_included=endnode_names_included, is_top=FALSE, sep=sep)
  if (is_top)
    return(unlist(ret, use.names=TRUE))
  return(ret)
}
