// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

//  surface class for sunview

#include <surf_sun.h>

#include <ctype.h>
#include <fstream.h>
#include <math.h>

#include <cgipw.h>
#include <suntool/sunview.h>
#include <sunwindow/pixwin.h>
#include <pixrect/pixrect_hs.h>
#include <suntool/canvas.h>

extern "C"{
extern pw_reversevideo(...);

int open_pw_cgi(...);
int open_cgi_pw(...);
int cgipw_text_precision(...);
int cgipw_character_height(...);
int cgipw_character_orientation(...);
int cgipw_text_color(...);
int cgipw_text_font_index(...);
int cgipw_text(...);
int close_cgi_pw(...);
int close_pw_cgi(...);
};

#define	PIX_COLOUR(colour)	(((int)colour) << 5)

// constructor
sunscreen::sunscreen(const int x0, const int y0, const int x1, const int
y1,
                     const int ofsx, const int ofsy)
{ x_ofs = ofsx;
  y_ofs = ofsy;
  use_left = x0;
  use_right = x1;
  use_top = y0;
  use_bottom = y1;
  clr = 0;
  _dotsize = 1;
  heap_check(gfp = new grey_font_sunview(0, 0));
}

// sunscreen = canvas
void sunscreen::operator=(canvas& c)
{ cv = &c;
  pw = cv->pixwin();
}

// sunscreen = frame
void sunscreen::operator=(frame& f)
{ heap_check(cv = new canvas(f));
  (*cv).fixed_image(FALSE).height(initial_canvas_height)
       .width(initial_canvas_width);
  pw = cv->pixwin();
}

// sunscreen = colour
void sunscreen::operator=(int new_colour) { clr = new_colour; }

// sunscreen width
sunscreen& sunscreen::width(int n)
{ cv->width(n);
  return *this;
}

// sunscreen height
sunscreen& sunscreen::height(int n)
{ cv->height(n);
  return *this;
}

// sunscreen << LINE
surface& sunscreen::operator<<(LINE& rhs)
{  pw_vector(pw, rhs.x1(), rhs.y1(), rhs.x2(), rhs.y2(), PIX_SRC,
             (rhs.clr() == -1 ? clr : rhs.clr()));
  return *this;
}

// sunscreen << dot
surface& sunscreen::operator<<(dot& rhs)
{ const int ds = ( (rhs.size() == -1) ? _dotsize : rhs.size());
  for (int n = 0; n < ds; n++)
    for (int m = 0; m < ds; m++)
      pw_put(pw, rhs.x() - n, rhs.y() - m, 
             (rhs.clr() == -1 ? clr : rhs.clr()));
  return *this;
}

surface& sunscreen::operator<<(text& rhs)
{ if (!(rhs.length())) then
    return *this;

  Ccoor position;
  Ccgiwin cgi_descriptor;
  Cint cgi_name;

  position.x = rhs.x();
  position.y = rhs.y();
  if (position.x < 0) then
  { position.x = im_left + (int)((abs(rhs.x())/100.0)* image_width()) 
                 - (rhs.length() * rhs.height()) / 2;
  }

  open_pw_cgi();
  open_cgi_pw(pw, &cgi_descriptor, &cgi_name);
  cgipw_text_precision(&cgi_descriptor, CHARACTER);
  cgipw_character_height(&cgi_descriptor, rhs.height());
  cgipw_character_orientation(&cgi_descriptor, 1.0, 0.0, 0.0, 1.0);
  cgipw_text_color(&cgi_descriptor, 
                   (rhs.clr() == -1 ? clr : rhs.clr()));
  if (font == "ROMAN") then cgipw_text_font_index(&cgi_descriptor, ROMAN);
  cgipw_text(&cgi_descriptor, &position, (const char*)rhs.words());
  close_cgi_pw(&cgi_descriptor);
  close_pw_cgi();

  return *this;
}

int sunscreen::width(void)
{ return cv->width(); }

int sunscreen::height(void)
{ return cv->height(); }

void sunscreen::clear(void)
{ gfp->length(0);
  pw_rop(pw, 0, 0, width(), height(), PIX_CLR, NULL, 0, 0); 
}

void sunscreen::invert(void)
{ pw_copy(pw, 0, 0, width(), height(), PIX_NOT(PIX_SRC), pw, 0, 0); }

// dump a sunscreen to a disk file
surface& sunscreen::dump(const char* filename)
{ Pixrect* pr = mem_create(width(), height(), 8);
  pw_read(pr, 0, 0, width(), height(), PIX_NOT(PIX_SRC), pw, 0, 0);
  FILE* pf = fopen(filename, "w");
  pr_dump(pr, pf, RMT_NONE, RT_STANDARD, TRUE);
  fclose(pf);
  pr_close(pr);
  return *this;
}

// print a sunscreen on a printer
void sunscreen::print(const char* printer_name)
{ DREstring print_file_suffix((int)time(0), 10),
         print_file_name = "sunscreen" + print_file_suffix;
  dump(print_file_name);

  char* command_DREstring = (char*)(DREstring("/bin/rasfilter8to1 < " +
                          print_file_name +
                          " -a 255 | suntops -r | lpr -P" +
                          printer_name));
  system(command_DREstring);
  command_DREstring = (char*)(DREstring("rm " + print_file_name));
  system(command_DREstring);
}

// flush the grey_font buffer to a sunscreen
void sunscreen::flush(void)
{ if (!(gfp->null())) then
  { for (int n = 0; n < gfp->length(); n++)
    { if (!(gfp->null(n))) then
      { pw_rop(pw, _x, _y, gfp->width(), gfp->height(),
               PIX_SRC | PIX_COLOUR(7),
               (Pixrect*)(gfp->memory_pattern(gfp->element(n) - gfp->offset())),
               0, 0);
      }
      _y += gfp->height();
    }
  }
  gfp->length(0);
}

