#include "777200.h"

#include <colors.h>
#include <isam.h>

const COLOR CU_BACKGROUND = XVT_MAKE_COLOR(224,224,224);

const TReport_font& best_font(const char* name, int size, XVT_FONT_STYLE_MASK fs)
{
  static TAssoc_array fonts;
  static const long famax = 1024;
  static char* family[famax] = { 0 };
  static long families = 0;

  TToken_string key;
  key = name; key.add(size); key.add((long)fs);
  TReport_font* fnt = (TReport_font*)fonts.objptr(key);
  if (fnt == NULL)
  {
    if (families == 0)
      families = xvt_fmap_get_families(NULL, family, famax);
    
    int best = -1;
    double score = 0.5;
    for (long i = 0; i < families; i++) if (*name == *family[i])
    {
      const double s = xvt_str_fuzzy_compare(name, family[i]);
      if (s > score)
      {
        best = i;
        score = s;
        if (score >= 1.0)
          break;
      }
    }
    if (best >= 0)
      name = family[best];
    fnt = new TReport_font;
    fnt->create(name, size, fs);
    fonts.add(key, fnt);
  }
  return *fnt;
}

class TCU_report : public TReport
{
  TReport_font _fnt_rep, _fnt_prm, _fnt_lbl, _fnt_sub, _fnt_prg;
  int _quality;  // 0=text only; 1=borders only; 2=filled bars

private:
  const TReport_field& last_field() const;
  void set_field_pos(int row, int col, int width, TReport_field& fld) const;
  TReport_field& add_break(TReport_section& sec, int row, bool small);
  void add_field_label(const TReport_field& fld, const char* text, char alignment = 'L');
  TReport_field& add_prompt(TReport_section& sec, int row, int col, int len, const char* text);
  void add_field_sublabel(const TReport_field& fld, const char* text);
  void add_field_grid(const TReport_field& fld, bool underlined, bool date);
  TReport_field& add_field(TReport_section& sec, int row, int col, int width, const char* field);

protected:
  TReport_field& add_prompted_field(TReport_section& sec, int row, int col, int width, const char* field, const char* prompt, int promptlen = -1);
  TReport_field& add_prompted_bool(TReport_section& sec, int row, int col, int width, const char* field, const char* prompt, int promptlen = -1);
  TReport_field& add_labeled_field (TReport_section& sec, int row, int col, int width, const char* field, const char* label, char alignment = 'B');
  TReport_field& add_labeled_number(TReport_section& sec, int row, int col, int width, const char* field, const char* label, char alignment = 'B');
  TReport_field& add_boxed_field   (TReport_section& sec, int row, int col, int width, const char* field, const char* prompt, int flags = 0x0);
  TReport_field& add_gridded_field (TReport_section& sec, int row, int col, int len, 
                                    const char* field, const char* prompt);
  void add_underlined_text(TReport_section& body, int row, const char* text);

  TReport_field& add_big_text(TReport_section& sec, int row, int col, const char* label, COLOR rgb);
  void add_band(TReport_section& sec, int row, int height, COLOR rgb = CU_BACKGROUND);
  void add_long_break (TReport_section& sec, int row);
  void add_short_break(TReport_section& sec, int row);
  void begin_paragraph(TReport_section& sec, int row, int height, const char* label, int mode = 0);
  void end_paragraph(TReport_section& sec);

  void create_logo(TReport_section& header);
  void create_B();
  void create_D();
  void create_H();

public:
  TCU_report(int quality);
};

#define CU_FORM_WIDTH  7800
#define CU_FORM_BORDER  100
#define CU_HEAD_WIDTH  1000

#define CU_AFTER_LAST  -1
#define CU_BEFORE_LAST -2
#define CU_ALIGN_RIGHT -3

#define CU_EURO_LEN 16

static int _row_offset = 0;
static int _row_height = 300;
static int _row_last   = 0;
static TReport_field* _last_fld = NULL;

const TReport_field& TCU_report::last_field() const
{
  return *_last_fld;
}


void TCU_report::set_field_pos(int row, int col, int len, TReport_field& fld) const
{
  TReport_section& sec = fld.section();

  int dimx = (len+1) * 100;
  int dimy = 150;
  int posx = 0;
  if (col < 0)
  {
    switch(col)
    {
    case CU_BEFORE_LAST: posx = last_field().get_rect().left() - dimx - 100; break;
    case CU_ALIGN_RIGHT: posx = CU_FORM_BORDER+CU_FORM_WIDTH - dimx - 100; break;
    default            : posx = last_field().get_rect().right() + 100; break;
    }
  }
  else
  {
    if (_row_offset > 0)               // in paragraph
      posx = CU_FORM_BORDER+CU_HEAD_WIDTH + (col+1)*100;
    else
      posx = CU_FORM_BORDER + col*100; // in header
  }

  int posy = 0;
  if (_row_offset > 0)            // in paragraph
    posy = _row_offset + (row+1)*_row_height - dimy;
  else
    posy = (row+1)*100 - dimy;    // in header

  if (len <= 0)
    dimx = CU_FORM_BORDER+CU_FORM_WIDTH - posx - 100;

  fld.set_pos(posx, posy);
  fld.set_size(dimx, dimy);
}


void TCU_report::begin_paragraph(TReport_section& sec, int row, int height, const char* label, int mode)
{
  if (row < 0)
    _row_offset = _row_last;
  else
    _row_offset = row*100;
  _row_last   = _row_offset + height*100;
  _row_height = height <= 2 ? 200 : (height%3 ? 400 : 300);
  _last_fld = NULL;

  TString str1 = label, str2;
  int delta2 = 0;
  if (mode & 0x2)
  {
    if (mode == 0x2)
    {
      str2 = str1;
      str1.cut(0);
    }
    else
    {
      const int due_paragrafi = str1.find('\n');
      str2 = str1.mid(due_paragrafi+1);
      str1.cut(due_paragrafi);
      delta2 = 200;
    }
  }
  
  if (str1.full())
  {
    TReport_field* txt = new TReport_field(&sec);
    txt->set_vertical_alignment('T');
    txt->set_horizontal_alignment('L');
    txt->set_pos(CU_FORM_BORDER, _row_offset);
    txt->set_size(CU_HEAD_WIDTH, height*100);
    txt->set_pattern(PAT_HOLLOW);
    txt->set_text_color(COLOR_BLACK);
    txt->set_back_color(COLOR_INVALID);
    txt->set_picture(str1);
    txt->set_font(_fnt_prg);
    sec.add(txt);
  }

  if (str2.full())
  {
    TReport_font fnt2;
    fnt2.create(_fnt_lbl.name(), _fnt_lbl.size(), XVT_FS_BOLD);

    TReport_field* txt2 = new TReport_field(&sec);
    txt2->set_vertical_alignment('T');
    txt2->set_horizontal_alignment('L');
    txt2->set_pos(CU_FORM_BORDER, _row_offset+delta2);
    txt2->set_size(CU_HEAD_WIDTH, (height*100)-delta2);
    txt2->set_pattern(PAT_HOLLOW);
    txt2->set_text_color(COLOR_BLACK);
    txt2->set_back_color(COLOR_INVALID);
    txt2->set_picture(str2);
    txt2->set_font(fnt2);
    sec.add(txt2);
  }
}

void TCU_report::end_paragraph(TReport_section& sec)
{
  add_long_break(sec, _row_last/100);
}

void TCU_report::add_field_label(const TReport_field& fld, const char* text, char alignment)
{
  TReport_section& sec = fld.section();
  TReport_field* label = new TReport_field(&sec);
  label->set_type('T');
  label->set_pattern(PAT_HOLLOW);
  label->set_text_color(COLOR_BLACK);
  label->set_back_color(COLOR_INVALID);
  label->set_font(_fnt_lbl);
  const TReport_rct& rct = fld.get_rect();
  label->set_pos(rct.x, rct.y-100);
  label->set_size(rct.width(), 100);
  label->set_picture(text);
  label->set_vertical_alignment('B');
  if (alignment == 'C')
  {
    label->set_horizontal_alignment('C');
    label->set_pos(rct.x-400, rct.y-100);
    label->set_size(rct.width()+800, 75);
  }

  sec.add(label);
}

void TCU_report::add_field_sublabel(const TReport_field& fld, const char* text)
{
  TReport_section& sec = fld.section();
  TReport_field* label = new TReport_field(&sec);
  label->set_type('T');
  label->set_pattern(PAT_HOLLOW);
  label->set_back_color(COLOR_INVALID);
  label->set_text_color(COLOR_BLACK);
  label->set_font(_fnt_sub);
  const TReport_rct& rct = fld.get_rect();
  label->set_pos(rct.x, rct.y);
  label->set_size(rct.width(), rct.height()/3);
  label->set_picture(text);
  sec.add(label);
}

TReport_field& TCU_report::add_field(TReport_section& sec, int row, int col, int len, const char* field)
{
  TReport_field* txt = new TReport_field(&sec);
  txt->set_type('S');
  txt->set_vertical_alignment('B');
  txt->set_dynamic_height(false);
  if (_quality >= 2)
  {
    txt->set_pattern(PAT_SOLID);
    txt->set_back_color(COLOR_WHITE);
  }
  else
  {
    txt->set_pattern(PAT_HOLLOW);
    txt->set_back_color(COLOR_INVALID);
    txt->set_fore_color(COLOR_GRAY);
    txt->set_border(1);
  }
  txt->set_field(field);
  set_field_pos(row, col, len, *txt);
  sec.add(txt);
  _last_fld = txt;
  return *txt;
}

int estimated_prompt_len(const char* text)
{
  static XVT_FNTID font_id = NULL;
  if (font_id == NULL)
  {
    font_id = xvt_font_create();
    xvt_font_set_family(font_id, XVT_FFN_HELVETICA);
    xvt_font_set_size(font_id, 12);
    xvt_dwin_set_font(TASK_WIN, font_id);
  }
  else
  {
    if (text == NULL)
    {
      xvt_font_destroy(font_id);
      font_id = NULL;
    }
  }

  const int len = (text && *text) ? xvt_dwin_get_text_width(TASK_WIN, text, -1) : 0;
  return len / 6;
}

TReport_field& TCU_report::add_prompt(TReport_section& sec, int row, int col, int len, const char* text)
{
  TReport_field* label = new TReport_field(&sec);
  label->set_type('T');
  label->set_vertical_alignment('C');
  label->set_pattern(PAT_HOLLOW);
  label->set_back_color(COLOR_INVALID);
  label->set_text_color(COLOR_BLACK);
  label->set_font(_fnt_prm);
  label->set_picture(text);
  if (len < 0)
    len = estimated_prompt_len(text)/2;
  set_field_pos(row, col, len, *label);
  const TReport_rct& rct = label->get_rect();
  if (rct.height() > 100)
  {
    const int delta = rct.height() - 100;
    label->set_pos(rct.left(), rct.top()+delta);
    label->set_size(rct.width(), rct.height()-delta);
  }
  sec.add(label);
  _last_fld = label;
  return *label;
}

TReport_field& TCU_report::add_labeled_field(TReport_section& body, int row, int col, int len, 
                                             const char* field, const char* label, char alignment)
{
  if (alignment != 'C' && len > 0 && label && int(strlen(label)) > 2*len)
    alignment = 'C';

  TReport_field& txt = add_field(body, row, col, len, field);
  if (alignment == 'C')
    txt.set_horizontal_alignment(alignment);
  if (field && *field && field[1] >= 'A')
  {
    TString4 num = field+7; 
    if (num[0] == '0') num.ltrim(1);
    add_field_sublabel(txt, num);
  }
  if (label && *label)
    add_field_label(txt, label, alignment);
  return txt;
}

TReport_field& TCU_report::add_labeled_number(TReport_section& body, int row, int col, int width, 
                                              const char* field, const char* label, char alignment)
{
  TReport_field& txt = add_labeled_field(body, row, col, width, field, label, alignment);
  txt.set_horizontal_alignment('R');
  if (width == CU_EURO_LEN)
  {
    txt.set_type('S'); // avoid obnoxious x100
  }
  else
  {
    txt.set_type('N');
    txt.hide_zeroes(true);
  }
  return txt;
}

TReport_field& TCU_report::add_prompted_field(TReport_section& body, int row, int col, int width, const char* field, const char* prompt, int promptlen)
{
  if (col == CU_ALIGN_RIGHT && width > 0)
  {
    TReport_field& fld = add_field(body, row, col, width, field);
    if ((prompt && *prompt) || promptlen > 0)
      add_prompt(body, row, CU_BEFORE_LAST, promptlen, prompt);
    return fld;
  }
  if ((prompt && *prompt) || promptlen > 0)
  {
    add_prompt(body, row, col, promptlen, prompt);
    col = CU_AFTER_LAST;
  }
  return add_field(body, row, col, width, field);
}

TReport_field& TCU_report::add_prompted_bool(TReport_section& sec, int row, int col, int width, const char* field, const char* prompt, int promptlen)
{
  TReport_field& cb = add_prompted_field(sec, row, col, width, field, prompt, promptlen);
  cb.set_type('B');
  cb.set_horizontal_alignment('C');
  cb.set_vertical_alignment('C');
  return cb;
}

TReport_field& TCU_report::add_boxed_field(TReport_section& sec, int row, int col, int width, 
                                            const char* field, const char* prompt, int flags)
{
  TReport_field* fld = NULL;
  if (flags & 0x2)
    fld = &add_gridded_field (sec, row, col, width, field, prompt);
  else
    fld = &add_prompted_field(sec, row, col, width, field, prompt);
  
  TReport_field& txt = *fld;
  if (width < 16)
    txt.set_type('N');
  txt.set_border(2);
  txt.set_fore_color(COLOR_BLACK);
  txt.set_horizontal_alignment('C');

  if (flags & 0x1)  // Half height
  {
    const TReport_rct& rct = txt.get_rect(); 
    TReport_field* line = new TReport_field(&sec);
    line->set_type('R');
    line->set_pos(rct.left()-10, rct.top()-10);
    line->set_size(rct.width()+20, rct.height()/3);
    line->set_pattern(PAT_SOLID);
    line->set_back_color(COLOR_WHITE);
    sec.add(line);
  }

  return txt;
}


void TCU_report::add_field_grid(const TReport_field& fld, bool underlined, bool date)
{
  TReport_section& sec = fld.section();
  const TReport_rct& rct = fld.get_rect();
  
  if ((rct.width() / 100) & 1) // Campo di lunghezza dispari!
  {
    TReport_field& f = (TReport_field&)fld;
    f.set_width(rct.width()-100);
  }

  if (underlined)
  {
    TReport_field* line = new TReport_field(&sec);
    line->set_type('L');
    line->set_pos(rct.left(), rct.bottom());
    line->set_size(rct.width(), 0);
    line->set_border(1);
    line->set_fore_color(COLOR_BLACK);
    sec.add(line);
  }

  int fr, to, len, spc;
  if (date)
  {
    len = 4;
    fr  = 1;
    to  = 2;
    spc = 50;
  }
  else
  {
    len = rct.width() / 200;
    fr  = underlined ? 0 : 1;
    to  = len - (underlined ? 0 : 1);
    spc = underlined ? 0 : 50;
  }
  for (int y = fr; y <= to; y++)
  {
    TReport_field* line = new TReport_field(&sec);
    line->set_type('L');
    line->set_pos(rct.left()+y*rct.width()/len, rct.top()+spc);
    line->set_size(0, rct.height()-spc);
    line->set_border(1);
    line->set_fore_color(COLOR_BLACK);
    sec.add(line);
  }
}

TReport_field& TCU_report::add_gridded_field(TReport_section& sec, int row, int col, int len, 
                                   const char* field, const char* label)
{
  const bool is_date = len == 10;
  const bool underlined = len>=16 && _row_offset <= 0;  // Underlined grid in the header
  TString80 str; 
  if (is_date)
  {
    str = "## ## ####";
    len = 5;
  }
  else
  {
    for (int i = 0; i < len; i++) 
    {
      if (i) str << ' ';
      str << "#";
    }
    str.rtrim();
  }
  TReport_field& fld = add_labeled_field(sec, row, col, len*2, field, label);
  fld.set_picture(str);
  if (is_date)
    fld.set_horizontal_alignment('C');
  else
    fld.set_horizontal_alignment('R');
  add_field_grid(fld, underlined, is_date);

  return fld;
}

TReport_field& TCU_report::add_big_text(TReport_section& sec, int row, int col, const char* label, COLOR rgb)
{
  const TReport_font& fnt_big = best_font("Arial Black", _fnt_prg.size()*3, _fnt_prg.style());
  
  TReport_field* txt = new TReport_field(&sec);
  txt->set_type('T');
  txt->set_picture(label);
  txt->set_pos(CU_FORM_BORDER+col*100, row*100);
  txt->set_size(strlen(label)*300, 200);
  txt->set_pattern(PAT_HOLLOW);
  txt->set_back_color(COLOR_INVALID);
  txt->set_text_color(rgb);
  txt->set_font(fnt_big);
  
  sec.add(txt);
  return *txt;
}

TReport_field& TCU_report::add_break(TReport_section& sec, int row, bool small)
{
  TReport_field* line = new TReport_field(&sec);
  line->set_type('L');
  if (small)
  {
    line->set_pos(CU_FORM_BORDER+CU_HEAD_WIDTH, row*100);
    line->set_size(CU_FORM_WIDTH-CU_HEAD_WIDTH, 0);
    line->set_border(1);
  }
  else
  {
    line->set_pos(CU_FORM_BORDER, row*100);
    line->set_size(CU_FORM_WIDTH, 0);
    line->set_border(2);
  }
  line->set_fore_color(COLOR_BLACK);
  sec.add(line);
  return *line;
}

void TCU_report::add_long_break(TReport_section& sec, int row)
{ add_break(sec, row, false); }

void TCU_report::add_short_break(TReport_section& sec, int row)
{ add_break(sec, row, true); }

void TCU_report::add_band(TReport_section& sec, int row, int height, COLOR rgb)
{
  TReport_field* rct = new TReport_field(&sec);
  if (rgb == COLOR_INVALID)
    rgb = CU_BACKGROUND;
  rct->set_pos(CU_FORM_BORDER+CU_HEAD_WIDTH, row   *100);
  rct->set_size(CU_FORM_WIDTH-CU_HEAD_WIDTH, height*100);
  if (_quality >= 2)
  {
    rct->set_pattern(PAT_SOLID);
    rct->set_back_color(rgb);
  }
  else
  {
    rct->set_pattern(PAT_HOLLOW);
    rct->set_border(2);
    rct->set_fore_color(rgb);
    rct->set_back_color(COLOR_INVALID);
  }
  sec.add(rct);

  add_long_break(sec, row);
}

void TCU_report::add_underlined_text(TReport_section& body, int row, const char* text)
{
  TReport_field& line = add_break(body, _row_offset/100+row+1, true);
  const TReport_rct rct = line.get_rect();
  line.set_pos(rct.left()+100, rct.top()+25);
  line.set_size(rct.width()-200, rct.height());
  add_field_label(line, text, 'C');
}

void TCU_report::create_logo(TReport_section& header)
{
  add_big_text(header, 4, 0, "CERTIFICAZIONE", COLOR_GRAY).set_vertical_alignment('T');
  add_big_text(header, 6, 0, "UNICA", COLOR_BLACK).set_vertical_alignment('B');
  add_big_text(header, 6,12, "2015",  COLOR_LTGRAY).set_vertical_alignment('B');

  TReport_field* txt = new TReport_field(&header);
  txt->set_type('I');
  txt->set("res/AgenziaEntrate.gif");
  txt->set_pos(CU_FORM_BORDER, 900);
  txt->set_size(1200, 200);
  header.add(txt);
}

void TCU_report::create_B()
{
  TReport_section& header = section('B', 1);
  header.set_condition("#1=\"B\"");

  _row_offset = 0;
  estimated_prompt_len(NULL); // Reset font computer

  create_logo(header);
  add_gridded_field(header, 11, CU_ALIGN_RIGHT, 16, "#2", ""); // Codice fiscale dichiarante
  add_prompt(header, 11, CU_BEFORE_LAST, 7, "Codice fiscale");
 
  add_band(header, 13, 27);

  begin_paragraph(header, 13, 2, "TIPO DI COMUNICAZIONE");
  add_prompted_bool(header, 0,  0, 2, "#10", "Annullamento");
  add_prompted_bool(header, 0, 28, 2, "#11", "Sostituzione");
  end_paragraph(header);

  begin_paragraph(header, CU_AFTER_LAST, 9, "DATI RELATIVI\nAL SOSTITUTO");
  add_labeled_field(header, 0, 0, 32,  "#2", "Codice Fiscale");
  add_labeled_field(header, 1, 0, 36, "#12", "Cognome o Denominazione").set_alternate_field("#14");
  add_labeled_field(header, 1,CU_AFTER_LAST, CU_ALIGN_RIGHT, "#13", "Nome"); // La colonna segue il cognome
  TReport_field& tel = add_labeled_field(header, 2, 0, 16, "#16", "Telefono o fax");
  add_field_sublabel(tel, "prefisso    numero");
  tel.set_alternate_field("#17");
  add_labeled_field(header, 2, CU_AFTER_LAST, CU_ALIGN_RIGHT, "#15", "Indirizzo di posta elettronica"); // La colonna segue il telefono
  end_paragraph(header);

  begin_paragraph(header, CU_AFTER_LAST, 6, "DATI RELATIVI AL RAPPRESENTANTE FIRMATARIO DELLA COMUNICAZIONE");
  add_labeled_field(header, 0, 0, 24, "#18", "Codice Fiscale");
  TReport_field& cc = add_labeled_field(header, 0,32,  3, "#19", "Codice carica", 'C');
  cc.set_type('N'); cc.hide_zeroes(true);
  TReport_field& pi = add_gridded_field(header, 0,CU_ALIGN_RIGHT, 11, "#22", "Codice fiscale societ� o ente dichiarante");
  pi.set_type('N'); pi.hide_zeroes(true);
  add_labeled_field(header, 1, 0, 36, "#20", "Cognome");
  add_labeled_field(header, 1,CU_AFTER_LAST, CU_ALIGN_RIGHT, "#21", "Nome");
  end_paragraph(header);

  begin_paragraph(header, CU_AFTER_LAST, 3, "FIRMA DELLA COMUNICAZIONE");
  add_labeled_number(header, 0,  4, 5, "#23", "Numero certificazioni\nlavoro dipendente ed assimilati", 'C');
  add_labeled_number(header, 0, 15, 5, "#24", "Numero certificazioni\nlavoro autonomo e provvigioni", 'C');
  add_labeled_field (header, 0, 25, 3, "#25", "Quadro CT", 'C');
  add_prompted_field(header, 0, CU_ALIGN_RIGHT, 24, "", "FIRMA"); 
  end_paragraph(header);

  begin_paragraph(header, CU_AFTER_LAST, 7, "IMPEGNO ALLA PRESENTAZIONE TELEMATICA");
  _row_height = 300;
  add_prompted_field(header, 0, 0, 16, "#27", "Codice fiscale dell'intermediario");
  add_break(header, _row_offset/100+3, true);
  end_paragraph(header);

  begin_paragraph(header, _row_offset/100+3, 2, "Riservato\nall'intermediario");
  add_prompt(header, 0, 0, 30, "Impegno a presentare in via telematica la comunicazione");
  TReport_field& ipt = add_field(header, 0, CU_ALIGN_RIGHT, 2, "#28");
  ipt.set_type('N');
  ipt.set_horizontal_alignment('C');
  ipt.hide_zeroes(true);
  add_break(header, _row_offset/100+2, true);
  add_prompt(header, 1,0, -1, "Data dell'impegno");
  TReport_field& dit = add_gridded_field(header, 1, 10, 10, "#29", "");
  dit.set_type('N');
  dit.hide_zeroes(true);
  add_prompted_field(header,1, CU_ALIGN_RIGHT,24, "", "FIRMA DELL'INTERMEDIARIO", 15); 
  add_break(header, _row_offset/100+4, false);
}

void TCU_report::create_D()
{
  TReport_section& body = section('B', 2);
  body.set_condition("#1=\"D\"");
  body.force_page_break(true);

  _row_offset = 0;
  create_logo(body);
  
  TReport_font fnt_big; fnt_big.create(_fnt_prg.name(), 3*_fnt_prg.size()/2, _fnt_prg.style());
  TReport_field* txt = new TReport_field(&body);
  txt->set_type('T');
  txt->set_picture("CERTIFICAZIONE DI CUI ALL'ART.4, COMMI 6-ter e 6-quater,\n"
                   "DEL D.P.R. 22 LUGLIO 1998, n. 322, RELATIVA ALL'ANNO");
  txt->set_pos(CU_FORM_BORDER+28*100, 7*100);
  txt->set_size(7000, 300);
  txt->set_pattern(PAT_HOLLOW);
  txt->set_back_color(COLOR_INVALID);
  txt->set_text_color(COLOR_BLACK);
  txt->set_font(fnt_big);
  body.add(txt);

  add_boxed_field(body, 8, 68, 4, "2014", "");

  add_band(body, 12, 35);

  begin_paragraph(body, 12, 9, "DATI ANAGRAFICI\nDATI RELATIVI\nAL DATORE DI LAVORO,\nENTE PENSIONISTICO O\nALTRO SOSTITUTO\nD'IMPOSTA", 0x3);
  add_labeled_field(body, 0, 0,             16, "#DA001001", "Codice Fiscale");
  add_labeled_field(body, 0, CU_AFTER_LAST, 30, "#DA001002", "Cognome o Denominazione");
  add_labeled_field(body, 0, CU_AFTER_LAST, CU_ALIGN_RIGHT, "#DA001003", "Nome"); // La colonna segue il cognome

  add_labeled_field(body, 1, 0,            24, "#DA001004", "Comune");
  add_labeled_field(body, 1, CU_AFTER_LAST, 2, "#DA001005", "Prov.");
  add_labeled_field(body, 1, CU_AFTER_LAST, 5, "#DA001006", "Cap");
  add_labeled_field(body, 1, CU_AFTER_LAST, CU_ALIGN_RIGHT, "#DA001007", "Indirizzo");

  TReport_field& tel = add_labeled_field(body, 2, 0, 16, "#DA001008", "Telefono o fax");
  add_field_sublabel(tel, "    prefisso    numero");
  add_labeled_field(body, 2, CU_AFTER_LAST, 30, "#DA001009", "Indirizzo di posta elettronica"); 
  add_labeled_field(body, 2, CU_AFTER_LAST,  6, "#DA001010", "Codice attivit�"); 
  add_labeled_number(body, 2, CU_AFTER_LAST, CU_ALIGN_RIGHT, "#DA001011", "Codice sede"); 
  end_paragraph(body);
 
  begin_paragraph(body, CU_AFTER_LAST, 6, "DATI RELATIVI\nAL DIPENDENTE,\nPENSIONATO O\nALTRO PERCETTORE\nDELLE SOMME", 0x2);
  add_labeled_field(body, 0, 0,             16, "#DA002001", "Codice Fiscale");
  add_labeled_field(body, 0, CU_AFTER_LAST, 30, "#DA002002", "Cognome o Denominazione");
  add_labeled_field(body, 0, CU_AFTER_LAST, CU_ALIGN_RIGHT,  "#DA002003", "Nome"); // La colonna segue il cognome
  add_labeled_field(body, 1, 0,              1, "#DA002004", "Sesso\n(M o F)", 'C');
  add_gridded_field(body, 1, CU_AFTER_LAST, 10, "#DA002005", "Data di nascita");
  add_labeled_field(body, 1, 16,            24, "#DA002006", "Comune (o Stato estero) di nascita");
  add_labeled_field(body, 1, CU_AFTER_LAST,  3, "#DA002007", "Prov. nasc.\n(sigla)", 'C');
  add_labeled_field(body, 1, 49,             3, "#DA002008", "Categorie\nparticolari", 'C');
  add_labeled_number(body,1, 55,             3, "#DA002009", "Eventi\neccezionali", 'C');
  add_labeled_number(body,1, 61,             3, "#DA002010", "Casi di esclusione\ndalla precompilata", 'C');
  end_paragraph(body);

  begin_paragraph(body, CU_AFTER_LAST, 8, "");
  add_underlined_text(body, 0, "DOMICILIO FISCALE ALL'1/1/2014");
  add_labeled_field(body, 0, 0,             50, "#DA002020", "Comune");
  add_labeled_field(body, 0, CU_AFTER_LAST,  3, "#DA002021", "Provincia (sigla)");
  add_labeled_field(body, 0, CU_ALIGN_RIGHT, 6, "#DA002022", "Codice comune");
  add_underlined_text(body, 4, "DOMICILIO FISCALE ALL'1/1/2015");
  add_labeled_field(body, 1, 0,             50, "#DA002023", "Comune");
  add_labeled_field(body, 1, CU_AFTER_LAST,  3, "#DA002024", "Provincia (sigla)");
  add_labeled_field(body, 1, CU_ALIGN_RIGHT, 6, "#DA002025", "Codice comune");
  end_paragraph(body);

  begin_paragraph(body, CU_AFTER_LAST, 3, "DATI RELATIVI\nAL RAPPRESENTANTE", 0x2);
  add_labeled_field(body, 0, 0, 16, "#DA002030", "Codice Fiscale");
  end_paragraph(body);

  begin_paragraph(body, CU_AFTER_LAST, 6, "RISERVATO\nAI PERCIPIENTI ESTERI", 0x2);
  add_labeled_field(body, 0,              0,             16, "#DA002040", "Codice di identificazione fiscale estero");
  add_labeled_field(body, 0,  CU_AFTER_LAST, CU_ALIGN_RIGHT, "#DA002041", "Localit� di residenza estera");
  add_labeled_field(body, 1,              0,             50, "#DA002042", "Via e numero civico");
  add_labeled_field(body, 1, CU_ALIGN_RIGHT,              5, "#DA002043", "Codice Stato estero", 'C');
  end_paragraph(body);
  begin_paragraph(body, CU_AFTER_LAST, 3, "");
  add_gridded_field(body, 0,              0,             10, "#DA003001", "DATA");
  add_labeled_field(body, 0,             15, CU_ALIGN_RIGHT,          "", "FIRMA DEL SOSTITUTO DI IMPOSTA", 'C');
  end_paragraph(body);
}

void TCU_report::create_H()
{
  TReport_section& body = section('B', 3);
  body.set_condition("#1=\"H\"");
  body.force_page_break(true);
  _row_offset = 0;

  add_prompt     (body, 4, 0, 14, "Codice fiscale del percipiente");
  add_boxed_field(body, 4,CU_AFTER_LAST, 16, "#4", "", 0x1);

  add_boxed_field(body, 4, 74, 2, "#3", "", 0x3);
  add_prompt(body, 4, CU_BEFORE_LAST, -1, "Mod. N.");

  const TReport_font& fnt_big = best_font(_fnt_prg.name(), 3*_fnt_prg.size()/2, _fnt_prg.style());
  TReport_field* title = new TReport_field(&body);
  title->set_pos(CU_FORM_BORDER+CU_HEAD_WIDTH, 700);
  title->set_size(CU_FORM_WIDTH-CU_HEAD_WIDTH, 200);
  title->set_horizontal_alignment('C');
  title->set_vertical_alignment('C');
  title->set_picture("CERTIFICAZIONE LAVORO AUTONOMO,\nPROVVIGIONI E REDDITI DIVERSI");
  title->set_font(fnt_big);
  body.add(title);
  add_band(body, 10, 25);

  const int tab0 = 2, tab1 = 6, tab2 = 27, tab3 = CU_ALIGN_RIGHT;

  begin_paragraph(body, 10, 4, "DATI RELATIVI ALLE SOMME EROGATE\nTIPOLOGIA REDDITUALE", 0x3);
  add_labeled_field(body, 0, tab0, 2, "#AU001001", "Causale");
  end_paragraph(body);
  
  begin_paragraph(body, -1, 21, "DATI FISCALI");
  add_labeled_number(body, 0, tab1-1,         4, "#AU001002", "Anno", 'C');
  add_labeled_field (body, 0, CU_AFTER_LAST,  2, "#AU001003", "Anticipazione", 'C');
  add_labeled_number(body, 0, tab2, CU_EURO_LEN, "#AU001004", "Ammontare lordo corrisposto", 'C');
  add_labeled_number(body, 0, tab3, CU_EURO_LEN, "#AU001005", "Somme non soggette a ritenuta\nper regime convenzionale", 'C');
  
  add_labeled_number(body, 1, tab0,           2, "#AU001006", "Codice");
  add_labeled_number(body, 1, tab1, CU_EURO_LEN, "#AU001007", "Altre somme non soggette a ritenuta", 'C');
  add_labeled_number(body, 1, tab2, CU_EURO_LEN, "#AU001008", "Imponibile",                          'C');
  add_labeled_number(body, 1, tab3, CU_EURO_LEN, "#AU001009", "Ritenute a titolo di acconto",        'C');

  add_labeled_number(body, 2, tab1, CU_EURO_LEN, "#AU001010", "Ritenute a titolo d'imposta", 'C');
  add_labeled_number(body, 2, tab2, CU_EURO_LEN, "#AU001011", "Ritenute sospese",            'C');
  add_labeled_number(body, 2, tab3, CU_EURO_LEN, "#AU001012", "Addizionale regionale a titolo d'acconto", 'C');
  
  add_labeled_number(body, 3, tab1, CU_EURO_LEN, "#AU001013", "Addizionale regionale a titolo d'imposta", 'C');
  add_labeled_number(body, 3, tab2, CU_EURO_LEN, "#AU001014", "Addizionale regionale sospesa",            'C');
  add_labeled_number(body, 3, tab3, CU_EURO_LEN, "#AU001015", "Addizionale comunale a titolo d'acconto",  'C');
  
  add_labeled_number(body, 4, tab1, CU_EURO_LEN, "#AU001016", "Addizionale comunale a titolo d'imposta",  'C');
  add_labeled_number(body, 4, tab2, CU_EURO_LEN, "#AU001017", "Addizionale comunale sospesa",             'C');
  add_labeled_number(body, 4, tab3, CU_EURO_LEN, "#AU001018", "Imponibile anni precedenti",               'C');

  add_labeled_number(body, 5, tab1, CU_EURO_LEN, "#AU001019", "Ritenute operate anni precedenti",         'C');
  add_labeled_number(body, 5, tab2, CU_EURO_LEN, "#AU001020", "Contributi previdenziali\na carico del soggetto erogante", 'C');
  add_labeled_number(body, 5, tab3, CU_EURO_LEN, "#AU001021", "Contributi previdenziali\na carico del percipiente",       'C');

  add_labeled_number(body, 6, tab1, CU_EURO_LEN, "#AU001022", "Spese rimborsate",    'C');
  add_labeled_number(body, 6, tab2, CU_EURO_LEN, "#AU001023", "Ritenute rimborsate", 'C');
  end_paragraph(body);
}


TCU_report::TCU_report(int quality) : _quality(quality)
{
  set_lpi(6);
  set_cpi(10);
  _fnt_rep.create("Courier New", 12, 0);
  set_font(_fnt_rep);
  _fnt_lbl.create("Arial",           _fnt_rep.size()/2, 0);
  _fnt_sub.create(_fnt_lbl.name(),   _fnt_lbl.size(),   XVT_FS_BOLD);
  _fnt_prg.create(_fnt_lbl.name(), _fnt_rep.size()/2+1, XVT_FS_BOLD);
  _fnt_prm.create(_fnt_lbl.name(), 2*_fnt_rep.size()/3, 0);

  create_B();
  create_D();
  create_H();
}

void print_cu(const TFilename& datafile, int quality)
{
  TCU_report cur(quality);
  cur.set_recordset(new TTrasferimentoCU(datafile, 'r'));
  cur.preview();
  xvtil_statbar_set(NULL);
}