PlotEquiMap <- function(var, lon, lat, varu=NULL, varv=NULL,
                        subsample=1, scalearrow=0.5,
                        refwind=15, unitwind="m/s",
                        toptitle = '', sizetit = 1, units = '', 
                        brks = NULL, cols = NULL, square = TRUE, 
                        filled.continents = TRUE, contours = NULL, 
                        brks2 = NULL, dots = NULL, axelab = TRUE, labW = FALSE, 
                        intylat = 20, intxlon = 20, drawleg = TRUE, 
                        subsampleg = 1, numbfig = 1, colNA = 'white') {
  # Map two dimensional matrix with (longitude, latitude) dimensions in
  # cylindrical equidistant latitude and longitude projection.
  #
  # Args:
  #   var: Matrix to plot with (longitude, latitude) dimensions.
  #   lon: Array of longitudes.
  #   lat: Array of latitudes.
  #   varu: Matrix of the zonal component of wind/current
  #         with (longitude, latitude) dimensions.
  #         (not compatible with square=FALSE, optional)
  #   varv: Matrix of the meridional component of wind/current
  #         with (longitude, latitude) dimensions.
  #         (not compatible with square=FALSE, optional)
  #   subsample: if varu and varv set, subsample define the interval
  #              between two arrows in grid point. (Default: 2,
  #              an arrow is plotted every 2 grid point)
  #              (not compatible with square=FALSE, optional)
  #   scalearrow: scale for the arrow, default= 0.5
  #   refwind: Size of the arrow for the legend (Default: 15 m/s)
  #   unitwind:Unit of varu and varv (for the legend, default: m/s)
  #   toptitle: Title, optional.
  #   sizetit: Multiplicative factor to increase title size, optional.
  #   units: Units, optional.
  #   brks: Colour levels, optional.
  #   cols: List of colours, optional.
  #   square: Map with squares (TRUE) for each grid points or smoothing 
  #           (FALSE). Default: TRUE.
  #   filled.continents: Continents filled in grey (TRUE) or represented by a 
  #                      black line (FALSE). Default = TRUE.
  #                      Filling unavailable if crossing Greenwich.
  #                      Filling unavailable if square.
  #   contours: Matrix to add to the plot with contours. Default = NULL.
  #   brks2: Contour levels, optional.
  #   dots: Matrix with TRUE / FALSE flags to add black dots option only 
  #         available if square = TRUE.
  #   axelab: TRUE/FALSE, label the axis. Default = TRUE.
  #   labW: 
  #   initylat: Interval between latitude ticks on y-axis. Default: 20deg.
  #   initxlon: Interval between longitude ticks on x-axis. Default: 20deg.
  #   drawleg: Draw colorbar. Can be FALSE only if square = FALSE.
  #            Must be FALSE if numbfig > 1. Default: T.
  #   subsampleg: Supsampling factor of the interval between ticks on colorbar.
  #               Default: 1 = every colour level.
  #   numbfig: Number of figures in the final multipanel.
  #   colNA: Colour for missing values
  #
  # Returns:
  #   This function returns nothing.
  #
  # History:
  #   1.0  #  2011-11  (V. Guemas, vguemas@ic3.cat)  #  Original code   
  #   1.0  #  2014-04  (C. Prodhomme, chloe.prodhomme@ic3.cat)  #  add wind option   
  #
  #  Some required packages 
  # ~~~~~~~~~~~~~~~~~~~~~~~~
  #
  #library(GEOmap)
  #library(geomapdata)
  #library(maps)
  data(coastmap, envir = environment())
  #
  #  Input arguments 
  # ~~~~~~~~~~~~~~~~~
  #
  dims <- dim(var)
   # Tests for arrow plotting
  if (is.null(varu)==FALSE){
    if (is.null(varv)){
      stop("you set a u component of wind/current but not the correponding v component")
    }else if((isTRUE(all.equal(dim(var),dim(varv)))&
         isTRUE((all.equal(dim(var),dim(varv)))))==FALSE){
           stop("var, varu and varv should have the same Dimension")
    }
  }
 
  if (length(dims) > 2) {
    stop("Only 2 dimensions expected for var : (lon,lat) ")
  }
  if (dims[1] != length(lon) | dims[2] != length(lat)) {
    if (dims[1] == length(lat) & dims[2] == length(lon)) {
      var <- t(var)
      if(is.null(varu)==FALSE){varu <- t(varu)}
      if(is.null(varv)==FALSE){varv <- t(varv)}
     dims <- dim(var)
    } else {
      stop("Inconsistent var dimensions / longitudes + latitudes")
    }
  }
  latb <- sort(lat, index.return = TRUE)
  dlon <- lon[2:dims[1]] - lon[1:(dims[1] - 1)]
  wher <- which(dlon > (mean(dlon) + 1))
  if (length(wher) > 0) {
    lon[(wher + 1):dims[1]] <- lon[(wher + 1):dims[1]] - 360
  }
  lonb <- sort(lon, index.return = TRUE)
  latmin <- floor(min(lat) / 10) * 10
  latmax <- ceiling(max(lat) / 10) * 10
  lonmin <- floor(min(lon) / 10) * 10
  lonmax <- ceiling(max(lon) / 10) * 10

  colorbar <- colorRampPalette(c("dodgerblue4", "dodgerblue1",
              "forestgreen", "yellowgreen", "white", "white",
              "yellow", "orange", "red", "saddlebrown"))
  if (is.null(brks) == TRUE) {
    ll <- signif(min(var, na.rm = TRUE), 4)
    ul <- signif(max(var, na.rm = TRUE), 4)
    if (is.null(cols) == TRUE) {
      cols <- colorbar(10)
    }
    nlev <- length(cols)
    brks <- signif(seq(ll, ul, (ul - ll) / nlev), 4)
  } else {
    if (is.null(cols) == TRUE) {
      nlev <- length(brks) - 1
      cols <- colorbar(nlev)
    } else {
      if (length(cols) != (length(brks) - 1)) {
        stop("Inconsistent colour levels / list of colours")
      }
    }
  }

  if (is.null(brks2) == TRUE ) {
    if (is.null(contours)) { 
      if (square == FALSE) {
        brks2 <- brks
        contours <- var 
      }
    } else {
      ll <- signif(min(contours, na.rm = TRUE), 2)
      ul <- signif(max(contours, na.rm = TRUE), 2)
      brks2 <- signif(seq(ll, ul, (ul - ll) / (length(brks) - 1)), 2)
    }
  }
  #
  #  Plotting the map
  # ~~~~~~~~~~~~~~~~~~
  #
  if (axelab == TRUE) { 
    ypos <- seq(latmin, latmax, intylat)
    xpos <- seq(lonmin, lonmax, intxlon)
    letters <- array('', length(ypos))
    letters[ypos < 0] <- 'S'
    letters[ypos > 0] <- 'N'
    ylabs <- paste(as.character(abs(ypos)), letters, sep = '')
    letters <- array('', length(xpos))
    if (labW) {
      nlon <- length(xpos)
      xpos2 <- xpos  
      xpos2[xpos2 > 180] <- 360 - xpos2[xpos2 > 180]
    }
    letters[xpos < 0] <- 'W'
    letters[xpos > 0] <- 'E'
    if (labW) {
      letters[xpos == 0] <- ' '
      letters[xpos == 180] <- ' '
      letters[xpos > 180] <- 'W'  
      xlabs <- paste(as.character(abs(xpos2)), letters, sep = '')
    } 
    else{
      xlabs <- paste(as.character(abs(xpos)), letters, sep = '')
    }
    xmargin <- 1.2 - (numbfig ^ 0.2) * 0.05
    ymargin <- 3 - (numbfig ^ 0.2)
    spaceticklab <- 1.3 - (numbfig ^ 0.2) * 0.8
    topmargin <- 0.4
    ymargin2 <- 1.5 - (numbfig ^ 0.2) * 0.9
  } else {
    xmargin <- 0.2 
    ymargin <- 0.2 + switch(as.character(square), 'FALSE' = 1.8, 0) 
    topmargin <- 0.2
    spaceticklab <- 1
    ymargin2 <- 0.2
  }
  if (toptitle != '') {
    topmargin <- 2.5 - (numbfig ^ 0.2) * 0.6
  }
  if (min(lon) < 0) {
    continents <- 'world'
  } else {
    continents <- 'world2'
  }
  # Increase the bottom margin
  # to plat the legend of the arrow plot
  if ((is.null(varu)==FALSE)&&(drawleg==FALSE)){
    xmargin=xmargin + xmargin*2
    if(axelab==FALSE){
      xmargin=xmargin + 3
    }
  }
  if (square) {
    if (drawleg) {
      layout(matrix(1:2, ncol = 1, nrow = 2), heights = c(5, 1))
    }
    par(mar = c(xmargin, ymargin, topmargin, ymargin2), cex = 1.4, 
        mgp = c(3, spaceticklab, 0), las = 0)
    if (colNA != 'white') {
      blanks <- array(0, dim = c(length(lonb$x), length(latb$x)))
      image(lonb$x, latb$x, blanks, col = c(colNA), breaks = c(-1, 1), 
            main = toptitle, cex.main = (1.5 / numbfig ^ (0.2)) * sizetit, 
            axes = FALSE, xlab = "", ylab = "")
      flagadd <- T
    } else {  
      flagadd <- F
    }
    image(lonb$x, latb$x, var[lonb$ix, latb$ix], col = cols, breaks = brks, 
          main = toptitle, axes = FALSE, xlab = "", ylab = "", 
          cex.main = (1.5 / numbfig ^ (0.2)) * sizetit, add = flagadd)
    if (axelab == TRUE) {
      axis(2, at = ypos, labels = ylabs, cex.axis = 1 / (numbfig ^ 0.3), 
           tck = -0.03)
      axis(1, at = xpos, labels = xlabs, cex.axis = 1 / (numbfig ^ 0.3),
           tck = -0.03)
    }
    if (is.null(contours) == FALSE) {
      contour(lonb$x, latb$x, contours[lonb$ix, latb$ix], levels = brks2,
              method = "edge", add = TRUE, labcex = 1 / numbfig, 
              lwd = 0.5 / (numbfig ^ 0.5))
    }
    map(continents, interior = FALSE, add = TRUE, lwd = 1)
    box()
  } else {
    par(mar = c(xmargin + 5, ymargin + 1.5, topmargin, ymargin2), 
        cex.main = (1.6 * numbfig ^ (0.3)) * sizetit, cex.axis = 1.4, 
        cex.lab = 1.6, mgp = c(3, spaceticklab + 0.5, 0), las = 0)
    if (axelab == TRUE) {
      filled.contour(lonb$x, latb$x, var[lonb$ix, latb$ix], xlab = "", 
                     levels = brks, col = cols, ylab = "", main = toptitle,
                     key.axes = axis(4, brks[seq(1, length(brks), subsampleg)],
                     cex.axis = 1 / (numbfig ^ 0.3)), 
                     plot.axes = {axis(2, at = ypos, labels = ylabs, 
                                  cex.axis = 1 / (numbfig ^ 0.3), tck = -0.03)
                                  axis(1, at = xpos, labels = xlabs,
                                  cex.axis = 1 / (numbfig ^ 0.3), tck = -0.03)
                                  contour(lonb$x, latb$x, contours[lonb$ix,
                                          latb$ix], levels = brks2, 
                                          method = "edge", add = TRUE,
                                          labcex = 1, lwd = 2)
                                  map(continents, interior = FALSE, 
                                      xlim = c(lonmin, lonmax),
                                      ylim = c(latmin, latmax), add = TRUE)},
                     key.title = title(main = units, 
                                 cex.main = (1.2 * numbfig ^ (0.3)) * sizetit))
    } else {
      filled.contour(lonb$x, latb$x, var[lonb$ix, latb$ix], xlab = "",
                     levels = brks, col = cols, ylab = "", main = toptitle,
                     key.axes = axis(4, brks[seq(1, length(brks), subsampleg)],
                     cex.axis = 1 / (numbfig ^ 0.3)), 
                     plot.axes = {contour(lonb$x, latb$x, contours[lonb$ix, 
                                          latb$ix], levels = brks2, 
                                          method = "edge", add = TRUE,
                                          labcex = 1, lwd = 2)
                                  map(continents, interior = FALSE, 
                                      xlim = c(lonmin, lonmax), 
                                      ylim = c(latmin, latmax), add = TRUE)},
                     key.title = title(main = units, 
                                 cex.main = (1.2 * numbfig ^ (0.3)) * sizetit))
    }
  } 
  #
  #  Adding black dots  
  # ~~~~~~~~~~~~~~~~~~~
  #
  if (is.null(dots) == FALSE) {
    for (ix in 1:length(lon)) {
      for (jy in 1:length(lat)) {
        if (is.na(var[ix, jy]) == FALSE) {
          if (dots[ix, jy] == TRUE) {
            text(x = lon[ix], y = lat[jy], ".", 
                 cex= 12 / (sqrt(sqrt(length(var))) * numbfig ^ 0.5))
          }
        }
      }
    }
  }
  #
  #  Filling continents
  # ~~~~~~~~~~~~~~~~~~~~
  # 
  if (square == TRUE & filled.continents == TRUE) {
    if (min(lon) >= 0) {
      ylat <- latmin:latmax
      xlon <- lonmin:lonmax
      proj <- setPROJ(1, LON0 = mean(xlon), LAT0 = mean(ylat), LATS = ylat,
                      LONS = xlon)
      coastmap$STROKES$col[which(coastmap$STROKES$col == "blue")] <- "white"
      par(new = TRUE)
      plotGEOmap(coastmap, PROJ = proj, border = 'black', add = TRUE)
      box()
    } else {
      map(continents, interior = FALSE, wrap = TRUE, lwd = 0.7, col = gray(0.5),
          fill = TRUE, add = TRUE, border = gray(0.5))
    }
  }
  #
  #  PlotWind
  # ~~~~~~~~~~
  #
  if (is.null(varu)==FALSE){
    # Create a two dimention array of longitude and latitude
    lontab <- InsertDim(lonb$x, 2, length( latb$x))
    lattab <- InsertDim(latb$x, 1, length( lonb$x))
    varplotu <- varu[lonb$ix, latb$ix]
    print("here2")
    varplotv <- varv[lonb$ix, latb$ix]
    print("here2")

    # Select a subsample af the points to an arrow
    #for each "subsample" grid point
    sublon <- seq(1,length(lon), subsample)
    sublat <- seq(1,length(lat), subsample)

    uaux <- lontab[sublon,sublat]+varplotu[sublon,sublat]*scalearrow
    vaux <- lattab[sublon,sublat]+varplotv[sublon,sublat]*scalearrow
    # Plot Wind
    arrows(lontab[sublon,sublat], lattab[sublon,sublat],
           uaux, vaux,
           angle=15/(numbfig ^ (0.2)),
           length=0.15*scalearrow/(numbfig ^ (0.2)))

    # Plotting an arrow at the bottom of the plot for the legend
    posarlon=lonb$x[1]+(lonmax-lonmin)*0.1
    posarlat=latmin-(latmax-latmin)*0.04

    print(refwind)
    arrows(posarlon,posarlat,
          posarlon+scalearrow*refwind,posarlat,
          length=0.15*scalearrow/(numbfig ^ (0.2)), angle=15/(numbfig ^ (0.2)),
          xpd = TRUE)
    #save the parameter value
    xpdsave=par()$xpd
    #desactivate xpd to be able to plot in margen
    par(xpd=NA)
    #plot text
    text(x = posarlon+scalearrow*7.5, y = posarlat-(latmax-latmin)*0.04,
         labels = paste(as.character(refwind),unitwind,sep=""),
         cex = (1 * sizetit / numbfig ^ (0.2)) )
    #come back to the previous xpd value
    par(xpd=xpdsave)
    
  }
  #
  #  Colorbar
  # ~~~~~~~~~~
  #
  if (square & drawleg) {
    par(mar = c(1.5, ymargin + 1.5, 2.5, ymargin2), mgp = c(1.5, 0.3, 0), 
        las = 1, cex = 1.2)
    image(1:length(cols), 1, t(t(1:length(cols))), axes = FALSE, col = cols, 
          xlab = '', ylab = '', main = units, cex.main = 1.1)
    box()
    axis(1, at = seq(0.5, length(brks) - 0.5, subsampleg), 
         labels = brks[seq(1, length(brks), subsampleg)])
    #title(xlab = units)
  }

}
