.packageName <- "ctc"
hc2Newick <- function(hc, flat=TRUE) {

  dist <- 0
  if (is.null(hc$labels))
    labels <- seq(along=hc$order)
  else
    labels <- hc$labels

  putparenthesis <- function(i) {
    ## recursive function
    ## i: index of row in hc$merge
    j <- hc$merge[i, 1]
    k <- hc$merge[i, 2]
    
    if (j < 0) {
      left <- labels[-j]
      if (k > 0)
        dist <- hc$height[i] - hc$height[k]
      else
        dist <- hc$height[i]
    } else {
      left <- putparenthesis(j)
    }

    if (k < 0) {
      right <- labels[-k]
      if (j > 0)
        dist <- hc$height[i] - hc$height[j]
      else
        dist <- hc$height[i]
    } else {
      right <- putparenthesis(k)
    } 
    if (flat)
      return(paste("(", left, ":", dist/2, ",", right, ":", dist/2, ")", sep=""))
    else
      return(list(left=left, right=right, dist=dist))
  }
  
  n <- putparenthesis(nrow(hc$merge))
  if (flat)
    n <- paste(n, ";", sep="")
  
  return(n)
}
hclust2treeview <- function(x,file="cluster.cdt",method = "euclidean",
                              link = "complete",keep.hclust=FALSE)
  {
    if("amap" %in% .packages(all=TRUE))
      {
        hr <- hcluster (x,method =method, link=link)
        hc <- hcluster (t(x),method =method, link=link)
      }
    else
      {
        hr <- hclust(dist(x,method =method), method=link)
        hc <- hclust(dist(t(x),method =method), method=link)
      }
    basefile = strsplit(file,"\\.")[[1]]
    if(length(basefile>1))  
      basefile = paste(basefile[-length(basefile)],collapse=".")

    
    
    r2atr(hc,file=paste(basefile,".atr",sep=""))
    r2gtr(hr,file=paste(basefile,".gtr",sep=""))
    r2cdt(hr,hc,x ,file=paste(basefile,".cdt",sep=""))

    if(keep.hclust)
      return(list(hr,hc))
    else
      return(1)
  }
r2cdt <- function(hr,hc,data,labels=FALSE,description=FALSE,file="cluster.cdt",dec="."){
#-------------------------------------------------------
#
#  Created       : 20/11/02
#  Last Modified : Time-stamp: <2003-07-22 16:52:28 lucas>
#
#  Description   : Write data object to cdt 
#                  file (Xcluster or Cluster output).
#                  Should be use with r2gtr
#                  Visualisation of cluster can be
#                  done with tools like treeview
#
#                  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#
#  Licence       : GPL (r2xcluster, not Xcluster)
#
#-------------------------------------------------------
#
#

  n <- dim(data)[1]

  # Add GWEIGHT column
  data <- as.data.frame(cbind(1,data))
  

  # If the name column does not exist -> creation
  # of this column else: put column name on
  # first place. (column NAME in the file)
  if(!description){
    if(!labels){
      data <- cbind(row.names(data),data)
    }
    else{
      data <- cbind(as.factor(data[,2]),data)
    }
  }
  else{
    data <- cbind(as.factor(data[,3]),data[,-3])        
      }
  # column YORF in the file
  if(!labels){
    data <- cbind(row.names(data),data)
  }
  else{
    data <- cbind(as.factor(data[,3]),data[,-3])
  }

  # add GID column
  GID <- paste ('GENE',0:(n-1),'X',sep='')
  data <- cbind(as.factor(GID),data)

  # Put data in right order
  data <- data [hr$order,]

  m <- dim(data)[2]
  data[,5:m] <- data[,5:m][hc$order]
  colnames(data)[5:m] <-  colnames(data)[5:m][hc$order]
  
  # Round data
  data[,5:m] <- signif(data[,5:m], digits = 4)


  levels(data[,1]) <- c(levels(data[,1]),"1","GID","AID","EWEIGHT")
  levels(data[,2]) <- c(levels(data[,2]),"1","UNIQID")
  levels(data[,3]) <- c(levels(data[,3]),"1","NAME")
  data <- rbind(1,data)
  nom <- c("GID","UNIQID","NAME","GWEIGHT",names(data)[-c(1,2,3,4)])
  names(data) <- nom
  data[1,1] <- "EWEIGHT"
  data <- rbind(c("AID",NA,NA,NA,paste('ARRY',hc$order-1,'X',sep='')),data)
  
  # NA will be replaced by "" in the file
  # data[2:length(data[,1]),2] <- NA
  data[2,2:4] <- NA

  # Write file
  if(dec==',')
    {
      data<-apply(data,2,function(u){chartr(".",",",u)})
      data[data=="NA"]<-NA
    }
  write.table(data,file = file,sep = '\t',row.names = FALSE,col.names = TRUE,na="",quote=FALSE)

}
r2cluster <- function(data,labels=FALSE,colname="ACC",description=FALSE,file="cluster.txt",dec='.'){
#-------------------------------------------------------
#
#  Created       : 05/07/02
#  Last Modified : Time-stamp: <2003-07-22 16:53:00 lucas>
#
#  Description   : Write to Cluster file format (Cluster make
#                  Hierarchical cluster analysis)
#  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#  See Also      : r2xcluster
#
#  Xcluster      : Cluster is a program that performs
#                  hierarchical clustering, K-means and
#                  SOM. 
#                  Cluster is copyrighted. 
#                  To get or have information on Cluster:
#          
#                  http://rana.lbl.gov/EisenSoftware.htm
#
#  Licence       : GPL 
#
#
#-------------------------------------------------------
#
#
# Example:
# source('r2cluster.R')
# r2cluster(data)
#
#-------------------------------------------------------

n <- length(data[,1])
data <- as.data.frame(cbind(1,1:n,data))

# If the name column does not exist -> creation
# of this column, else: put column name on
# first place.
if(!description){
        if(!labels){
                data <- cbind(row.names(data),data)
        }
        else{
                data <- cbind(as.factor(data[,3]),data)
        }
}
else{
        data <- cbind(as.factor(data[,4]),data[,-4])
}
if(!labels){
        data <- cbind(row.names(data),data)
}
else{
        data <- cbind(as.factor(data[,4]),data[,-4])
}
levels(data[,1]) <- c(levels(data[,1]),"1",colname,"EWEIGHT")
levels(data[,2]) <- c(levels(data[,2]),"1","NAME","EWEIGHT")
data <- rbind(1,data)
nom <- c(colname,"NAME","GWEIGHT","GORDER",names(data)[-c(1,2,3,4)])
names(data) <- nom
data[1,1] <- "EWEIGHT"
data[1,2:4] <- NA

# NA will be replaced by "" in the file
#data[2:length(data[,1]),2] <- NA
#data[2,3] <- NA

# Write file
if(dec==',')
  {
    data<-apply(data,2,function(u){chartr(".",",",u)})
    data[data=="NA"]<-NA
  }

write.table(data,file,sep='\t',row.names = FALSE,col.names = TRUE,na="",quote=FALSE)
}
r2gtr <- function(hr,file="cluster.gtr",distance=hr$dist.method,dec=".",
                  digits=5)
{
#-------------------------------------------------------
#
#  Created       : 20/11/02	
#  Last Modified : Time-stamp: <2005-04-05 16:06:45 lucas>
#
#  Description   : Write hclust object to gtr atr
#                  files (Xcluster or Cluster output).
#                  Visualisation of cluster can be
#                  done with tools like treeview
#  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#  See Also      : plot.hclust  (library mva)
#
#  Licence       : GPL 
#-------------------------------------------------------



  height <- hr$height

  if(substr(distance,1,1)=="p")
    {
      height  <- 1 - height
    }
  else 
    {
      height <- height +1
      height  <- height[1] / height
#      height  <- (( 2 / height ) -1 ) / (( 2 / height[1] ) -1)
    }
  height  <- signif(height, digits = digits)
  
  
  n <- length(height)
  node <- 1:n
  node <- paste ('NODE',node,'X',sep='')

  merge1  <- hr$merge[,1]
  merge11 <- paste ('NODE',merge1,'X',sep='')
  merge12 <- paste ('GENE',-1-merge1,'X',sep='')
  merge1[hr$merge[,1]>0] <- merge11[hr$merge[,1]>0]
  merge1[hr$merge[,1]<0] <- merge12[hr$merge[,1]<0]
  
  merge2  <- hr$merge[,2]
  merge11 <- paste ('NODE',merge2,'X',sep='')
  merge12 <- paste ('GENE',-1-merge2,'X',sep='')
  merge2[hr$merge[,2]>0] <- merge11[hr$merge[,2]>0]
  merge2[hr$merge[,2]<0] <- merge12[hr$merge[,2]<0]


  data  <- data.frame(cbind(node,merge1,merge2))
  data  <- cbind(data,height)
 
  write.table(data,file=file,row.name=FALSE,col.names=FALSE,quote=FALSE,sep='\t',dec=dec)

}


#-----------------------------------
# Cosmetic modifications for r2atr
#-----------------------------------
r2atr <- function(hc,file="cluster.atr",distance=hc$dist.method,dec=".",
                  digits=5)
{



  height <- hc$height

  if(substr(distance,1,1)=="p")
    {
      height  <- 1 - height
    }
  else 
    {
      height <- height +1
      height  <- height[1] / height
    }
  height  <- signif(height, digits = digits)
  
  
  n <- length(height)
  node <- 1:n
  node <- paste ('NODE',node,'X',sep='')

  merge1  <- hc$merge[,1]
  merge11 <- paste ('NODE',merge1,'X',sep='')
  merge12 <- paste ('ARRY',-1-merge1,'X',sep='')
  merge1[hc$merge[,1]>0] <- merge11[hc$merge[,1]>0]
  merge1[hc$merge[,1]<0] <- merge12[hc$merge[,1]<0]
  
  merge2  <- hc$merge[,2]
  merge11 <- paste ('NODE',merge2,'X',sep='')
  merge12 <- paste ('ARRY',-1-merge2,'X',sep='')
  merge2[hc$merge[,2]>0] <- merge11[hc$merge[,2]>0]
  merge2[hc$merge[,2]<0] <- merge12[hc$merge[,2]<0]


  data  <- data.frame(cbind(node,merge1,merge2))
  data  <- cbind(data,height)
 
  if(dec==',')
    {
      data<-apply(data,2,function(u){chartr(".",",",u)})
      data[data=="NA"]<-NA
    }

  write.table(data,file=file,row.name=FALSE,col.names=FALSE,quote=FALSE,sep='\t')

}


r2xcluster <- function(data,labels=FALSE,description=FALSE,file="xcluster.txt"){
#-------------------------------------------------------
#
#  Created       : 10/12/01
#  Last Modified : Time-stamp: <2002-11-12 13:17:15 lucas>
#
#  Description   : Write to Xcluster file format (Xcluster make
#                  Hierarchical cluster analysis)
#  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#  See Also      : xcluster2r
#
#  Xcluster      : Xcluster is a C program that performs
#                  hierarchical clustering, K-means and
#                  SOM. 
#                  Xcluster is copyrighted. 
#                  To get or have information on Xcluster:
#          
#                  http://genome-www.stanford.edu/~sherlock/cluster.html     
#
#  Licence       : GPL (r2xcluster, not Xcluster)
#
#-------------------------------------------------------
#
#
# Example:
# source('r2xcluster.R')
# r2xcluster(data)
# system('Xcluster -f xcluster.txt')
# h <- xcluster2r('xcluster.gtr')
# library(mva)
# plot(h,hang=-1)
#
#-------------------------------------------------------


data <- as.data.frame(cbind(1,data))

# If the name column does not exist -> creation
# of this column else: put column name on
# first place.
if(!description){
        if(!labels){
                data <- cbind(row.names(data),data)
        }
        else{
                data <- cbind(as.factor(data[,2]),data)
        }
}
else{
	data <- cbind(as.factor(data[,3]),data[,-3])        
}
if(!labels){
        data <- cbind(row.names(data),data)
}
else{
        data <- cbind(as.factor(data[,3]),data[,-3])
}

levels(data[,1]) <- c(levels(data[,1]),"1","NAME","EWEIGHT")
levels(data[,2]) <- c(levels(data[,2]),"1","DESCRIPTION")
data <- rbind(1,data)
nom <- c("NAME","DESCRIPTION","GWEIGHT",names(data)[-c(1,2,3)])
data <- rbind(nom,data)
data[2,1] <- "EWEIGHT"

# NA will be replaced by "" in the file
#data[2:length(data[,1]),2] <- NA
data[2,2:3] <- NA

# Write file
write.table(data,file,sep='\t',row.names = FALSE,col.names = FALSE,na="",quote=FALSE)
}
read.eisen <- function(file,sep="\t",dec=".",format.check=TRUE) {

        f<-read.table(file=file,header=TRUE,sep=sep,dec=dec)

        rownames(f)<-f[,1]
        if (format.check & colnames(f)[1] %in% c("UNIQID","YORF","MCLID","CLID","ACC")) {
          stop(paste("This is not a proper Eisen-formatted file ('",file,"').",sep=""))
        }

        if ("NAME"==colnames(f)[2]) {
                colstart<-3
        } else {
                colstart<-2
        }

        if (""==rownames(f)[1]) {
                rowstart<-2
        } else {
                rowstart<-1
        }

        r<-f[rowstart:nrow(f),colstart:ncol(f)]

        if (2==rowstart) {
                attr(r,"second.row")<-f[1,colstart:ncol(f)]
        } else {
                attr(r,"second.row")<-NULL
        }

        if (3==colstart) {
                attr(r,"NAME")<-f[rowstart:nrow(f),2]
        } else {
                attr(r,"NAME")<-NULL
        }

        return(r)
}
xcluster <- function(data,distance="euclidean",clean=FALSE,tmp.in="tmp.txt",tmp.out="tmp.gtr"){
#-------------------------------------------------------
#
#  Created       : 10/12/01
#  Last Modified : Time-stamp: <2002-11-12 09:48:10 lucas>
#
#  Description   : Execute Xcluster (Xcluster make
#                  Hierarchical cluster analysis)
#  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#  See Also      : xcluster2r
#
#  Xcluster      : Xcluster is a C program that performs
#                  hierarchical clustering, K-means and
#                  SOM. 
#                  Xcluster is copyrighted. 
#                  To get or have information on Xcluster:
#          
#                  http://genome-www.stanford.edu/~sherlock/cluster.html     
#
#  Licence       : GPL (r2xcluster, not Xcluster)
#
#
#-------------------------------------------------------
#  Xcluster flags
#-------------------------------------------------------
#
# -g 0|1|2 ; 0 indicates no gene clustering, 1 indicates non-centered metric, 2 indicates centered metric when clustering genes.  2 is default.
# -e 0|1|2 ; 0 indicates no experiment clustering, see above for 1 and 2.  0 is the default.
# -p 0|1 ; whether to use pearson correlation (1), or Euclidean distance (0).  1 is the default.
# -s 0|1 ; whether to make a SOM (1). 0 is the default. 
# -x specify x dimension of SOM
# -y specify y dimension of SOM
# -r 0|1 ; whether to seed the random number generator with the time when making a SOM.  1 is the default.
# -k num ; how many k-means clusters to make.  num is an integer, greater than 1, and preferably less than a gazillion. 
# -l 0|1 ; whether to log transform the data.
# -u string ; a unique identifier by which to name the output files, instead of basing their names on the input file.  eg -u 888 will generate 888.cdt as an output file.
#-------------------------------------------------------
#
#
# Example:
# source('r2xcluster.R')
# system('Xcluster -f xcluster.txt')
# h <- xcluster2r('xcluster.gtr')
# library(mva)
# plot(h,hang=-1)
#
#-------------------------------------------------------

r2xcluster(data,file=tmp.in)

#-------------------------------------
#      CASE DISTANCE=EUCLIDEAN
#-------------------------------------
if(substr(distance,1,1)=="e")
   {
    script <- paste ("Xcluster -f",tmp.in," -e 0 -p 0 -s 0 -l 0")
    system(script)
    tree <- xcluster2r(file=tmp.out,distance="euclidean",labels=TRUE,fast= TRUE,clean=clean)
    }
#-------------------------------------
#      CASE DISTANCE=PEARSON
#-------------------------------------
if(substr(distance,1,1)=="p")
   {
    script <- paste ("Xcluster -f",tmp.in,"-g 2 -e 0 -p 1 -s 0 -l 0")
    system(script)
    tree <- xcluster2r(file=tmp.out,distance="pearson",labels=TRUE,fast= TRUE,clean=clean)
    }
#-------------------------------------
#   CASE DISTANCE=NONCENTEREDPEARSON
#-------------------------------------
if(substr(distance,1,1)=="n")
   {
    script <- paste ("Xcluster -f",tmp.in,"-g 1 -e 0 -p 1 -s 0 -l 0")
    system(script)
    tree <- xcluster2r(file=tmp.out,distance="pearson",labels=TRUE,fast= TRUE,clean=clean)
    }


script <-  paste ("rm ",substr(tmp.in,0,nchar(tmp.in)-3),"*",sep='')
system(script)
tree
}
xcluster2r <- function(file,distance="euclidean",labels=FALSE,fast=FALSE,clean=FALSE,dec="."){
#-------------------------------------------------------
#
#  Created       : 26/11/01
#  Last Modified : Time-stamp: <2002-11-22 11:48:29 lucas>
#
#  Description   : Read Xcluster output (Xcluster make
#                  Hierarchical cluster analysis) to
#                  analyse and plot the result. 
#  Author        : Antoine Lucas
#                  lucas@toulouse.inra.fr
#  See Also      : plot.hclust  (library mva)
#
#  Xcluster      : Xcluster is a C program that performs
#                  hierarchical clustering, K-means and
#                  SOM. 
#                  Xcluster is copyrighted. 
#                  To get or have information on Xcluster:
#          
#                  http://genome-www.stanford.edu/~sherlock/cluster.html     
#
#  Licence       : GPL (xcluster2r, not Xcluster)
#
#
#-------------------------------------------------------
#
#
# Example:
# source('xcluster2r.R')
# h <- xcluster2r('data.gtr')
# library(mva)
# plot(h,hang=-1)
#
#
#------------------------------
#  Determin if it is a .gtr or
#   .atr file
#------------------------------
ext <- substr(file,nchar(file)-2,nchar(file)-2)
if( (ext=='a') || (ext=='A') )
{
        premierelettre  <- 'A'
        atr             <- TRUE
}
else
{
        premierelettre  <- 'G'
        atr             <- FALSE
}

#------------------------------
#         reading file
#------------------------------



if(atr){
        premierelettre  <- 'A'
       }
else   {
        premierelettre  <- 'G'
       }

data    <- read.table(file,sep='\t',dec=dec)
data1   <- as.character(data[,2])
i1      <- (substr(data1,1,1)==premierelettre)*(-1)
#si i1 -1 => Gene, 
#Si i1  0 => Cluster
data1   <-  as.integer(substr(data1,5,nchar(data1)-1))
data1   <-  data1*i1+i1+data1*(1+i1)
data2   <- as.character(data[,3])
i2      <- (substr(data2,1,1)==premierelettre)*(-1)
data2   <-  as.integer(substr(data2,5,nchar(data2)-1))
data2   <-  data2*i2+i2+data2*(1+i2)
if(substr(distance,1,1)=="e")
   {
   Hheight <- 2 / (data[,4] +1 )   #Distance = Euclidean 
   }
   else{
   Hheight <- 1-data[,4]           #Distance = pearson (centered or not)
   }
rm(data)


#----------------------------------------------------
#         Giving ordered distances
#----------------------------------------------------
if(clean){
    Hheight <- cummax(Hheight)
    }



#----------------------------------------------------
#         Reorganizing data (Not essential, 
#         but gives the same look as R)
#         Fast=T skip this part
#----------------------------------------------------
if(!fast){
for(i in 1:length(data1)){
        if(abs(data1[i])>abs(data2[i])){
                tmp      <- data2[i]
                data2[i] <- data1[i]
                data1[i] <- tmp}
        if(data1[i]>0 && data2[i]<0)
        {
                tmp2     <- data2[i]
                data2[i] <- data1[i]
                data1[i] <- tmp2
        }
}
}
#----------------------------------------------------
#          Order the clusters 
#----------------------------------------------------

liste <- list("1"=c(data1[1],data2[1]))
for(i in 2:length(data1)){
        if(data1[i]<0 && data2[i]<0){
                liste[[as.character(i)]] <- c(data1[i],data2[i])
        }
        if(data1[i]>0 && data2[i]<0)
        {
                tmp <- as.character(data1[i])
                liste[[as.character(i)]] <- c(data2[i],liste[[tmp]])
                liste[[tmp]] <- c()
         }
        if(data1[i]<0 && data2[i]>0)
        {
                tmp <- as.character(data2[i])
                liste[[as.character(i)]] <- c(data1[i],liste[[tmp]])
                liste[[tmp]] <- c()
        }
        if(data1[i]>0 && data2[i]>0)
        {
                tmp1 <- as.character(data1[i])
                tmp2 <- as.character(data2[i])
                if(data1[i]<=data2[i])
                {
                        liste[[as.character(i)]] <- c(liste[[tmp1]],liste[[tmp2]])
                }
                else
                {
                        liste[[as.character(i)]] <- c(liste[[tmp2]],liste[[tmp1]])
                }                
                liste[[tmp1]] <- c()
                liste[[tmp2]] <- c()
        }
}


#--------------------------------
#       Giving the outputs
#-------------------------------- 

Hmerge  <- cbind(as.integer(data1),as.integer(data2))
Horder  <- -liste[[as.character(length(data2))]]
Hlabels <- as.character(1:(length(data2)+1))
Hmethod <- "average"
#Hdist.method <- "Pearson"
#Hcall  <- "Xcluster"

#--------------------------------
#  Getting labels on .cdt file
#--------------------------------
if(labels){
	if(atr)
	{
                filetxt <- paste(substr(file,0,nchar(file)-4),'.txt',sep='')
                data    <- read.table(filetxt,nrows=1,sep='\t',dec=dec)
                Hlabels <- as.character(t(data[4:length(data)]))
	}
	else
	{
                filecdt <- paste(substr(file,0,nchar(file)-4),'.cdt',sep='')
                data    <- read.table(filecdt,skip=1,sep='\t',dec=dec)
                data1   <- as.character(data[,1])
                data1   <- as.integer(substr(data1,5,nchar(data1)-1))
                data2   <- as.character(data[,2])
                Hlabels[data1+1] <- data2
        }
}

tree    <- list(merge=Hmerge,height=Hheight,order=Horder,labels=Hlabels,method=Hmethod)
class(tree) <- "hclust"
tree
}




.noGenerics <- TRUE
.conflicts.OK <- TRUE

.onLoad <- .First.lib <- function(lib, pkg)
{
  if("amap" %in% .packages(all=TRUE))
      require("amap")
}

