SeaIceModes <- function(var, exp, obs, sdates, seasoninf, seasonsup, nclusters=NULL, nleadtime=NULL, nmember=NULL, leadtimemin=1, leadtimemax=NULL, storefreq="monthly", sampleperiod=1, pldgr=0, listregs=NULL, weights=NULL, listindx=NULL) {
  #
  # This function computes sea ice variability modes based on the K-means clustering
  # method applied to sea ice variable such as area, extent, volume or thickness averages 
  # over the selected regions with sea ice in the Northern or Southern Hemisphere.
  #
  # Args:
  #   var : e.g. sia, sie, sit, .. (sea ice area, extent, thickness, ..)
  #   exp, obs, sdates, nleadtime, leadtimemin, leadtimemax, storefreq and sampleperiod
  #     are the same as in Load: only var, exp, obs and sdates are mandatory, and only
  #     1 experiment or only 1 observational dataset can be loaded
  #   nmember : selected ensemble member or mean between selected ensemble members, e.g. c(1,3)
  #             (default is NULL which produce ensemble mean of all available ensemble members)
  #   seasoninf : month of the year when to start computing any month or season or year: 1 to 12.
  #   seasonsup : month of the year when to stop computing any month or season or year: 1 to 22. 
  #               Selected season can go over 31 December: e.g. for DJF use seasoninf=12 and seasonsup=14.
  #               For using all months together: seasoinf=1, seasonsup=12 
  #   nclusters : K number of clusters to be computed, or K initial cluster centers (default is NULL
  #               and then Clusters.R  will determine the optimal number of clusters and their centers) 
  #   pldgr : pldgr<0 for using the full values, 0 for removing the long-term mean, and 0<pldgr for
  #           using residulas after removing polynomial fit of the pldgr order/degree (deafult is 0) 
  #   listregs : list of sea ice regions/zones/points used must be specified (it is expected that 
  #              Load configuration file has entries that support experiments and/or observations
  #              with variable names in the form of var_listregs[1], var_listregs[2], ..)
  #   weights : area weights of the selected regions in listsregs (default NULL means that var is
  #             being area weighted before loading, e.g. average sit, so this puts all values to 1)
  #   listindx : 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') 
  #
  # Return: (output of kmeans 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 ( is.null(listregs) ) { stop('list of sea ice regions/zones/points is not specified') }
  
  if ( is.null(weights) ) { weights <- rep(1, length(listregs)) }
  
  for ( i in 1:length(listregs) ) {
    tmp1 <- Load(paste(var, listregs[i], sep='_'), exp, obs, sdates, nleadtime=nleadtime, nmember=NULL, leadtimemin=leadtimemin, leadtimemax=leadtimemax, storefreq=storefreq, sampleperiod=sampleperiod)  
    
    if ( is.null(obs) ) {
      #    tmp2 <- Season(tmp1$mod, posdim=4, monini=as.integer(substr(sdates,5,6)), moninf=seasoninf, monsup=seasonsup)
      tmp2 <- tmp1$mod
    } else {
      #    tmp2 <- Season(tmp1$obs, posdim=4, monini=as.integer(substr(sdates,5,6)), moninf=seasoninf, monsup=seasonsup)
      tmp2 <- tmp1$obs
    }
    
    ti2 <- ti1 <- seq(seasoninf, seasonsup)
    while ( max(ti2) < dim(tmp2)[4] ) { ti1 <- ti1 + 12; ti2 <- append(ti2, ti1) }
    tif <- dim(tmp2)[4]
    ti2[ti2 > tif] <- ti2[ti2 > tif] - tif
    ti2 <- unique(ti2)
    
    tmp2a <- drop(tmp2)
    tii <- min(ti2)
    tmp2b <- matrix(0, nrow = dim(tmp2a)[1], ncol = 1)
    tmp2b[,1] <- tmp2a[, tii]
    for (i1 in (tii+1):tif) {
      if (i1 %in% ti2) { tmp2b <- cbind(tmp2b, tmp2a[,i1]) }
    }
    
    tmp2 <- InsertDim(var=InsertDim(var=tmp2b, posdim=2, lendim=1), posdim=1, lendim=1)
    
    if ( is.null(nmember) ) {
      tmp3 <- Mean1Dim(tmp2, posdim=2)
    } else {
      if ( length(nmember)== 1) {
        if ( nmember > length(tmp2[1,,1,1]) ) stop('selected ensemble member is not available')
        tmp3 <- InsertDim(var=InsertDim(var=tmp2[1,nmember,1,], posdim=1, lendim=1), posdim=1, lendim=1)
      } else {
        if ( length(nmember)==2 ) {
          if ( max(nmember) > length(tmp2[1,,1,1]) ) stop('selected ensemble member is not available')
          tmp3 <- Mean1Dim(tmp2, posdim=2, limits=nmember)
        } else {
          stop('incorrect selection of ensemble members')
        }
      }
    }
    
    if ( i==1 ) { tmp4 <- array(dim=c(length(tmp3[1,1,]), length(listregs))) }
    tmp4[,i] <- tmp3[1,1,]
  }
  
  ifelse(pldgr<0, output1 <- Clusters(var=tmp4, weights, nclusters, listindex=listindx), 
         ifelse(pldgr>0, output1 <- Clusters(Trend(var=tmp4, posTR=1, pldegree=pldgr)$detrended, weights, nclusters, listindex=listindx), 
                output1 <- Clusters(var=tmp4 - InsertDim(var=Mean1Dim(tmp4, posdim=1), posdim=1, lendim=dim(tmp4)[1]), weights, nclusters, listindex=listindx))) 
  
  invisible(output1)
  
}
