/*******************************************************************************
+
+  LEDA 3.5
+
+  ps.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#ifndef _PS_H_
#define _PS_H_

#include <LEDA/stream.h>
#include <LEDA/color.h>
#include <LEDA/list.h>
#include <LEDA/point.h>
#include <LEDA/polygon.h>
#include <LEDA/circle.h>

// ---------------------------------------------------------------------------

#define DefPSFileName	"out.ps"

#define PSPixelPerCM	28.35

// ---------------------------------------------------------------------------

class PostScript {

  ostrstream s;
  string f;
  
  double x_width,y_width;

  string creator;
  
  string color_name[16];
  void init_color_names();
  
  void define_colors(ostream& out);
  void header(ostream& out);
  void prolog(ostream& out);
  void footer(ostream& out);
  
  void init();

  static color fgcol;
  static color bgcol;
  

 public:

  PostScript(char* fname=DefPSFileName) : f(fname) {
    init();
  }

/*
  PostScript(const PostScript& ps) : s(ps.s), f(DefPSFileName) {
    init();
  }
*/
  
  ~PostScript() {}

  void set_origin(double x, double y);
  
  void set_color(color c);

  void scale(double f_x, double f_y);

  void set_line_width(int w);

  double get_x_width();
  double set_x_width(double new_x_width);
  double get_y_width();
  double set_y_width(double new_y_width);
  
  void set_page_size(double new_x_width, double new_y_width);
  
  char* str();

  void add(const char* str);
  void add(const string& str);
  void add(color c);

  bool save(string fname);
  bool save();
  
  void set_variable(string name, int value);
  void set_font(const char* name="Times-Roman", int size=10);

  void set_line_style(line_style s);

  void draw_text(double x, double y, string s, color c=PostScript::fgcol);
  void draw_text(point p, string s, color c=PostScript::fgcol);
  void draw_ctext(double x, double y, string s, color c=PostScript::fgcol);
  void draw_ctext(point p, string s, color c=PostScript::fgcol);

  void draw_circle(double x, double y, double r, color c=PostScript::fgcol);
  void draw_circle(point p, double r, color c=PostScript::fgcol);
  void draw_circle(const circle& c, color clr=PostScript::fgcol);

  void draw_disc(double x, double y, double r, color c=PostScript::fgcol);
  void draw_disc(point p, double r, color c=PostScript::fgcol);
  void draw_disc(const circle& c, color clr=PostScript::fgcol);

  void draw_segment(double x0, double y0, double x1, double y1, color c=PostScript::fgcol);
  void draw_segment(point p, point q, color c=PostScript::fgcol);
  void draw_segment(const segment& s, color c=PostScript::fgcol);
  
  void draw_arrow(double x0, double y0, double x1, double y1, color c=PostScript::fgcol);
  void draw_arrow(point p, point q, color c=PostScript::fgcol);
  void draw_arrow(const segment& s, color c=PostScript::fgcol);
  
  void draw_rectangle(double x0, double y0, double x1, double y1, color c=PostScript::fgcol);
  void draw_filled_rectangle(double x0, double y0, double x1, double y1, color c=PostScript::fgcol);

  void draw_ellipse(double x, double y, double r1, double r2, color c=PostScript::fgcol);
  void draw_ellipse(point p, double r1, double r2, color c=PostScript::fgcol);
  
  void draw_filled_ellipse(double x, double y, double r1, double r2, color c=PostScript::fgcol);
  void draw_filled_ellipse(point p, double r1, double r2, color c=PostScript::fgcol);

  void draw_circle_node(double x, double y, double r, color c=PostScript::fgcol);
  void draw_circle_node(point p, double r, color c=PostScript::fgcol);
  void draw_circle_node(const circle& c, color clr=PostScript::fgcol);

  void draw_ellipse_node(double x, double y, double r1, double r2, color c=PostScript::fgcol);
  void draw_ellipse_node(point p, double r1, double r2, color c=PostScript::fgcol);
  
  void draw_rectangle_node(double x0, double y0, double x1, double y1, color c=PostScript::fgcol);

  void draw_polygon(const list<point>& P, color c=PostScript::fgcol);
  void draw_polygon(const polygon& P, color c=PostScript::fgcol);
  
  void draw_filled_polygon(const list<point>& P, color c=PostScript::fgcol);
  void draw_filled_polygon(const polygon& P, color c=PostScript::fgcol);
  
  void draw_polygon_edge(const list<point>& P, color c=PostScript::fgcol);
  void draw_polygon_edge(const polygon& P, color c=PostScript::fgcol);
  
  void draw_polygon_arrow(const list<point>& P, color c=PostScript::fgcol);
  void draw_polygon_arrow(const polygon& P, color c=PostScript::fgcol);
  
  friend ostream& operator << (ostream& o, PostScript& ps);
};

// ---------------------------------------------------------------------------

PostScript& operator << (PostScript& ps, const char* str);
PostScript& operator << (PostScript& ps, const string& str);
PostScript& operator << (PostScript& ps, double d);
PostScript& operator << (PostScript& ps, int i);  
PostScript& operator << (PostScript& ps, color c);

PostScript& operator << (PostScript& ps, const circle& c);
PostScript& operator << (PostScript& ps, const segment& s);

PostScript& operator << (PostScript& ps, color c);

// ---------------------------------------------------------------------------

#endif
