adduct.search <-
function(ftlist, mz.tol = 3e-3, adducts = 0, mode = "+", onlyIsotopes = TRUE, fplot = TRUE){

cat("ADDUCT ANALYSIS:\n", sep = "")
if (is.data.frame(adducts)){
    info_ad <- adducts
} else {
    info_ad <- adduct.list(mode)
}

if (length(info_ad$labels)!=length(info_ad$masses)){
    cat("ERROR: Labels and masses lengths are not equal...",sep="")
    return()
}

Nfeat <- dim(ftlist$isotopes)[1]
rmv   <- union(ftlist$isotopes[,2],ftlist$isotopes[,3])
rmv   <- sort(rmv)
rmv<-rmv[2:length(rmv)]

index <- which(ftlist$isotopes[,3]!=0)
for (i in 1:length(index)){
    a <- which(ftlist$isotopes[index[i],1]==ftlist$isotopes[,1])
    if (length(a)>1){
        ftlist$isotopes[index[i],1] <- 0
        ftlist$isotopes[a[1],c(3,6)]<- ftlist$isotopes[a[2],c(3,6)]
    }
} 
ftlist$isotopes <- ftlist$isotopes[which(ftlist$isotopes[,1]!=0),]

corr <- ftlist$feature.set
kk      <- round(length(ftlist$feature.set[,1])/10)
cat("- Creating isotope list: ",sep="")
for (i in 1:length(ftlist$feature.set[,1])){
    if (any(ftlist$feature.set[i,1]==rmv) | any(ftlist$feature.set[i,2]==rmv)) corr[i,1] <- 0
    if (((i-1) %% kk) == 0) cat(10*(i-1)/kk,"% ",sep="")
} 
cat("100%\n",sep="")
corr <- corr[which(ftlist$feature.set[,1]!=0),]

if (onlyIsotopes) g1 <- sort(unique(ftlist$isotopes[,1]))
else g1 <- sort(unique(union(ftlist$feature.set[,1],ftlist$feature.set[,2])))

ftlist$labels <- info_ad$labels
ftlist$masses <- info_ad$masses
mand <- which(ftlist$labels=="[M+H]")
ftlist$masses <- ftlist$masses[setdiff(1:length(ftlist$masses),mand)]-ftlist$masses[mand]
ftlist$labels <- ftlist$labels[setdiff(1:length(ftlist$labels),mand)]

adducts <- matrix(0,length(g1),1+length(ftlist$masses))
k       <- 1
kk      <- round(length(g1)/10)
cat("- Adduct patterns search: ",sep="")
for (i in 1:length(g1)){
    if (((i-1) %% kk) == 0) cat(10*(i-1)/kk,"% ",sep="")
    where <- which(corr[,1]==g1[i] | corr[,2]==g1[i])
    if (length(where)>0){
    if (length(where)==1) data <- matrix(corr[where,c(1,2,6)],1,3)
    else data  <- corr[where,c(1,2,6)]
    z     <- which(data[,1]!=g1[i])
    data[z,3] <- -data[z,3]
    data[z,c(1,2)] <- data[z,c(2,1)]
    ms    <- kronecker( matrix(1,length(data[,1]),1) , matrix(ftlist$masses,1,length(ftlist$masses)))
    ds    <- kronecker( matrix(1,1,length(ftlist$masses)) , matrix(data[,3],length(data[,3]),1))
    ds    <- abs(ds-ms) < mz.tol
    adduct<- which(apply(ds,2,sum)==1)
    if (length(adduct)>0){
        adducts[k,1] <- data[1,1]
        for (j in 1:length(adduct)){
            adducts[k,1+adduct[j]]  <- data[which(ds[,adduct[j]]==1),2]
        } 
        k <- k+1
    }}
} 
cat("\n",sep="")
adducts <- adducts[1:k-1,]
if (length(adducts[1,])>2){
    counts <- apply(adducts[,seq(2,length(adducts[1,]))]!=0,2,sum) 
} else{
    counts <- sum(adducts[,seq(2,length(adducts[1,]))]!=0) 
}

if (fplot) {
  par(las=2)
  par(mar=0.1+c(7,4,3,1))
  barplot(counts, names.arg=ftlist$labels,main="Ion groupping", ylab="#Pairs", cex.names=.7)
  par(mar=0.1+c(5,4,4,2))
  par(las=0)
}
cat("\t- M/Z tolerance:\t+/-",mz.tol,"u\n",sep="")
for (i in 1:length(ftlist$labels)) {
  if (counts[i]>0) cat("\t- ",counts[i]," ",ftlist$labels[i],"adducts.\n", sep = "")
}
ftlist$adducts <- adducts

indexes <- sort(ftlist$isotopes[,1])
final   <- matrix(0,length(indexes),5+length(ftlist$labels))
for (i in 1:length(indexes)){
    final[i,1] <- indexes[i]
    a <- which(ftlist$isotopes[,1]==indexes[i])
    if (length(a)>0) final[i,c(2,3,4,5)]<-c(ftlist$isotopes[a,2],ftlist$isotopes[a,5]/ftlist$isotopes[a,4],ftlist$isotopes[a,3],ftlist$isotopes[a,6]/ftlist$isotopes[a,4])
    a <- which(ftlist$adducts[,1]==indexes[i])
    if (length(a)>0) final[i,seq(6,dim(final)[2])]<-ftlist$adducts[a,seq(2,dim(ftlist$adducts)[2])]
}
colnames(final) <- c("C12isotope","C13#1 isotope","C13#1 ratio","C13#2 isotope","C13#2ratio",ftlist$labels)
return(final)
}
