Clusters <- function(var, weights, nclusters=NULL, listindex=NULL) {
  #
  # This function computes clusters and their time series of occurrences with 
  # the K-mean clustering method on a matrix of input var (time, space). 
  # It requires NbClust package. 
  #
  # Args:
  #   var : A matrix (time, space); the 2nd spatial dimension can correspond either  
  #         to area-averages over a series of domains or the grid points for any
  #         grid (x,y), (x,y,z), (y,z), .. organised in an array for each time step
  #   weights : a vector of weights corresponding to the areas covering each domain/region
  #             or grid-cell of var; the length of weights vector should equal to the 2nd
  #             spatial dimension of var
  #   nclusters : K number of clusters to be computed, or K initial cluster centers 
  #               (default is NULL and then function  will determine the optimal number 
  #               of clusters and their centers, but it can be a CPU intense process) 
  #   listindex : list of validity indices (from NbClust package plus 'first') used to determine optimal 
  #               K if it is not specified via positive integer bigger than 1 or initial/seed cluster 
  #               centers in nclusters (NULL is deafult which leads to application of: 'kl', 'ch', 
  #               'duda', 'ratkowsky', 'ball', 'ptbiserial', 'gap', 'mcclain', 'tau', and 'sdindex') 
  #
  # Returns: (output of kemans function)
  #  $cluster : a vector (time series) of integers indicating the occurrence of a cluster, i.e., when
  #              certain data member in time is allocated to a specific cluster (e.g., 2 1 3 1 1 1 ..)
  #  $centers : a matrix of cluster centres or centroids (e.g. [1:K, 1:spatial degrees of freedom])
  #  $totss : the total sum of squares
  #  $withinss : vector of within-cluster sum of squares, one component per cluster
  #  $tot.withinss : total within-cluster sum of squares, i.e., ‘sum(withinss)’
  #  $betweenss : the between-cluster sum of squares, i.e. ‘totss-tot.withinss’
  #  $size : the number of points in each cluster
  #
  # History:
  #   1.0  #  2014-10  (N.S. Fuckar, neven.fuckar@ic3.cat)  #  Original code
  #   
##############################################################################

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 }

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

if ( is.null(nclusters)==FALSE ) { 
  kmeans.results <- kmeans(var1, centers=nclusters, iter.max=maxnoiterat, nstart=30) 
} else {
  if ( is.null(listindex)==TRUE ) { listindex <- c('kl', 'ch', 'duda', 'ratkowsky', 'ball', 'ptbiserial', 'gap', 'mcclain', 'tau', 'sdindex') }

  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)
        Karray[ii] <- nbclust.results$Best.nc[1]  
      } else {
        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])
        }

        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
        break
      }
    }
  }

  qw <- hist(Karray, breaks = seq(0, maxtryclstr), plot=F)$counts

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

invisible(kmeans.results)

}
