# Copyright 2010-2015 Meik Michalke <meik.michalke@hhu.de>
#
# This file is part of the R package rkwarddev.
#
# rkwarddev is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# rkwarddev is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with rkwarddev.  If not, see <http://www.gnu.org/licenses/>.


#' Paste simple JavaScript plot code
#' 
#' This function is similar to \code{rk.paste.JS}, but adds some code parts to its output which
#' are commonly used to generate plots with RKWard.
#' 
#' The contents of the \code{...} argument are evaluated by \code{rk.paste.JS} and encapsulated
#' between \code{if(!is_preview)\{rk.graph.on()\} try(\{} and \code{\}) if(!is_preview)\{rk.graph.off()\}}. If generic
#' plot options are supplied, their \code{"code.preprocess"} and \code{"code.calculate"} modifiers are
#' also automatically taken care of, so you only need to include \code{"code.printout"} inside of
#' \code{...}.
#'
#' @param ... The actual plot code, passed through to \code{rk.paste.JS}.
#' @param plotOpts An object generated by \code{rk.XML.embed} or \code{rk.plotOptions}, i.e. embedded plot options.
#' @param printoutObj An \code{rk.JS.var} object fetching the \code{"code.printout"} modifier of \code{plotOpts}
#'    (see examples below!). If \code{NULL} and \code{plotOpts} is of class \code{rk.plot.opts} (as returned by \code{rk.plotOptions}),
#'    will be fetched from \code{plotOpts} automatically.
#' @param level Integer, which indentation level to use, minimum is 1.
#' @param indent.by A character string defining the indentation string to use.
#' @param empty.e For \code{rk.JS.ite} objects only: Logical, if \code{TRUE} will force to add empty \code{else \{\}} brackets when
#'    there is no \code{else} statement defined, which is considered to enhance code readability by some.
#' @param useIsPreview Logical, defines which variable name shoud be used to toggle previews. If \code{TRUE} will use the newer 
#'    and recommended approach (\code{js(if("!is_preview"){...})}, otherwise the now deprecated \code{js(if("full"){...})}
#'    approach, which is only still included for backward compatibility.
#' @return A character string.
#' @export
#' @seealso
#'    \code{\link[rkwarddev:rk.paste.JS]{rk.paste.JS}}
#' @examples
#' tmp.var.selectVars <- rk.XML.varselector(label="Select data")
#' tmp.var.x <- rk.XML.varslot(label="My data", source=tmp.var.selectVars, required=TRUE)
#' # let this be the embedded generic plot options in yout plot dialog
#' tmp.plot.options <- rk.plotOptions()
#' 
#' # you can now generate the plot code using generic plot options
#' js.prnt <- rk.paste.JS.graph(
#'  echo("\t\tplot("),
#'  echo("\n\t\t\tx=", tmp.var.x),
#'  echo(tmp.plot.options),
#'  echo(")"),
#'  plotOpts=tmp.plot.options)
#'
#' cat(js.prnt)
rk.paste.JS.graph <- function(..., plotOpts=NULL, printoutObj=NULL, level=2, indent.by=rk.get.indent(), empty.e=rk.get.empty.e(), useIsPreview=TRUE){

  plotOptsIndent <- paste(rep(rk.get.indent(escape=TRUE), level), collapse="")
  if(isTRUE(useIsPreview)){
    previewVar <- "!is_preview"
  } else {
    previewVar <- "full"
  }
  
  # define variables
  js.prnt <- rk.paste.JS(
    if(!is.null(plotOpts)){
      if(inherits(plotOpts, "rk.plot.opts")){
        js.po.preprocess <- slot(plotOpts, "preprocess")
        js.po.calculate <- slot(plotOpts, "calculate")
        if(is.null(printoutObj)){
          printoutObj <- slot(plotOpts, "printout")
        } else {}
      } else {
        js.po.preprocess <- rk.JS.vars(plotOpts, modifiers="code.preprocess", check.modifiers=FALSE)
        js.po.calculate <- rk.JS.vars(plotOpts, modifiers="code.calculate", check.modifiers=FALSE)
      }
      trim(rk.paste.JS(
        rk.comment("in case there are generic plot options defined:"),
        js.po.preprocess,
        if(!is.null(printoutObj)){
          printoutObj
        } else {
          warning("rk.paste.JS.graph: you're using plot options, but 'printoutObj' is empty, is that intended?")
        },
        js.po.calculate,
        level=level
      ))
    } else {},
    level=level, indent.by=indent.by, empty.e=empty.e
  )

  # graph.on() & begin try()
  js.prnt <- paste(js.prnt, rk.paste.JS(
    js(
      if(previewVar){
        echo("rk.graph.on()\n")
      } else {}
    ),
#    ite("full", echo("rk.graph.on()\n")),
    echo(paste0(indent(level=level, by=indent.by), "try({\n")),
    level=level, indent.by=indent.by, empty.e=empty.e
  ), sep="\n\n")

  # plot options: preprocess
  js.prnt <- paste(js.prnt, rk.paste.JS(
    if(!is.null(plotOpts)){
      rk.paste.JS(
        rk.comment("insert any option-setting code that should be run before the actual plotting commands:"),
        id(paste0(
          indent(level=level, by=indent.by),
          "printIndentedUnlessEmpty(\""), plotOptsIndent, "\", ", js.po.preprocess, ", \"\\n\", \"\");"
        ),
        level=level
      )
    } else {},
    level=level, indent.by=indent.by, empty.e=empty.e
  ), sep="\n\n")

  # here comes the plot
  js.prnt <- paste(js.prnt, rk.paste.JS(
    rk.comment("the actual plot:"),
    rk.paste.JS(..., level=level, indent.by=indent.by, empty.e=empty.e),
    level=level, indent.by=indent.by, empty.e=empty.e
  ), sep="\n\n")

  # plot options: postprocess
  js.prnt <- paste(js.prnt, rk.paste.JS(
    if(!is.null(plotOpts)){
      rk.paste.JS(
        rk.comment("insert any option-setting code that should be run after the actual plot:"),
        id(paste0(
          indent(level=level, by=indent.by), 
          "printIndentedUnlessEmpty(\""), plotOptsIndent, "\", ", js.po.calculate, ", \"\\n\", \"\");"
        ),
        level=level
      )
    } else {},
    level=level, indent.by=indent.by, empty.e=empty.e
  ), sep="\n\n")

  # end try() & graph.off()
  js.prnt <- paste(js.prnt, rk.paste.JS(
    echo(paste0("\n",indent(level=level, by=indent.by),"})\n")),
    js(
      if(previewVar){
        echo("rk.graph.off()\n")
      } else {}
    ),
#    ite("full", echo("rk.graph.off()\n")),
    level=level, indent.by=indent.by, empty.e=empty.e
  ), sep="\n\n")

  return(js.prnt)
}
