##+++++++++++++++++++++++++++++++++++++++++++++++##
## THE FIRST FUNCTION IS FROM STACK OVERFLOW.    ##
## I WANT TO MAKE A SIMILAR FUNCTION THAT GIVES  ##
## VECTORS INDEXING THE STRUCTURE OF THE LIST.   ##
##                                               ##
##  eg:                                          ##
##       c(1, 1)                                 ##
##       c(1, 2)                                 ##
##       c(2, 1)                                 ##
##       c(2, 2)                                 ##
##  as the output for shortList below.           ##
##                                               ##
##+++++++++++++++++++++++++++++++++++++++++++++++##




##############################################################

##+++++++++++++++++++++++++++++++++++##
## THIS FUNCTION FROM STACK OVERFLOW ##
##+++++++++++++++++++++++++++++++++++##

## Find the deepest level of the list

## TODO:  Return with this a list of vectors tracing the path down the longest depth
listDepth.fromSO <- function(this,thisdepth=0){
  if(!is.list(this)){
    return(thisdepth)
  }else{
    return(max(unlist(lapply(this,listDepth.fromSO,thisdepth=thisdepth+1))))    
  }
}
+++++++++++++++++++++++++++++++++++++++
depth <- function(x, counter=0) {
# Returns the depth of a list-like object.  
# Vectors are considered to have depth 0
# an un-nested list has depth 1  
  ifelse (!is.list(x), counter, max(sapply(x, depth, counter+1)))  
}


+++++++++++++++++++++++++++++++++++++++
listStr.IdenticalToList <- function(this, pre=NULL, thisdepth=0) {
  ## This works, but returns as a list that I need to smoosh
  if (!is.list(this))
    return(pre)

  s <- seq(length(this))
  inds <- lapply (s, function(i) c(pre, i) )
  lapply(s, function(i) listStr.IdenticalToList(this[[i]], pre=inds[[i]]))
}
+++++++++++++++++++++++++++++++++++++++

listStr <- function(this, pre=NULL, thisdepth=0) {
  if (!is.list(this))
    return(pre)

  s <- seq(length(this))
  soFar <- lapply (s, function(i) c(pre, i) )
  ret <- lapply(s, function(i) listStr(this[[i]], pre=soFar[[i]]))
  ret <- lapply(ret, function(el) if(!is.list(el)) {rbind(el)} else {do.call(rbind, el)} )
  ret <- lapply(ret, unname)
  ret
}

##############################################################

---------
nll <- function() {cat("----------------------------\n")} 
nl  <- function() {cat("\n")}
---------

##############################################################

##+++++++++++++++++++++++++++++++++++##
##          BEGIN HERE               ##
##+++++++++++++++++++++++++++++++++++##


listStr <- function(this, pre=NULL, thisdepth=0) {
  if (!is.list(this))
    return(pre)

  s <- seq(length(this))
  soFar <- lapply (s, function(i) c(pre, i) )
  
  ## IF ALL THE NESTED LISTS ARE OF SAME SIZE, THIS LINE WORKS
  do.call(rbind, lapply(s, function(i) listStr(this[[i]], pre=soFar[[i]])))

  ## IF ALL THE NESTED LISTS ARE NOT THE SAME SIZE, THEN USE THESE LINES
   # ret <- lapply(ret, function(el) if(!is.list(el)) {rbind(el)} else {do.call(rbind, el)} )
   # lapply(ret, unname)
}

listStr(shortList)
listStr(medList)
listStr(myList)
str(myList)

rbindNA <- function(...) {
  cl <- list(...)
  mxlength <- max(sapply(cl, length))
  listWithNA <- lapply(cl, function(el) ifelse (length(el) < mxlength, c(el, rep(NA, mxlength-length(el))), el))
#  listWithNA$mxlength <- mxlength
  # return(listWithNA)
  do.call(rbind, listWithNA)
}
x <- rbindNA(listStr(myList))
x
do.call(rbindNA, listStr(myList))


---------
lapply(this, listStr, pre=seq(length(this)))

    seq(length(this)) + lapply(this, seq(length))



  ret <- mapply(c, seq(length(this)), listStr(this))
  return(ret)
}

####################### 
## EXAMPLE ##


f <- function(x) if (!is.list(x)) return(NULL) else return(seq(length(x)))
  #else
  return (lapply(this, listStr, pre=c(pre, seq(length(this)))))
}

  PRE   SEQ  nextlevel
[-----] [-] [-]
3, 3, 1  1   1
             2
             3
             4 
         2   1
             2
             3 
         3

1a  : 
2a  : 

1a  : 1a 1
      1a 2

2a  : 2a 1
      2a 2



1 1 AA
1 2 AB

2 1 BA
2 2 BB

  levs <- seq(length(this))
}
unname(shortList)
shortList <- list(A=list("AA", "AB"), B=list("BA", "BB"))




1, 1, 1, 1, 1, 1, A
1, 1, 1, 1, 1, 2, B
1, 1, 1, 1, 1, 3, C

1, 1, 1, 1, 2, 1
1, 1, 1, 1, 2, 2
1, 1, 1, 1, 2, 3


ind <- c(1, 1, 1, 1, 1, 1)
myList[[ind]]

1         List of 2
           $ :List of 2
            ..$ :List of 2
            .. ..$ :List of 2
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. ..$ :List of 2
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            ..$ :List of 2
            .. ..$ :List of 2
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. ..$ :List of 2
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
            .. .. ..$ :List of 3
            .. .. .. ..$ : chr "A"
            .. .. .. ..$ : chr "B"
            .. .. .. ..$ : chr "C"
           $ :List of 2
            ..$ :List of 3
            .. ..$ : chr "A"
            .. ..$ : chr "B"
            .. ..$ : chr "C"
            ..$ :List of 3
            .. ..$ : chr "A"
            .. ..$ : chr "B"
            .. ..$ : chr "C"



listDepth(myList)


####  SAMPLE DATA #######

## SHORT 
shortList <- structure(list(A = list("AA", "AB"), B = list("BA", "BB")), .Names = c("A", "B"))

## MEDIUM
medList <- list(A = list("AA", "AB", "AC"), B = list("BA", "BB"), C = list("CA", "CB", "CC"))

## MEDIUM
longList <- list(AandB=list(A = list("AA", "AB", "AC"), B = list("BA", "BB")), C = list("CA", "CB", "CC"))


#### LONGER
Lev0 <- list("A", "B", "C")
Lev1 <- list(Lev0, Lev0)
Lev2 <- list(Lev1, Lev1)
Lev3 <- list(Lev2, Lev2)
myList <- list(Lev3, Lev1, Lev2)
str(myList)
length(myList)
sapply(myList, length)
sapply(sapply(myList, function(x) x), length)

     
