# TODO: Add comment
# 
# Author: E.Korsching  ?? 2020 ??
###############################################################################



####   union/intersections
iu.set <- function(x, idv=NULL, setfn="ic", raw=F, name=""){
	# x: get a list of named objects:  vector, data.frame columns  --  min.: 2 list elements
	#  e.g.: list(a=expA, b=expB, ... ) or list(expA, expB, ... )
	#  and return   a union (u)  or  an  intersection : common of all (ic)  or  unique for each (ue)
	# idv: vector handling -- vector with numbers as long as the number of list elements:
	#      -1: use row.names, 0: use vector as is, 1..n: select column by number and use column as is
	# setfn: character: which type of set function (see: return)
	# raw: assign raw matrix to workspace,  name: object name for raw export or use default name
	# return: 0   or  one vector (u,ic)  or  list of vectors (ue)  after applying the setfn on all elements
	
	# ini
	if(is.null(idv)){ stop("idv missing") }
	l.len <- length(x)		# list length
	if(l.len<2){ stop("needs >=2 target vectors") }
	if(setfn!="u"&setfn!="ic"&setfn!="ue"){ stop("setfn must be one of: u, ic, ue") }
	
	l.names <- names(x)
	if(is.null(l.names)){ l.names <- as.character(1:l.len) }
	# get unique elements
	l.ent <- vector("list",l.len)
	for(i in 1:l.len){
		if(idv[i]==-1){ l.ent[[i]] <- unlist( dimnames(x[[i]])[[1]] ) }
		if(idv[i]==0){ l.ent[[i]] <- x[[i]] }		# idv==0 : nothing to do, a vector as is
		if(idv[i]>0){ l.ent[[i]] <- unlist( x[[i]][,idv[i]] ) }
	}
	tmp <- unlist(l.ent)	# chain all list vectors one after each other
	uni.el <- unique(tmp)	# remove duplicates , is a character string afterwards
	uni.el.len <- length(uni.el)
	
	# create logical matrix
	mat <- matrix(0,uni.el.len,l.len)	# will even create something with 0 rows
	dimnames(mat)[[1]] <- uni.el
	dimnames(mat)[[2]] <- l.names
	for(i in 1:l.len){
		mat[,i] <- uni.el %in% l.ent[[i]]
	}
	if(raw){
		if(name==""){ name <- "a.set" }
		assign(name, mat, envir=.GlobalEnv)
	}
	
	# select
	if(setfn=="u"){
		if(uni.el.len==0){ return(0) }
		return(uni.el[order(uni.el)])	# union of all, one vector
	}
	if(setfn=="ic"){
		if(uni.el.len==0){ return(0) }
		logi <- rowSums(mat)==l.len
		uni.el <- uni.el[logi]		# common of all, one vector
		return(uni.el[order(uni.el)])
	}
	if(setfn=="ue"){
		l.i <- 1:l.len
		l.uni.out <- vector("list",l.len)
		names(l.uni.out) <- l.names
		if(uni.el.len==0){
			for(i in l.i){
				l.uni.out[[i]] <- 0
			}
			return(l.uni.out)
		}
		for(i in l.i){
			logi <- vector("logical",uni.el.len)
			for(j in 1:uni.el.len){
				logi[j] <- mat[j,i]==1 & sum(mat[j,l.i[-i]])==0		# unique for each, many vectors
#				cat("\n logi 2",logi[j])
			}
			if(sum(logi)==0){
				l.uni.out[[i]] <- 0
			}else{
				l.uni.out[[i]] <- uni.el[logi]
				l.uni.out[[i]] <- l.uni.out[[i]][order(l.uni.out[[i]])]
			}
		}
		return(l.uni.out)
	}
}



# test
#a <- c()
#b <- c()
#iu.set(x=list(a,b), idv=c(0,0), setfn="ue")
#
#a <- c("a","b","b","b","c")
#b <- c("a","b","c","b","b","e")
#c <- c("a","b","d","e")
#d <- c("a","b","b","b","c")
#d <- c("a","c","b","b","b")
#
#aa <- iu.set(x=list(a,b,c), idv=c(0,0,0), setfn="u")
#aa <- iu.set(x=list(a,b,c), idv=c(0,0,0), setfn="ic")
#aa <- iu.set(x=list(a,b,c), idv=c(0,0,0), setfn="ue")
#aa <- iu.set(x=list(a=a,b=b,c=c), idv=c(0,0,0), setfn="ue")
#aa <- iu.set(x=list(b=b,c=c), idv=c(0,0,0), setfn=c(1,2))
#aa <- iu.set(x=list(b=b,c=c,a=a), idv=c(0,0,0), setfn=c(1,2))
#aa <- iu.set(x=list(a=a,d=d), idv=c(0,0), setfn="ue")



