  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  ggLinegraph.r                                                                          #
  #           Last Updated Funclist  :  19 Feb 2015,  1:05 PM (Thursday)                                                       #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   ggLinegraph        ( DT, x=names(DT)[[1]], y=names(DT)[[2]], color=NULL, alpha=1, size=1, linetype=NULL                  #
  #                        , thickness=size, line_alpha=alpha, dotsize=dotsize.scale * thickness, dotsize.scale=2.25           #
  #                        , dot_alpha=alpha, dot_color=color, smooth=FALSE, smooth_se=FALSE                                   #
  #                        , smooth_alpha=0.25 * alpha, smooth_method="loess", ... )                                           #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

if (FALSE)
  ggShowLineTypes()



ggLinegraph <- function(DT
                      , x=setdiff(getDateColNames(DT), color) [[1]]
                      , y=setdiff(nwhich(canBeNumeric(DT)), color) [[1]]
                      , color=NULL
                      , linealpha=alpha

                      ## These parameters are unique to this graph ##
                      ## ----------------------------------------- ##
                      , size=1
                      , linetype=NULL
                      , thickness=size
                      , line_alpha = alpha
                      , dotsize=dotsize.scale * thickness
                      , dotsize.scale = 2.25
                      , dot_alpha = alpha
                      , dot_color = color
                      , smooth=FALSE
                      , smooth_se = FALSE
                      , smooth_alpha = .25 * alpha
                      , smooth_method = "loess"
                      , alpha = 1

                      , ...
) {


## dotsize :: set to 0 or NULL to turn off dots
## label :: set to a column name (which itslef has the text labels to use)
## labelcolor :: set to NULL to use same as default. Set to a color value to override
## smooth_method :: replaces geom_line with geom_smooth
## h / vline_value  :: a value where to insert a verticle line

  lib(ggplot, quiet=TRUE)

  ## GENERIC ERROR TEST
  gg_confirm_aes_values(DT, c("x", "y", "linetype", "color"))

  if (!identical(smooth, "+") && !any(c(TRUE, FALSE) %in% smooth))
      stop ("'smooth' should be TRUE or FALSE")
  if (!is.numeric(alpha) || (alpha < 0 || alpha > 1))
      stop ("'alpha' must be a decimal between [0, 1]")
    

  ## Base function 
  P <- ggplot(DT) + aes_string(x = x, y=y)


  ## Possibly add smoothing on top of
  if (identical(smooth, "+")) {
      P <- P + geom_smooth(se=smooth_se, alpha=smooth_alpha, method=smooth_method)
  }

  ## Add line
  ## ------------------------------------------ ##
  ## If smoothing *insteaad* of geom_line, this function will replace geom_line with geom_smooth
  geom_line_func <- if (!isTRUE(smooth)) geom_line else function(..., alpha) geom_smooth(..., se=smooth_se, alpha=smooth_alpha, method=smooth_method)

  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ## TODO 2015-08-27 - this needs to better allow for different combinations of column name / value
  ##       Alternatively, perhaps we could have typeValue, typeCol for each type of aesthetic
  ##       something like 
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ## IMPLEMENT THIS.......
  type      = NULL
  typeValue = NULL
  typeCol   = NULL
  ## Sanity check
  if (sum(!is.null(type), !is.null(typeValue), !is.null(typeCol)) > 1)
    stop("Only at most one of type, typeValue, typeCol can be used")
  if (!is.null(type)) {
    ## Find if it is a column name or a value
    if (is.character(type) && type %in% names(DT))
      typeValue <- type
    else
      typeCol  <- type
  }
  ## Then to execute, maybe this will work    geom(aes_string(type=typeValue), aes(type=typeCol))
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # alpha
  # thickness
  # linetype
  add_as_es <- function(z) (is.character(z) && z %in% names(DT))
  params <- list(alpha=linealpha, linetype=linetype, size=thickness) %>% removeNullsAndBlanksFromList
  if (length(params)) {
    wh.as_aes <- sapply(params, add_as_es)
    aes_part <- params[wh.as_aes] %>% {sprintf("%s = \"%s\"", names(.), .)} %>% pasteC(C=", ") %>% {if (nchar(.)) sprintf("aes_string(%s)", .)}
    non_aes_part <- params[!wh.as_aes] %>% {sprintf("%s = %s", names(.), .)} %>% pasteC(C=", ") %>% {if (nchar(.)) sprintf("%s", .)}
    P <- pasteC(c(aes_part, non_aes_part), C=", ") %>% sprintf("geom_line_func(%s)", .) %>%
      {P + eval(parse(text=.))}
  }

 if (is.character(thickness) && thickness %in% names(DT))
 {
     if (missing(dotsize))
       stop("When size/thickness is a column of DT, dotsize must be given explicitly")
     if (!is.null(linetype))
       P <- P + geom_line_func(aes_string(linetype=linetype, size=thickness), alpha=line_alpha)
     else 
       P <- P + geom_line_func(aes_string(size=thickness), alpha=line_alpha)
 } else {
     if (!is.null(linetype))
       P <- P + geom_line_func(aes_string(linetype = linetype), size=thickness, alpha=line_alpha)
     else 
       P <- P + geom_line_func(size=thickness, alpha=line_alpha)
 }
 if (!is.null(dotsize) && dotsize > 0) {
   if (!is.null(dot_color) && !identical(color, dot_color))
     P <- P + geom_point(size=dotsize, alpha=dot_alpha, aes_string(color=dot_color))
   else 
     P <- P + geom_point(size=dotsize, alpha=dot_alpha)
 }

  if (FALSE) {
    browser(text = "before calling gg_GenericProcessing")
    ARGS <- collectArgs()
    names(ARGS)
    gg_GenericProcessing(P = P, DT = DT, x = x, y = y, size = size, xlab = list(...)$xlab, title=title, alpha = alpha, color=color)
    gg_GenericProcessing(P = P, DT = DT, x = x, y = y, size = size, xlab = list(...)$xlab, title=list(...)$title, alpha = alpha, color=color)
    do.call(gg_GenericProcessing, ARGS)
  }
  do.call(gg_GenericProcessing, collectArgs(), quote=TRUE)
}


