///////////////////////////////////////////////////////////////////////////////
// Name:        tutorial5.cpp
// Purpose:     Tutorial 5: Test program for wxPdfDocument
// Author:      Ulrich Telle
// Modified by:
// Created:     2005-08-29
// Copyright:   (c) Ulrich Telle
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include <wx/tokenzr.h>
#include <wx/txtstrm.h>
#include <wx/wfstream.h>

#include "wx/pdfdoc.h"

/**
* Tables
*
* This tutorial shows how to make tables easily. 
* 
* A table being just a collection of cells, it is natural to build one from
* them. The first example is achieved in the most basic way possible: simple
* framed cells, all of the same size and left aligned. The result is rudimentary
* but very quick to obtain. 
* 
* The second table brings some improvements: each column has its own width,
* titles are centered and figures right aligned. Moreover, horizontal lines
* have been removed. This is done by means of the border parameter of the Cell()
* method, which specifies which sides of the cell must be drawn. Here we want the
* left (L) and right (R) ones. It remains the problem of the horizontal line to
* finish the table. There are two possibilities: either check for the last line in
* the loop, in which case we use LRB for the border parameter; or, as done here,
* add the line once the loop is over. 
* 
* The third table is similar to the second one but uses colors. Fill, text and
* line colors are simply specified. Alternate coloring for rows is obtained by
* using alternatively transparent and filled cells. 
*/

class PdfTuto5 : public wxPdfDocument
{
public:
  // Load data
  void LoadData(const wxString& file, wxArrayPtrVoid& data)
  {
    // Read file lines
    wxFileInputStream f(file);
    wxTextInputStream text( f );
    wxString line;
    while (!f.Eof())
    {
      text >> line;
      if (!f.Eof() && line.Length() > 0)
      {
        wxArrayString* row = new wxArrayString;
        data.Add(row);
        wxStringTokenizer tkz(line, wxT(";"));
        while ( tkz.HasMoreTokens() )
        {
          wxString token = tkz.GetNextToken();
          row->Add(token);
        }
      }
    }
  }

  // Simple table
  void BasicTable(wxArrayString& header,wxArrayPtrVoid& data)
  {
    size_t j;
    // Header
    for (j = 0; j < header.GetCount(); j++)
    {
      Cell(40,7,header[j],wxPDF_BORDER_FRAME);
    }
    Ln();
    // Data
    for (j = 0; j < data.GetCount(); j++)
    {
      wxArrayString* row = (wxArrayString*) data[j];
      size_t k;
      for (k = 0; k < (*row).GetCount(); k++)
      {
        Cell(40,6,(*row)[k],wxPDF_BORDER_FRAME);
      }
      Ln();
    }
  }

  // Better table
  void ImprovedTable(wxArrayString& header,wxArrayPtrVoid& data)
  {
    // Column widths
    double w[4] = {40,35,40,45};
    // Header
    size_t i;
    for (i = 0; i <header.GetCount(); i++)
    {
      Cell(w[i],7,header[i],wxPDF_BORDER_FRAME,0,wxPDF_ALIGN_CENTER);
    }
    Ln();
    // Data
    size_t j;
    for (j = 0; j < data.GetCount(); j++)
    {
      wxArrayString* row = (wxArrayString*) data[j];
      Cell(w[0],6,(*row)[0],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT);
      Cell(w[1],6,(*row)[1],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT);
      Cell(w[2],6,(*row)[2],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_RIGHT);
      Cell(w[3],6,(*row)[3],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_RIGHT);
      Ln();
    }
    // Closure line
    Cell((w[0]+w[1]+w[2]+w[3]),0,wxT(""),wxPDF_BORDER_TOP);
  }

  // Colored table
  void FancyTable(wxArrayString& header, wxArrayPtrVoid& data)
  {
    // Colors, line width and bold font
    SetFillColour(wxColour(255,0,0));
    SetTextColour(255);
    SetDrawColour(wxColour(128,0,0));
    SetLineWidth(.3);
    SetFont(wxT(""),wxT("B"));
    //Header
    double w[4] = {40,35,40,45};
    size_t i;
    for (i = 0; i < header.GetCount(); i++)
    {
      Cell(w[i],7,header[i],wxPDF_BORDER_FRAME, 0, wxPDF_ALIGN_CENTER, 1);
    }
    Ln();
    // Color and font restoration
    SetFillColour(wxColour(224,235,255));
    SetTextColour(0);
    SetFont(wxT(""));
    // Data
    int fill = 0;
    size_t j;
    for (j = 0; j < data.GetCount(); j++)
    {
      wxArrayString* row = (wxArrayString*) data[j];
      Cell(w[0],6,(*row)[0],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_LEFT,fill);
      Cell(w[1],6,(*row)[1],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_LEFT,fill);
      Cell(w[2],6,(*row)[2],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_RIGHT,fill);
      Cell(w[3],6,(*row)[3],wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT,0,wxPDF_ALIGN_RIGHT,fill);
      Ln();
      fill = 1 - fill;
    }
    Cell((w[0]+w[1]+w[2]+w[3]),0,wxT(""),wxPDF_BORDER_TOP);
  }
};

void
tutorial5()
{
  PdfTuto5 pdf;
  // Column titles
  wxArrayString header;
  wxArrayPtrVoid data;
  header.Add(wxT("Country"));
  header.Add(wxT("Capital"));
  header.Add(wxT("Area (sq km)"));
  header.Add(wxT("Pop. (thousands)"));
  // Data loading
  pdf.LoadData(wxT("countries.txt"),data);
  pdf.SetFont(wxT("Helvetica"),wxT(""),14);
  pdf.AddPage();
  pdf.BasicTable(header,data);
  pdf.AddPage();
  pdf.ImprovedTable(header,data);
  pdf.AddPage();
  pdf.FancyTable(header,data);
  pdf.SaveAsFile(wxT("tutorial5.pdf"));
  size_t j;
  for (j = 0; j < data.GetCount(); j++)
  {
    wxArrayString* row = (wxArrayString*) data[j];
    delete row;
  }
}

