
/******************************************************************************
* MODULE     : editor.gen.cc
* DESCRIPTION: routines for the editor
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license and comes WITHOUT
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
* If you don't have this file, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/

#include <Editor/edit_main.gen.h>
#include <tm_widget.gen.h>
#include <tm_buffer.gen.h>
#include <file.gen.h>
#include <dir.gen.h>
#include <PsDevice/printer.gen.h>
#include <PsDevice/page_type.gen.h>
#include <convert.gen.h>
#include <connect.gen.h>
#include <typesetter.gen.h>

#module code_edit_main
#import edit_main
#import tm_widget
#import tm_buffer
#import file
#import dir
#import printer
#import page_type
#import convert
#import connect
#import typesetter

#include <dlfcn.h>
#include <setjmp.h>

extern bool eval_scheme_any (string s, string& r);
extern bool eval_scheme_func_tree_tree (string f, tree t, tree& r);

/******************************************************************************
* Constructors and destructor
******************************************************************************/

editor_rep::editor_rep ():
  basic_widget_rep (dis), et (buf->t) {}

editor_rep::editor_rep (server_rep* sv2, display dis, tm_buffer buf2):
  basic_widget_rep (dis), sv (sv2), buf (buf2), et (buf2->t) {}

edit_main_rep::edit_main_rep (server_rep* sv, display dis, tm_buffer buf):
  editor_rep (sv, dis, buf)
{
  notify_change (THE_TREE);
  tp= correct_cursor (et, path (0));
}

edit_main_rep::~edit_main_rep () {}

editor
new_editor (server_rep* sv, display dis, tm_buffer buf) {
  return new edit_main_rep (sv, dis, buf);
}

/******************************************************************************
* Global routines
******************************************************************************/

void
edit_main_rep::clear_buffer () {
  assign (path (), tree (DOCUMENT, tree ("")));
}

void
edit_main_rep::new_window () {
}

void
edit_main_rep::clone_window () {
}

void
edit_main_rep::tex_buffer () {
}

string
edit_main_rep::get_name () {
  return buf->name;
}

void
edit_main_rep::focus_on_this_editor () {
  sv->focus_on_editor (this);
}

/******************************************************************************
* Printing
******************************************************************************/

void
edit_main_rep::set_page_parameters () {
  if (attached ()) this << emit_invalidate_all ();

  string medium     = get_init_string (PAGE_MEDIUM);
  string type       = get_init_string (PAGE_TYPE);
  string orientation= get_init_string (PAGE_ORIENTATION);
  bool   landscape  = (orientation == "landscape");

  if (medium == "automatic") {
    init_env (PAGE_ODD, "5mm");
    init_env (PAGE_EVEN, "5mm");
    init_env (PAGE_RIGHT, "5mm");
    init_env (PAGE_TOP, "5mm");
    init_env (PAGE_BOT, "5mm");
    notify_change (THE_AUTOMATIC_SIZE);
    return;
  }
  if (type == "user") return;

#define PAGE_INIT(feature) \
  init_env (feature, page_get_feature (type, feature, landscape))
  PAGE_INIT (PAR_WIDTH);
  PAGE_INIT (PAGE_ODD);
  PAGE_INIT (PAGE_EVEN);
  PAGE_INIT (PAGE_RIGHT);
  PAGE_INIT (PAGE_TOP);
  PAGE_INIT (PAGE_BOT);
  PAGE_INIT (PAGE_REDUCE_LEFT);
  PAGE_INIT (PAGE_REDUCE_RIGHT);
  PAGE_INIT (PAGE_REDUCE_TOP);
  PAGE_INIT (PAGE_REDUCE_BOT);
#undef PAGE_INIT
}

void
edit_main_rep::set_page_medium (string medium) {
  init_env (PAGE_MEDIUM, medium);
  set_page_parameters ();
}

void
edit_main_rep::set_page_type (string type) {
  init_env (PAGE_TYPE, type);
  set_page_parameters ();
}

void
edit_main_rep::set_page_orientation (string orientation) {
  init_env (PAGE_ORIENTATION, orientation);
  set_page_parameters ();
}

/******************************************************************************
* Printing
******************************************************************************/

string printing_dpi ("600");
string printing_cmd ("lpr");
string printing_on ("a4");

void
edit_main_rep::print (string ps_name, bool conform, int first, int last) {
  string medium = env->get_string (PAGE_MEDIUM);
  if (conform && (medium == "papyrus")) conform= FALSE;
  if ((!conform) && (medium == "automatic")) {
    set_message (
      "Error: you should switch to ``paper'' or ``papyrus'' page type",
      "print");
    return;
  }

  // Set environment variables for printing

  typeset_prepare ();
  env->write (DPI, printing_dpi);
  env->write (PAGE_REDUCE_LEFT, "0cm");
  env->write (PAGE_REDUCE_RIGHT, "0cm");
  env->write (PAGE_REDUCE_TOP, "0cm");
  env->write (PAGE_REDUCE_BOT, "0cm");
  env->write (PAGE_SHOW_HF, "true");
  if (!conform) env->write (PAGE_MEDIUM, "paper");

  // Typeset pages for printing

  box the_box= typeset_as_document (env, et, path ());

  // Determine parameters for printer device

  string page_type = printing_on;
  double w         = env->get_length (PAGE_WIDTH);
  double h         = env->get_length (PAGE_HEIGHT);
  double cm        = env->decode_length (string ("1cm"));
  bool   landsc    = (env->get_string (PAGE_ORIENTATION) == "landscape");
  int    dpi       = as_int (printing_dpi);
  int    start     = max (0, first-1);
  int    end       = min (N(the_box[0]), last);
  int    pages     = end-start;
  if (conform) {
    page_type= "user";
    SI bw= the_box[0][0]->w();
    SI bh= the_box[0][0]->h();
    string bws= as_string (bw) * "unit";
    string bhs= as_string (bh) * "unit";
    w= env->decode_length (bws);
    h= env->decode_length (bhs);
  }

  // Print pages

  int i;
  ps_device dev=
    printer (dis, ps_name, dpi, pages, page_type, landsc, w/cm, h/cm);
  for (i=start; i<end; i++) {
    rectangles rs;
    the_box[0]->sx(i)= 0;
    the_box[0]->sy(i)= 0;
    the_box[0][i]->redraw (dev, path (0), rs);
    if (i<end-1) dev->next_page ();
  }
  delete dev;
}

void
edit_main_rep::print_to_file (string ps_name, string first, string last) {
  print (ps_name, FALSE, as_int (first), as_int (last));
}

void
edit_main_rep::print_buffer (string first, string last) {
  string temp= get_temp_file_name () * ".ps";
  print (temp, FALSE, as_int (first), as_int (last));
  system (printing_cmd * " " * temp);
  system ("rm " * temp);
}

void
edit_main_rep::export_ps (string ps_name, string first, string last) {
  print (ps_name, TRUE, as_int (first), as_int (last));
}

/******************************************************************************
* Evaluation of expressions
******************************************************************************/

void
edit_main_rep::eval (string s) {
  eval (string_to_scheme_tree (s));
}

void
edit_main_rep::eval (scheme_tree p) {
  string r;
  (void) sv->eval_any (p, r);
  set_message (r, "evaluate expression");
}

bool
edit_main_rep::exec (string s) {
  return sv->exec (s);
}

bool
edit_main_rep::exec (scheme_tree p) {
  return sv->exec (p);
}

tree
edit_main_rep::the_line () {
  path p= search_parent_upwards (DOCUMENT);
  return copy (subtree (et, p));
}

tree
edit_main_rep::the_buffer () {
  return copy (et);
}

tree
edit_main_rep::shell_eval (tree t) {
  string s= tree_to_verbatim (t);
  string e= eval_system (s);
  return verbatim_to_tree (e);
}

tree
edit_main_rep::scheme_eval (tree t) {
  string s= tree_to_verbatim (t);
  string r;
  (void) eval_scheme_any (s, r);
  return verbatim_to_tree (r);
}

tree
edit_main_rep::edit_lisp_compile (tree t) {
  return dl_compile_lisp (t);
}

tree
edit_main_rep::edit_lisp_eval (tree t) {
  return dl_eval_lisp (t);
}

tree
edit_main_rep::prog_eval (tree t) {
  string lan= get_env_string (PROG_LANGUAGE);
  if (lan == "shell") return shell_eval (t);
  if (lan == "scheme") return scheme_eval (t);
  if (lan == "TeXmacs lisp") return edit_lisp_eval (t);
  if (package_declared (lan)) return sv->evaluate (lan, "default", t);
  set_message ("Programming language not declared",
	       "Evaluate#'" * lan * "'#expression");
  return "";
}

void
edit_main_rep::process_input () {
  path p= search_upwards_expand ("input");
  if (nil (p) || (N (subtree (et, p)) != 3)) return;
  tree t= subtree (et, p) [2];
  string lan= get_env_string (PROG_LANGUAGE);

  if (is_func (t, DOCUMENT, 1)) t= t[0];
  if (is_expand (t, "math", 1)) {
    tree in= tuple (lan, t[1]), out;
    if (!eval_scheme_func_tree_tree ("cas-math-input", in, out)) t= out;
  }

  if (lan == "shell") {
    start_output ();
    lazy_shell_command (tree_to_verbatim (t));
  }
  else if (connection_declared (lan)) {
    start_output ();
    feed_input (t);
  }
  else {
    start_output ();
    tree u= prog_eval (t);
    if (!is_document (u)) u= tree (DOCUMENT, u);
    insert_tree (u);
    start_input ();
  }
}

/******************************************************************************
* Miscellaneous
******************************************************************************/

void
edit_main_rep::show_tree () {
  cout << et << "\n";
}

void
edit_main_rep::show_env () {
  cout << env << "\n";
}

void
edit_main_rep::show_path () {
  cout << tp << "\n";
}

void
edit_main_rep::show_cursor () {
  cout << "Principal cursor: "
       << cu->ox << ", " << cu->oy << " [" << cu->delta << "]\n";
  cout << "Ghost cursor    : "
       << mv->ox << ", " << mv->oy << " [" << mv->delta << "]\n";
}

void
edit_main_rep::show_selection () {
  selection sel; selection_get (sel);
  cout << "physical  selection: " << start_p << " --- " << end_p << "\n";
  cout << "logical   selection: " << sel->start << " --- " << sel->end << "\n";
}

void
edit_main_rep::show_meminfo () {
  mem_info ();
}

void
edit_main_rep::edit_special () {
}

void
edit_main_rep::edit_test () {
  bool error_flag;
  tree t= directory_tree (".", error_flag, TRUE);
  cout << make_path (t) << "\n";
  // cout << "Test !\n";
}

#endmodule // code_edit_main
