#include <printwin.h>                  
#include <xvtility.h>
#include <applicat.h>

static char __spc[] = "                                                  "
"                                                  "
"                                                  "
"                                                  "
"                                                  "
"                                                  ";

#define LEN_SPACES(x) (win_get_text_width(win(),__spc,x))

void TPrintwin::paint_background(long j)
{
  _isbackground = _bg->items() > 0 && main_app().printer().isgraphics();
  if (!_isbackground) return;     
  int rw = (int)(j % _formlen);
  TString& rwd = (TString&)(*_bg)[rw];  
  int cnt = 0; char ch;  
  
  char curcol  = 'n';
  char curpen  = 'n';
  char curpat  = 'n';
  char curwid  = '1';

  unsigned int x1, x2;  PNT b, e;
  while (ch = rwd[cnt++])
  {           
    switch(ch)
    {
    case 'v':  // verticale intera
      x1  = (unsigned char)rwd[cnt++]-1;
      b.h = e.h = LEN_SPACES(x1)+LEN_SPACES(1)/2+_hofs;
      b.v = rw * _chary + _vofs; e.v = rw * _chary + _vofs;
      win_move_to(win(),b);
      win_draw_line(win(),e);
      break;   
    case 'o':  // verticale pezzo sopra
      x1  = (unsigned char)rwd[cnt++]-1;
      b.h = e.h = LEN_SPACES(x1)+LEN_SPACES(1)/2 + _hofs;
      b.v = rw * _chary + _vofs; e.v = rw * _chary - _chary/2 + _vofs; 
      win_move_to(win(),b);                 
      win_draw_line(win(),e); 
      break;   
    case 'u':  // verticale pezzo sotto
      x1 = (unsigned char)rwd[cnt++]-1;
      b.h = e.h = LEN_SPACES(x1)+LEN_SPACES(1)/2 + _hofs;
      b.v = rw*_chary + _chary/2 + _vofs; e.v = rw * _chary + _vofs; 
      win_move_to(win(),b);                          
      win_draw_line(win(),e); 
      break;   
    case 'h':  // orizzontale intera
      x1 = (unsigned char)rwd[cnt++]-1;
      x2 = (unsigned char)rwd[cnt++]-1;  
      b.v = e.v = rw*_chary + _chary/2 + _vofs;
      b.h = LEN_SPACES(x1)+_hofs; e.h = LEN_SPACES(x2)+_hofs;
      win_move_to(win(),b);
      win_draw_line(win(),e); 
      break;   
    case 'r':  // orizzontale scorciata agli estremi
      x1 = (unsigned char)rwd[cnt++]-1;
      x2 = (unsigned char)rwd[cnt++]-1;
      b.v = e.v = rw*_chary + _chary/2 + _vofs;
      b.h = LEN_SPACES(x1)+LEN_SPACES(1)/2 + _hofs; 
      e.h = LEN_SPACES(x2)+LEN_SPACES(1)/2+_hofs;
      win_move_to(win(),b);
      win_draw_line(win(),e); 
      break;       
    case 'W':
      curwid = rwd[cnt++];
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
              trans_pen(curpen));
      break;
    case 'P':
      curpen = rwd[cnt++];
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
              trans_pen(curpen));
      break;
    case 'B':
      curpat = rwd[cnt++];
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
              trans_pen(curpen));
      break;
    case 'C':
      curcol = rwd[cnt++];
      set_pen(trans_color(curcol), curwid- '0', trans_brush(curpat),
              trans_pen(curpen));
      break;
    default:
      break;
    }
  }                    
  // restore default pen
  set_pen(COLOR_BLACK);
}

void TPrintwin::paint_row(long j)
{
  static char line[257];
  
  const char* cp;  int pos = 0;          
  int pixpos = 0;
  int row = (int)(j % _formlen);
  
  strcpy(line,_txt.line(j));
  
  _txt.read_line(j);
  while(cp = _txt.piece()) 
  {     
    pos += strlen(cp); 
#if XVT_OS != XVT_OS_SCOUNIX         
    int st  = _txt.get_style();
    long bg = trans_color(_txt.get_background());
    long fg = trans_color(_txt.get_foreground());
    set_font(FF_FIXED, st & 0x000f, _char_size);                 
    set_color(fg,bg);
#else
    set_color(COLOR_BLACK, COLOR_WHITE);
#endif
    win_draw_text(win(), pixpos+_hofs, row*_chary + _chary + _vofs - _descent, 
                  (char *)cp, -1);                           
#if XVT_OS == XVT_OS_WIN
    if (st & underlined) 
    {
      PNT b, e;
      
      set_pen(COLOR_BLACK);
      b.h = pixpos + _hofs; b.v = row*_chary + _chary + _vofs;
      e.h = (pixpos+win_get_text_width(win(), line, pos)) + _hofs; e.v = b.v;
      win_move_to  (win(),b);
      win_draw_line(win(),e);
    }
#endif
    pixpos = win_get_text_width(win(), line, pos); 
  }        
  paint_background(j);
}                   


bool TPrintwin::print_band(int page, RCT& r)
{
  int j = page*_formlen;
  int rows = (r.bottom - r.top) / _chary;  
  int top = r.top / _chary;  
  
  for (int k = top; k < top+rows; k++) 
  {
    if ((j+k) < _txt.lines() && k < _formlen) 
      paint_row(j+k);
    else break;
  }
  return j+k < _txt.lines();
}


bool TPrintwin::do_print()
{                    
  int page = 0; 
  RCT* rct;
  bool ok = TRUE;          
  
  while (ok && !_aborted)
  {
    _aborted = !(bool)start_page(_printrcd);   
    while (!_aborted && ok && (rct = next_band()) != NULL)
      ok = print_band(page, *rct);
    finish_page(_printrcd); 
    page++;
  }     
  return !_aborted;             
}                                            


TPrintwin::~TPrintwin()
{
  if (_inited && win() != NULL_WIN) close_print_window(win(), _printrcd);
  set_win(NULL_WIN);
}


TPrintwin::TPrintwin(PRINT_RCD* p, TTextfile& txt, int chsz) : 
_printrcd(p), _aborted(FALSE), _txt(txt), _char_size(chsz), _inited(FALSE)
{
  WINDOW w = new_print_window(_printrcd, (char*)(const char*)main_app().title());
  set_win(w);                                                                    
  _inited = TRUE;
  if (w != NULL_WIN)
  {         
    _bg           = main_app().printer().getbgdesc();
    _isbackground = _bg->items() > 0 && main_app().printer().isgraphics();
    _formlen      = main_app().printer().formlen();

    set_font(FF_SYSTEM,0,_char_size);           
    
    win_get_font_metrics(win(), &_lead, &_ascent, &_descent);

    _chary = main_app().printer().get_dots_per_line();
    
    RCT rct; get_client_rect(win(),&rct);
    
    _vofs         = main_app().printer().get_vert_offset(); 
    _hofs         = (rct.right - rct.left) % LEN_SPACES(1);  
  }
  else _aborted = TRUE;
}
