(* File: gnuplot_win32.ml

   Copyright (C) 2001-2004

     Christophe Troestler
     email: Christophe.Troestler@umh.ac.be
     WWW: http://math.umh.ac.be/an/software/

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   version 2.1 as published by the Free Software Foundation, with the
   special exception on linking described in file LICENSE.

   This library 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 file
   LICENSE for more details.
*)
(* 	$Id: gnuplot_win32.ml,v 1.6 2007-11-27 23:07:22 chris_77 Exp $	 *)

(*
 * Configuration
 ***********************************************************************)

(* The gnuplot executable.  You may want to set the full path to
   pgnuplot in [win32_gnuplot] if it isn't in your PATH. *)
let gnuplot = "pgnuplot.exe"
let gnuplot = "C:\\Program Files\\gnuplot\\bin\\pgnuplot.exe\\pgnuplot.exe"
(* let gnuplot = "gnuplot" (* Cygwin gnuplot *) *)
(* let gnuplot = "h:/anum/gp400win32/bin/pgnuplot.exe" *)

(* Set to [true] if you want to use the win32 (as opposed to the X11)
   gnuplot program under cygwin. *)
let cygwin_win32_gnuplot = true

let wgnuplot_ini = "C:\\WINDOWS\\WGNUPLOT.INI"

(***********************************************************************)

open Printf
open Gnuplot_dir

(* [is_cygwin] just says if we are under cygwin.
   [prefix] is to be added to cygwin temp files for the win32 gnuplot
   to find them. *)
let is_cygwin, prefix, temp_dir =
  match Sys.os_type with
  | "Win32" -> (false, "",
                (try Sys.getenv "TEMP" with Not_found -> "."))
  | "Cygwin" ->
      let cygroot =
        if cygwin_win32_gnuplot then begin
          let p = Unix.open_process_in "cygpath -w /" in
          let root = String.escaped(input_line p) in
          match Unix.close_process_in p with
          | Unix.WEXITED 0 -> root
          | _ -> failwith "Gnuplot_win32: \"cygpath\" returned an error code!"
        end else "" in
      (true, cygroot,
       (try Sys.getenv "TMPDIR" with Not_found -> "/tmp"))
  | _ ->
      output_string stderr "Configure PLATFORM in Makefile.conf";
      exit 1

let win32_gnuplot = not is_cygwin || cygwin_win32_gnuplot

(* Modify WGNUPLOT.INI in the windows dirextory if possible and backup
   the old one.  The name of the backup is returned ("" on failure). *)
let change_gnuplot_ini ?pos xsize ysize color =
  if Sys.file_exists wgnuplot_ini then begin
    let (backup, fh) = Filename.open_temp_file "gp" ".ini" in
    let fh = open_out wgnuplot_ini in
    output_string fh "[WGNUPLOT]\n";
    (match pos with
     | Some (x,y) when x >= 0 && y >= 0 ->
         fprintf fh "GraphOrigin=%i %i\n" x y
     | _ -> ());
    fprintf fh "GraphSize=%.0f %.0f\n" xsize ysize;
    output_string fh (if color then "GraphColor=1\n" else "GraphColor=0\n");
    output_string fh "GraphBackground=255 255 255\n";
    output_string fh "Border=0 0 0 0 0\n";
    close_out fh;
    backup
  end
  else begin
    (* Backup *)
    ""
  end

let restore_gnuplot_ini backup =
  if backup <> "" then begin
  end

type t = {
  dir : string;
  file : bool;
  mutable no : int;
}

let open_gnuplot_out =
  if win32_gnuplot then begin
    (* Win32 gnuplot *)
    fun persist ?pos xsize ysize color ->
      let backup = change_gnuplot_ini ?pos xsize ysize color in
      let gp = Unix.open_process_out
                 (if persist then gnuplot ^ " -" else gnuplot) in
      restore_gnuplot_ini backup;
      (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 })
  end
  else begin
    (* Cygwin X11 gnuplot *)
    fun persist ?pos xsize ysize color ->
      let pos =
        match pos with
        | None -> ""
        | Some (x,y) -> Printf.sprintf "%+i%+i" x y in
      let pgm =
        Printf.sprintf "%s -noraise -geometry %.0fx%.0f%s %s %s" gnuplot
          xsize ysize pos (if persist then "-persist" else "")
          (if color then "" else "-gray") in
      let gp = Unix.open_process_out pgm in
      (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 })
  end

let open_file_out fname =
  let gp = open_out fname in
  (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = true; no = 0 })

let close_out gp t =
  if t.file then close_out gp
  else
    match Unix.close_process_out gp with
    | Unix.WEXITED 0 -> remove_rec_dir t.dir
    | _ -> raise (Sys_error "Gnuplot ended with an error")


let set_terminal_X =
  if win32_gnuplot then begin
    (* Win32 gnuplot *)
    fun g _ _ color ->
      if color then output_string g "set terminal windows color\n"
      else output_string g "set terminal windows monochrome\n"
  end
  else begin
    (* Cygwin X11 gnuplot *)
    let pgmname = Filename.basename Sys.argv.(0) in
    fun g _ _ _ ->
      Printf.fprintf g "set terminal x11 title \"OCaml Gnuplot: %s\"\n" pgmname
  end


let open_temp_file t =
  t.no <- t.no + 1;
  let fname = Filename.concat t.dir (string_of_int t.no ^ ".dat") in
  (prefix ^ fname, open_out fname)


