#' Save or restore RKWard workplace
#' 
#' \code{rk.save.workplace} can be used to save a representation of the RKWard
#' workplace (i.e. which scripts, data edtiors and other windows are shown) to
#' a file. \code{rk.restore.workplace} restores an RKWard workplace as saved by
#' \code{rk.save.workplace}.
#' 
#' If the \code{file} parameter is omitted (or \code{NULL}), a suitable
#' filename is selected automatically. If a workspace has been loaded, this is
#' the URL of the workspace with an appended \code{.rkworkplace}. Otherwise a
#' filename in the RKWard directory, as generated by
#' \link{rk.get.tempfile.name}.
#' 
#' NOTE: Not all types of windows can be saved and restored. Esp. graphics
#' device windows will not be restored (but WILL be closed by
#' \code{rk.restore.workplace()}, if \code{close.windows} is TRUE).
#' 
#' @aliases rk.save.workplace rk.restore.workplace
#' @param file a character string giving the url of the file to save to, or
#'   NULL for automatic selection of a suitable file (see Details).
#' @param description For internal use, only. A character string describing the
#'   workplace status to save. Generally, you should leave this as the default
#'   value (\code{NULL}).
#' @param close.windows a logical; whether current windows should be closed
#'   before restoring.
#' @return Both functions return \code{NULL}.
#' @author Thomas Friedrichsmeier \email{rkward-devel@@kde.org}
#' @seealso \url{rkward://page/rkward_for_r_users}, \link{rk.get.workspace.url}
#' @keywords utilities
#' @rdname rk.workplace
#' @examples
#' 
#' ## Not run
#' rk.save.workplace ()
#' rk.restore.workplace ()
#' ## End not run
#' 
#' @export
"rk.save.workplace" <- function (file=NULL, description=NULL) {
	if (is.null (file)) {
		file <- rk.get.workspace.url ()
		if (is.null(file)) file <- rk.get.tempfile.name (prefix="unsaved", extension=".RData", directory=rk.tempdir ())
		else file <- URLdecode(file)
		file <- paste (file, "rkworkplace", sep=".")
	}
	if (is.null (description)) lines <- .rk.do.plain.call ("workplace.layout", "get")
	else lines <- description
	writeLines (lines, file)
}

#' @rdname rk.workplace
#' @export
"rk.restore.workplace" <- function (file=NULL, close.windows=TRUE) {
	if (is.null (file)) {
		if (exists (".rk.workplace.save", envir=globalenv (), inherits=FALSE)) {
			# For backwards compatibility with workspaces saved by RKWard 0.5.4 and earlier.
			# TODO: remove in time.
			lines <- as.character (.GlobalEnv$.rk.workplace.save)
			rm (list = c (".rk.workplace.save"), envir=globalenv ())
		} else {
			file <- URLdecode (rk.get.workspace.url ())
			if (is.null (file)) file <- rk.get.tempfile.name (prefix="unsaved", extension=".RData", directory=rk.tempdir ())
			file <- paste (file, "rkworkplace", sep=".")
		}
	}

	close <- "close"
	if (!isTRUE (close.windows)) close <- "noclose"
	if (!exists ("lines", inherits=FALSE)) lines <- readLines (file)
	.rk.do.plain.call ("workplace.layout", c ("set", close, lines), synchronous=FALSE)
	invisible (NULL)
}

#' Control window placement and style
#' 
#' \code{.rk.with.window.hints} can be used to make windows appear in a specific
#' location: attached, detached, or in a named position where a previous window is
#' found. (The latter used for preview windows, importantly). It can also be used to pass
#' "style" hints, importantly indicating that the window is a preview window. All specifications
#' affect newly created windows, only, not existing ones.
#' 
#' NOTE: This function is still somewhat experimental, and it is not guaranteed that
#' it will remain in place, with compatible parameters.
#' 
#' @aliases .rk.with.window.hints rk.with.window.hints
#' @param expr Expression to evaluate, unsually an expression that is expected to create exactly one
#'        new window.
#' @param placement a character string specifying either "attached" or "detached" placement, or
#'        (if left empty) the default placement for the type of window created.
#' @param name character string specifing a named position. If a name is given, and this position is
#'        not yet known, the placement hint (see above) will be followed. If later a second window is
#'        created with the same given name, it will replace the first window.
#' @param style character string specifing a style hint. Currently, this can either be "preview" or
#'        "" (default), with most types of window not implementing any special behavior for "preview".
#' @return \code{NULL}, invisibly.
#' @author Thomas Friedrichsmeier \email{rkward-devel@@kde.org}
#' @keywords utilities
#' @rdname rk.with.window.hints
#' @examples
#' 
#' ## Not run
#' .rk.with.window.hints ({
#'    RK ()
#'    plot (1, 1)
#' }, "attached")
#' ## End not run
#' 
#' @export
".rk.with.window.hints" <- function (expr, placement="", name="", style="") {
	.rk.do.plain.call ("set.window.placement.hint", as.character (c (placement, name, style)), FALSE)
	on.exit (.rk.do.plain.call ("set.window.placement.hint", c ("", "", ""), FALSE))
	eval.parent (expr)
	invisible (NULL)
}
