.packageName <- "y2hStat"


baitsOnly <- function(y2h){

    ##this function returns a list of type y2h; the only values of the
    ##list are those proteins that have been sampled as baits 
    baits <- lapply(y2h, names)

    inOrNot <- vector("list", length=length(y2h))
    names(inOrNot) <- names(y2h)

    for(i in 1:length(inOrNot)){
        inOrNot[[i]] <- list()
        
    }

    for (i in 1:length(inOrNot)){
      inOrNot[[i]] <- lapply(y2h[[i]], function(x) {x %in% baits[[i]]})
    }

    for(i in 1:length(y2h)){
        for(j in 1:length(y2h[[i]]))
          y2h[[i]][[j]] <- y2h[[i]][[j]][inOrNot[[i]][[j]]]
    }

    y2h
}
bpMatrix <- function(y2h, symMat = TRUE, homodimer=TRUE){

    baits <- unique(unlist(lapply(y2h, names)))
    preys <- unique(unlist(lapply(y2h, unlist))) 

    counter <- 1
    
    if(symMat){

        allProt <- union(baits, preys)
        baits <- allProt
        preys <- allProt

    }
    
    bpMat <- matrix(0, nrow <- length(baits), ncol <- length(preys))
    #print(dim(bpMat))
    dimnames(bpMat) <- list(baits, preys)

    for(i in 1:length(y2h)){

        if (length(y2h[[i]]) > 0){
            for(j in 1:length(y2h[[i]])){
                
                baitNames <- names(y2h[[i]])
                if(length(y2h[[i]][[j]])>0){
                    for(k in 1:length(y2h[[i]][[j]])){
                        preyNames <- y2h[[i]][[j]]
                        #print( bpMat[baitNames[j], preyNames[k]])
                        bpMat[baitNames[j], preyNames[k]] <- bpMat[baitNames[j], preyNames[k]] + 1
                        #print( bpMat[baitNames[j], preyNames[k]])
                        
                        #print(counter)
                        #counter <- counter+1
                    }
                    
                }
                
            }
        }
        
    }
    #print(sum(bpMat))
    if(!homodimer){diag(bpMat)=0}
    bpMat
    
}

collectBPStats <- function(bpMat, weight){

    baits <- rownames(bpMat)
    preys <- colnames(bpMat)
    
    edgeWeight <- as.numeric(names(table(bpMat)))
    bpStat <- list()
    
    for(i in 1:length(weight)){
        
        if(!(weight[i] %in% edgeWeight)){
            print(paste(weight[i], "is not an edge weight.", sep = " "))
        }
        
        else{
            ind <- which(bpMat == weight[i], arr.ind=TRUE)
            bpStat[[paste("Weight", weight[i], sep="")]] <- list()
            for(j in 1:nrow(ind)){
                bpStat[[paste("Weight", weight[i], sep="")]][[j]] <-
                  c(baits[ind[j,1]], preys[ind[j,2]])
            }
        }
    }

    bpStat
    
}
collectIntactData <- function(intactID = c("EBI-375746", "EBI-531419", "EBI-295760", "EBI-698096",
                                      "EBI-592695", "EBI-476385", "EBI-476699", "EBI-493706", "EBI-620118",
                                      "EBI-619785", "EBI-492533", "EBI-492535", "EBI-697014", "EBI-538313",
                                      "EBI-538324", "EBI-531492", "EBI-526219", "EBI-491968", "EBI-707901",
                                      "EBI-74070",  "EBI-603898", "EBI-597864", "EBI-455820", "EBI-457380",
                                      "EBI-457455", "EBI-79957",  "EBI-603955", "EBI-600030", "EBI-600812",
                                      "EBI-601450", "EBI-75443",  "EBI-727915", "EBI-607722", "EBI-525791",
                                      "EBI-476132", "EBI-49802",  "EBI-491628", "EBI-491642",
                                      "EBI-783101", "EBI-762635",
                                      "EBI-389903", "EBI-392769")){


    options(error=recover)
    fileToRead <- system.file("data", "tableList.rda", package = "y2hStat")
    load(fileToRead)
    data(sWAC2Sys)
    shortLabel <- vector()
    for(i in 1:length(intactID)){
        sLabel <- tableList[["acInfo"]][,"ac"] %in% intactID[i]
        shortL <- tableList[["acInfo"]][sLabel,"shortLabel"]
        shortL <- unique(shortL)
        print(shortL)
        shortLabel <- c(shortLabel, shortL)
        #print("---")
        #print(shortLabel)
    }

    n <- length(intactID)


    ##We chose all the id's that were either labelled bait or prey
    isBait <- tableList[["interaction2interactor"]][, "role"] == "bait"
    isPrey <- tableList[["interaction2interactor"]][, "role"] == "prey"
    
    ##For each experiment, we wanted to collect every interaction associated;
    ##So for each experiment, there will be k interactions...we want them all
    ##Here we simple get the row indices...
    isExp = vector("list", length = n)
    for (i in 1:n){
        
        isExp[[i]] <- tableList[["experiment2interaction"]][, "experiment"] ==
          intactID[i]
    }

    ##From the indices collected above, we subset the table so all the interactions of
    ##a particular experiment are collected:
    interaction <- vector("list", length = n)
    for (i in 1:n){

        interaction[[i]] <-  tableList[["experiment2interaction"]][isExp[[i]],"interaction"]
    }

    ##Now we go to another table. We want to find all the players in the interactions we
    ##have collected above. The following returns a logical...we will get the row index
    ##if the interaction is the one in which we are interested: 
    interactor <- vector("list", length = n)
    for (i in 1:n){

        interactor[[i]] <- tableList[["interaction2interactor"]][,"interaction"]%in% interaction[[i]]
    }
    
    ##Now we go into the same table as above; for each interaction, we want only those
    ##players corresponding to that interaction...since this is y2h, everyone element
    ##should only have two items...here we merely get the row indices
    b2p <- vector("list", length = n)
    for (i in 1:n){

        b2p[[i]] <- lapply(interaction[[i]], function(x)
                       which(tableList[["interaction2interactor"]][, "interaction"] == x))
    }

    ##In this list, we systematically build our interactions. We take the double row numbers
    ##collected above, and create a list of interactions.
    b2pList <- vector("list", length = n)
    for (i in 1:n){

        b2pList[[i]] <- lapply(b2p[[i]], function(x){
            tableList[["interaction2interactor"]][x,]
        })
    }

    ##This checks to see which element in b2pList is the bait
    check1 <- vector("list", length = n)
    for(i in 1:n){

        check1[[i]] <- sapply(b2pList[[i]], function(x) which(x[,"role"] == "bait"))
    }

    ##This checks for the prey
    check2 <- vector("list", length = n)
    for(i in 1:n){

        check2[[i]] <- sapply(b2pList[[i]], function(x) which(x[,"role"] == "prey"))
    }

    ##Later we will use the bait-prey pairs to build either a data.frame, an adjacency
    ##matrix, or a list of matrices. From the b2pList, we simple extract the bait element
    ##and then the prey element.
    indexSetAll <- vector("list", length = n)
    for (i in 1:n){

        indexSet <- vector("list", length = length(b2pList[[i]]))
        for(j in 1:length(indexSet)){
            indexSet[[j]] = c(b2pList[[i]][[j]][check1[[i]][j], "interactor"],
                              b2pList[[i]][[j]][check2[[i]][[j]], "interactor"])
        }

        indexSetAll[[i]] <- indexSet
    }

    names(indexSetAll) <- shortL

    ##We create a list of all the baits for each experiment.
    baits <- vector("list", length = n)
    for (i in 1:n){

        Baits <- tableList[["interaction2interactor"]][(interactor[[i]] & isBait),"interactor"]
        uBait = unique(Baits)
        baits[[i]] <- uBait       
    }

    ##We create a list of all the prey for each experiment
    preys <- vector("list", length = n)
    for (i in 1:n){

        Preys <- tableList[["interaction2interactor"]][(interactor[[i]] & isPrey),"interactor"]
        uPrey = unique(Preys)
        preys[[i]] <- uPrey        
    }

    ##We take the union of all the baits
    allBaits <- vector()
    for (i in 1:length(baits)){

        allBaits <- union(allBaits, baits[[i]])
    }

    ##We take the union of all the preys
    allPreys <- vector()
    for (i in 1:length(baits)){
        allPreys <- union(allPreys, preys[[i]])
    }


    numBaits = length(allBaits)
    numPreys = length(allPreys)

    ##This method will still leave the user with certain proteins that need
    ##to be mapped by hand!

    
    baitsSystematic <- map2Systematic(allProt = allBaits, tableList = tableList, sWAC = sWAC2Sys)
    preysSystematic <- map2Systematic(allProt = allPreys, tableList = tableList, sWAC = sWAC2Sys)


    dataList <- list()
    #dataList$numBaits <- numBaits
    #dataList$numPreys <- numPreys
    dataList$allBaits <- allBaits
    dataList$allPreys <- allPreys
    #dataList$intactID <- intactID
    dataList$indexSetAll <- indexSetAll
    dataList$baitsSystematic <- baitsSystematic
    dataList$preysSystematic <- preysSystematic
    dataList$shortLabel <- shortLabel
    #dataList$tableL <- tableList
    
    dataList

}





collectMembranePPI <- function(){
    #options(error=recover)
    dataPPI <- readLines(system.file("extdata", "memPPIedited.txt", package = "y2hStat"))
    PPI <- strsplit(dataPPI, " +", perl=TRUE)
    baits <- sapply(PPI, function(x) x[1])
    preys <- sapply(PPI, function(x) x[2])

    PPIList <- split(preys, baits)

    PPIList

}
createBPList <- function(indexSet, baitsSystematic, preysSystematic){

    baits <- lapply(indexSet, function(x) {sapply(x, function(y) y[1])})
    preys <- lapply(indexSet, function(x) {sapply(x, function(y) y[2])})

    
    bSys <- lapply(baits, function(x) {sapply(x, function(y) intAct2Sys(y, baitsSystematic))})
    
    

    pSys <- lapply(preys, function(x) {sapply(x, function(y) intAct2Sys(y, preysSystematic))})
        
    result <- list()

    
    for(i in 1:length(bSys)){
        
        result[[i]] <- split(pSys[[i]], bSys[[i]])
        
    }

    names(result) <- names(indexSet)
    result
    
}
createTables <- function(y2h){

    #authors <- names(y2h)
    numBaits <- sapply(y2h, length)
    numInteractions <- sapply(y2h, function(x){sum(sapply(x, length))})
    ratio <- numBaits/numInteractions
    deg <- degreeStats(y2h)
    meanDeg <- unlist(deg$mean)
    medianDeg <- as.integer(unlist(deg$med))
    maxDeg <- unlist(deg$max)
    minDeg <- unlist(deg$min)
    

    tab <- cbind(cbind(cbind(cbind(cbind(cbind(numBaits, numInteractions), ratio), minDeg), maxDeg), medianDeg), meanDeg)

    dimnames(tab) <- list(names(y2h), c("Total Baits", "Total Interactions",
                                        "Bait per Interaction",
                                        "Minimum Degree",
                                        "Maximum Degree",
                                        "Median Degree",
                                        "Mean Degree"))

    tab
    
    
}
degreeStats <- function(y2h){

   degree <- lapply(y2h, function(x) {sapply(x, length)})

   minD <- lapply(degree, min)
   maxD <- lapply(degree, max)
   medD <- lapply(degree, median)
   avgD <- lapply(degree, mean) 

   deg <- list()

   deg$degree <- degree
   deg$min <- minD
   deg$max <- maxD
   deg$med <- medD
   deg$mean <- avgD

   deg


}
findComplexBP <- function(amMat, ISI){

    compBP <- list()
    for (i in 1:ncol(ISI)){

        protInComp <- names(ISI[which(ISI[,i] == 1),i])
        compBP[[i]] <- amMat[intersect(protInComp, rownames(amMat)), intersect(protInComp, colnames(amMat)), drop=FALSE]

    }

    names(compBP) <- colnames(ISI)
    compBP

}
genBPGraph <- function(y2h, sym=FALSE, inNuc=FALSE, nonWeighted=FALSE, homodimer=TRUE){
    #options(error=recover)
    if(inNuc){

        nuc <- inNucleus(y2h)
        for(i in 1:length(y2h)){
            for(j in 1:length(y2h[[i]])){
                y2h[[i]][[j]] <- y2h[[i]][[j]][nuc$nuclearY2H[[i]][[j]]]
            }

        }

    }

    if(sym){
        symList <- symInteraction(y2h)
        #print(symList)
        bpMat <- bpMatrix(symList, symMat=TRUE, homodimer=homodimer)
        #bpGraph <- as(bpMat, "graphNEL")
    }
    
    else{

        bpMat <- bpMatrix(y2h, symMat=TRUE, homodimer=homodimer)
        #bpGraph <- as(bpMat, "graphNEL")
        
    }

    if(nonWeighted){
        mode(bpMat) = "logical"
        mode(bpMat) = "numeric"
    }
    
    bpMat
}







inNucleus <- function(y2h, ISI=NULL){

    
    yG2P <- as.list(YEASTGO2ALLPROBES)
    nucProt <- yG2P[["GO:0005634"]]
    if(!is.null(ISI)){
        cnames <- colnames(ISI)
        nucComp <- vector()
    
        for(i in 1:ncol(ISI)){
            
            hits <- names(which(ISI[,i]==1))
            nucC <- hits %in% nucProt
            if(sum(nucC)/sum(ISI[,i]) > 0.75){
                nucComp <- c(nucComp, cnames[i])
            }
            
        }
    }

    else{nucComp <- NULL}
    
    ckNuc <- lapply(y2h, function(x) {sapply(x, function(y) {y %in% nucProt})})
    ckNuc
    
    nuc <- list()
    nuc$nuclearProt <- nucProt
    nuc$nuclearComp <- nucComp
    nuc$nuclearY2H <- ckNuc

    nuc
    

    
}
intAct2Sys <- function(prot2Sys, bpSysL){
    options(error=recover)
    if(!is.null(names(bpSysL[[prot2Sys]])) && !is.na(names(bpSysL[[prot2Sys]]))){

        mapping <- intAct2Sys(names(bpSysL[[prot2Sys]])[1], bpSysL[[prot2Sys]])
   }

    else{

        if(!is.null(bpSysL[[prot2Sys]]) && bpSysL[[prot2Sys]] != "ND"){

            return(bpSysL[[prot2Sys]][1])

        }

        else{
            return(prot2Sys)
        }
          
        
    }

    mapping
    
}
map2Systematic <- function(allProt, tableList, sWAC){
    #print(allProt)

    ##The baitSystematic vector will be a mapping of the Intact codes to Yeast Systematic Names
    protSystematic <- vector(length = length(allProt))
    yeast2Sys <- as.list(YEASTCOMMON2SYSTEMATIC)
    yeast2Sys <- yeast2Sys[!is.na(yeast2Sys)]
    yeastAlias <- names(unlist(as.list(YEASTALIAS)))
    yro <- unlist(as.list(YEASTREJECTORF))
    #notfound <- vector()
    #notfoundSGD <- vector()
    #notfound2 <- vector()
    #notfound2SGD <- vector()
    one2Many <- vector("list", length = length(allProt))
    
    for(i in 1:length(allProt)){

        ProtN <- allProt[i]
        
        whichProt <- tableList[["ac2xref"]][, "ac"] %in% ProtN
        subTable <- tableList[["ac2xref"]][whichProt,1:4]
        #print(subTable)
        onlyWantSgd = which(subTable[,"db"] == "sgd")
        ac2SgdCode = split(subTable[onlyWantSgd,4], subTable[onlyWantSgd,1])
        ac2SgdCode <- lapply(ac2SgdCode, unique)
        sgdC <- unlist(ac2SgdCode)
        sgdC <- unique(sgdC)
        #print(sgdC)
        #print(ProtN)
        #print(i)
        
        if (length(sgdC) == 1){

            if (!is.null(yeast2Sys[[sgdC]])){
                protSystematic[i] <- yeast2Sys[[sgdC]][1]
                
                one2Many[[i]] <- yeast2Sys[[sgdC]]
                
            }
            
            else {

                
                
                if(sgdC %in% yeastAlias || sgdC %in% yro){
                    protSystematic[i] <- sgdC
                    one2Many[[i]] <- sgdC
                }
                
                else{

                 

                  if(substr(sgdC,1,1)=="Y"){
                        protSystematic[i] <- sgdC
                        one2Many[[i]] <- sgdC
                      }
                  else{

                    aN <- map2Systematic2(ProtN, tableList, sWAC)
                    aN <- unlist(aN)
                      if(!is.na(aN)){
                          one2Many[[i]] <- aN
                      }
                      else{
                          one2Many[[i]] <- "ND"
                      }
                    if(!is.na(aN)){
                        if(substr(aN,1,1)=="Y"){
                            protSystematic[i] = aN
                        }
                        else{
                            protSystematic[i] <- ProtN
                        }
                    }
                    else{
                      protSystematic[i] <- ProtN
                  }
                }
              }
            }
        }
        
        else{
            #print("here")
            if(length(sgdC)==0){
                if(is.null(sgdC)){
                    aN <- map2Systematic2(ProtN, tableList, sWAC)
                    aN <- unlist(aN)
                    if(!is.na(aN)){
                        one2Many[[i]] <- aN
                    }
                    else{
                        one2Many[[i]] <- "ND"
                    }
                    #print(one2Many)
                    if(!is.na(aN)){
                        if(substr(aN,1,1)=="Y"){
                            protSystematic[i] = aN
                        }
                    }

                                        #tryUniProt <- which(subTable[,"db"] == "uniprotkb")
                    #ac2UniCode <- split(subTable[tryUniProt,4], subTable[tryUniProt,1])
                    #ac2UniCode <- lapply(ac2UniCode, unique)
                    #uniC1 <- unique(unlist(ac2UniCode))
                    #uniC <- map2Systematic2(uniC1, tableList, sWAC)
                    #protSystematic[i] <- yeast2Sys[[uniC]][1]
                    #one2Many[[i]] <- yeast2Sys[[uniC]]
                                        #uniC <- strsplit(uniC1, "_yeast", fixed=TRUE)
                    #uniC <- toupper(unique(unlist(uniC)))
                    #print(yeast2Sys[[uniC]][1])
                    #print(uniC)
                    #if (!is.null(yeast2Sys[[uniC]])){
                    #    protSystematic[i] <- yeast2Sys[[uniC]][1]
                        
                        
                    #    one2Many[[i]] <- yeast2Sys[[uniC]]
                        
                    #}

                    #else()
                    
                }

                else{
                    #print("there")
                    protSystematic[i] <- ProtN
                    one2Many[[i]] <- sgdC
                }
            }
            else {
                #print("where")
                one2Many[[i]] <- list()
                
                for(k in 1:length(sgdC)){
                    if(!is.null(yeast2Sys[[sgdC[k]]])){
                        #print("i should get here once")
                        one2Many[[i]][[sgdC[k]]] <- yeast2Sys[[sgdC[k]]]
                
                 
                 
                    }
                    else{

                        if(substr(sgdC[k],1,1)=="Y"){
                            one2Many[[i]][[sgdC[k]]] <- sgdC[k]
                        }
                        else{
                            one2Many[[i]][[sgdC[k]]] <- "ND"
                        }
                    }
                
                }
            }
        }
        #print(one2Many[[ProtN]])
    }
    

    #protSystematic
    names(one2Many) = allProt
    one2Many

}
map2Systematic2 <- function(allProt, tableList, sWAC){

    
    ##The baitSystematic vector will be a mapping of the Intact codes to Yeast Systematic Names
    #protSystematic <- vector(length = length(allProt))
    #yeast2Sys <- as.list(YEASTCOMMON2SYSTEMATIC)
    #yeast2Sys <- yeast2Sys[!is.na(yeast2Sys)]
    #yeastAlias <- names(unlist(as.list(YEASTALIAS)))
    #yro <- unlist(as.list(YEASTREJECTORF))
    #notfound <- vector()
    #notfoundSGD <- vector()
    #notfound2 <- vector()
    #notfound2SGD <- vector()
    
    #for(i in 1:length(allProt)){

        ProtN <- allProt
        whichProt <- tableList[["ac2xref"]][, "ac"] %in% ProtN
        subTable <- tableList[["ac2xref"]][whichProt,1:4]
        ###print(subTable)
        onlyWantAN = which(subTable[,"db"] == "uniprotkb")
        ac2ANCode = split(subTable[onlyWantAN,4], subTable[onlyWantAN,1])
        ac2ANCode <- lapply(ac2ANCode, unique)
        AN <- unlist(ac2ANCode)
        AN = unique(AN)
        if(class(AN) == "character"){
            AN <- strsplit(AN, "_yeast", fixed=TRUE)
            AN <- unlist(AN)
            AN <- toupper(AN)
        }

        
        if(!is.null(AN)){
          
          AN <- sWAC[AN]
          }
        
        if(length(AN)>0){
          return(AN)
        }
        else{
          return(allProt)
        }
    }

nucStat <- function(y2h, matL, square=FALSE){

    nucl <- inNucleus(y2h)
    nuc <- nucl$nuclearProt

    #matL2 <- matL

    matL2 <- lapply(matL, function(x){x[intersect(nuc, rownames(x)), intersect(nuc, rownames(x)), drop=FALSE]})

    #matL3 <- matL

    if(square){
        matL3 <- lapply(matL, function(x) {x[c(intersect(nuc, rownames(x)), setdiff(rownames(x),intersect(nuc, rownames(x)))),
                                             c(intersect(nuc, colnames(x)), setdiff(colnames(x),intersect(nuc, colnames(x))))]})
    }
    else{
        matL3 <- lapply(matL, function(x){x[intersect(nuc, rownames(x)),
                                            setdiff(colnames(x),intersect(nuc, colnames(x))), drop=FALSE]})
    }
    mat <- list()

    mat$nucNuc <- matL2
    mat$nucNot <- matL3

    mat

}
recipBP <- function(y2h, homodimer=TRUE){

    preyS <- lapply(y2h, function(x) {unique(unlist(x))})
    recip <- vector("list", length=length(preyS))
    for(i in 1:length(preyS)){
        if(homodimer){
            recip[[i]] <-
              names(y2h[[i]][preyS[[i]]])[!is.na(names(y2h[[i]][preyS[[i]]]))]
        }
        else{
            ck <-
              y2h[[i]][preyS[[i]]][!is.na(names((y2h[[i]][preyS[[i]]])))]
            toKeep <- vector()
            if(length(ck)>0){
                for(j in 1:length(ck)){
                    if(length(setdiff(ck[[j]], names(ck)[j])) != 0){
                        toKeep <- c(toKeep, names(ck)[j])
                    }
                }
                recip[[i]] <- toKeep
            }
        }
        
    }

    names(recip) <- names(preyS)
    recip

}
symInteraction <- function(y2h){
    #options(error=recover)

    sym <- vector("list", length=length(y2h))
    
    for(i in 1:length(sym)){
        baits <- names(y2h[[i]])
        sym[[i]] <- list()
        
        for(j in 1:length(baits)){
            
            for(k in 1:length(y2h[[i]][[baits[j]]])){
                
                preyOfInt <- y2h[[i]][[baits[j]]][k]
                
                if(length(preyOfInt) > 0){
                
                    if(!is.null(unlist(y2h[[i]][[preyOfInt]]))){
                        if (baits[j] %in% unlist(y2h[[i]][[preyOfInt]])){
                            
             
                            sym[[i]][[preyOfInt]] <- c(sym[[i]][[preyOfInt]],baits[j])
                        }
                        
                    }
                }
                
            }
        }
        
    }

    names(sym) <- names(y2h)
    sym
}
  
