Cluster <- function(var, weights, nclusters=NULL, listindex='first') {
  #
  # This function computes clusters by applying the k-mean method on the 
  # 2-dimensional input var (time, space). The 2nd dimension can correspond
  # either to area-averages over a series of domains or to the grid-points 
  # from any grid (x,y), (x,z) ... re-organised in arrays for each time step
  #
  # Args:
  #  var : 2-dimensional matrice (time, space); the spatial dimension can 
  #        correspond either to area-averages over a series of domains or 
  #        to the grid-points from any grid (x,y), (x,z) ...
  #        re-organised in arrays for each time step
  #  weights : 1-dimensional array of weights corresponding to the areas 
  #            covered each domain or grid-cell of var; the length of 
  #            the weights array should equal the 2nd dimension of var
  #  nclusters : number of clusters to be computed, default is NULL which
  #              leads function to compute the optimal number of clusters
  #
  # Returns: all outputs of kemans, e.g. 
  #  kmeans.results$cluster : 1-dimension matrice (time) containing 1 or 2 or ... 
  #                            when a given cluster occurs
  #
  # History:
  #   
##############################################################################

if ( dim(var)[2]!=length(weights) ) stop("spatial dimension of var is not equal to length of weights")

var1 <- array(1, dim=dim(var))
for ( i in 1:dim(var)[1] ) { var1[i,] <- var[i,]/weights }

# three lines below are only for testing phase
#print(dim(var1))
#save(var1,file='weigthed_input_to_Cluster.sav')
#print(var1)

maxtryclstr <- 20
maxnoiterat <- 300
noatnbclust <- 10

if ( listindex=='default' ) { listindex <- c('kl', 'ch', 'duda', 'ratkowsky', 'ball', 'ptbiserial', 'gap', 'mcclain', 'tau', 'sdindex') }
# WARNING: tau is unfeasible (way too slow) when we have to deal with daily data - We need to rethink the default list !!!
if ( is.null(nclusters)==FALSE ) { kmeans.results <- kmeans(var1, centers=nclusters, iter.max=maxnoiterat, nstart=30) }
   else {
#  listindex <- c( 'kl', 'ch', 'marriot', 'tracew', 'duda', 'pseudots2', 'beal', 'ratkowsky', 'ball', 'ptbiserial', 'gap', 'mcclain', 'tau', 'sdindex' )
#  above in default is a safer list of index methods (some of methods in just above list can produce num sigularity), but I think that I could utilize also hurbert and dindex !!
   Karray    <- rep(0, length(listindex)*noatnbclust)

   ii <- 0
   for ( index1 in listindex ) {
       for ( i in 1:noatnbclust ) {
           ii <- ii + 1

           if ( index1!='first' ) {

           nbclust.results <- NbClust(var1, distance='euclidean', min.nc=2, max.nc=20, method='kmeans', index=index1)
           print(index1)
           print(nbclust.results$Best.nc[1])
           Karray[ii] <- nbclust.results$Best.nc[1]  

           } else {
#          print('start first')
           Karray <- c(Karray, rep(0, noatnbclust))

           tmp1a <- array(dim = maxtryclstr)
           tmp1b <- array(dim = maxtryclstr)
           tmp2a <- array(dim = maxtryclstr)
           tmp2b <- array(dim = maxtryclstr)

           for ( i in 1:maxtryclstr ) {
               tmp1a[i] <- kmeans(var1, centers = i, iter.max = maxnoiterat, nstart = 30)$tot.withinss
               tmp1b[i] <- kmeans(var1, centers = i, iter.max = maxnoiterat, nstart = 30)$betweenss
           }
           for ( i in 2:(maxtryclstr-1) ) {
               tmp2a[i] <- (tmp1a[i] - tmp1a[i+1])/(tmp1a[i-1] - tmp1a[i])
               tmp2b[i] <- (tmp1b[i] - tmp1b[i+1])/(tmp1b[i-1] - tmp1b[i])
           }

# If one does not want to see details of the selection process for the optiomal number of clusters otherwise comment out 10 lines below 
#          postscript('within-_and_between-cluster_analysis.eps')
#          mm <- rbind(c(1,2),c(3,4),c(5,5))
#          layout(mm)
#          plot(1:maxtryclstr,tmp1a,type="b",xlab="Number of clusters",ylab="Total within-cluster sum of squares")
#          plot(1:maxtryclstr,tmp2a,type="b",xlab="Number of clusters",ylab="Shifted derivative of .. (on left)")
#          plot(1:maxtryclstr,tmp1b,type="b",xlab="Number of clusters",ylab="Total between-cluster sum of squares")
#          plot(1:maxtryclstr,tmp2b,type="b",xlab="Number of clusters",ylab="Shifted derivative of .. (on left)")
#          plot(1:maxtryclstr,tmp1b/tmp1a,type="b",xlab="Number of clusters",ylab="...  between-cluster sum of squares")
#          dev.off()
#          cat("Press ENTER/RETURN to continue")
#          line <- readline()
#
           ia <- 2
           while ( tmp2a[ia] > tmp2a[ia+1] ) { ia <- ia + 1 }
           Karray[ii] <- ia      
           for (j in 1:(noatnbclust-1)) { Karray[ii+j] <- ia }
           ii <- ii + noatnbclust

           ib <- 2
           while ( tmp2b[ib] > tmp2b[ib+1] ) { ib <- ib + 1 }
           Karray[ii] <- ib      
           for (j in 1:(noatnbclust-1)) { Karray[ii+j] <- ib }
           ii <- ii + noatnbclust - 1
#          print('end first')
           break
           }
       }
   }

# nine lines below are only for testing phase
#        print(' ')
#        print(nbclust.results$All.index)
#        print(' ')
#        print(nbclust.results$Best.nc[1])
#        print(' ')
#        print(nbclust.results$Best.partition)
#        print(' ')        
#        cat("Press ENTER/RETURN to continue")
#        line <- readline()
        
#  qw <- rep(0, maxtryclstr)
#  for ( i in 2:maxtryclstr ) { qw[i] <- length(which(Karray==i)) }
   qw <- hist(Karray, breaks = seq(0, maxtryclstr), plot=F)$counts

# four lines below are only for testing phase
   print(' qw distribution')
   print(qw)
   print(' ')
   print(which(qw==max(qw)))

   kmeans.results <- kmeans(var1, centers=which(qw==max(qw)), iter.max=maxnoiterat, nstart=30) 
   }

invisible(kmeans.results)

}
