/*------------------------------------------------------------------------------}
{
  Very simple "mail merging" application.
  It loads a template from TEMPLATE.RVF, and data from CUSTOMERS.TXT.
  Template can be modified with another application in this directory:
  TEMPLATEEDITOR.

  Main settings:
  - since field names are stored in tags (see the help topic about tags)
    as strings, rvoTagsArePChars is included in Options of rvTemplate and
    rvOutput.
  - this demo uses a predefined set of styles (right click richviews,
    choose "Settings" from the context menu, choose "Use a predefined
    set of styles"). That means - only two text styles (see below) will be used.
  - rvOutput->Style = rvsOutput, rvTemplate->Style = rvsTemplate.
  - rvsTemplate has absolutely the same set of TextStyles as in template editor
    (0th style - normal text, 1th - field code)
  - rvsOutput has a similar set of styles, but 1th text style looks like
    normal text.
}
------------------------------------------------------------------------------*/
#include <vcl\vcl.h>
#include <stdio.h>
#pragma hdrstop

#include "MMMainFrm.h"
//---------------------------------------------------------------------------
#pragma link "RichView"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void ReadString(char*s, FILE*F)
{
   fgets(s, 200, F);
   int i=0;
   while (s[i])
   {
     if (s[i]=='\n')
       s[i]=0;
     i++;
   }
}
//---------------------------------------------------------------------------
/*
  This procedure loads file CUSTOMERS.TXT into:
  - ListBox1->Items (<- names of customers)
  - Codes (<- codes of customers)

  In real applications data can be stored in some database
*/
//---------------------------------------------------------------------------
void TForm1::LoadCustomers()
{
  FILE* F = fopen((ExtractFilePath(Application->ExeName)+"Customers.txt").c_str(), "rt");
  char s[200];
  ReadString(s,F);
  int Count = StrToIntDef(s, 0);
  for (int i=0; i<Count; i++)
  {
    ReadString(s,F);
    Codes->Add(s);
    ReadString(s,F);
    ListBox1->Items->Add(Trim((AnsiString)s));
  }
  fclose(F);
}
//---------------------------------------------------------------------------
/*
  Initialization: loading template into rvOutput, loading customers data.
*/
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Codes = new TStringList;
  LoadCustomers();
  rvTemplate->LoadRVF(ExtractFilePath(Application->ExeName)+"template.rvf");
  rvTemplate->Format();
  if (ListBox1->Items->Count)
  {
    ListBox1->ItemIndex = 0;
    ListBox1->OnClick(NULL);
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  delete Codes;
  Codes = NULL;
}
//---------------------------------------------------------------------------
/*
  This function returns a current field value by the field name.
  In this example, we have two fields: "name" and "code"
*/
AnsiString TForm1::GetFieldValueFromDatabase(const AnsiString FieldName)
{
  int Index = ListBox1->ItemIndex;
  if (FieldName=="name")
    return ListBox1->Items->Strings[Index];
  if (FieldName=="code")
    return Codes->Strings[Index];
  return "{error: illegal field code}";
}
//---------------------------------------------------------------------------
/*
  This function iterates through all items in RVData, and if tag of
  some text contains non-empty text, it calls GetFieldValueFromDatabase(tag) and
  replace this text with returned value.
  You can move this function to your application unchanged.
  Initial call: FillFields(RichView.RVData);
*/
void TForm1::FillFields(TCustomRVData* RVData)
{
  for (int i=0; i<RVData->ItemCount; i++)
    if (RVData->GetItemStyle(i)==rvsTable)
    {
      TRVTableItemInfo* table = (TRVTableItemInfo*)(RVData->GetItem(i));
      for (int r=0; r<table->Rows->Count; r++)
        for (int c=0; c<table->Rows->Items[r]->Count; c++)
          if (table->Cells[r][c])
            FillFields(table->Cells[r][c]->GetRVData());
      table->Changed();
    }
    else if (RVData->GetItemStyle(i)>=0)
    {
      AnsiString FieldName = PChar(RVData->GetItemTag(i));
      if (FieldName!="")
        RVData->SetItemText(i, GetFieldValueFromDatabase(FieldName));
    }
}
//---------------------------------------------------------------------------
/*
  On highlighting a new list box item: updating document in rvOutput.
*/
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
  rvOutput->Clear();
  if (ListBox1->ItemIndex>=0)
  {
    rvOutput->LoadRVF(ExtractFilePath(Application->ExeName)+"template.rvf");
    FillFields(rvOutput->RVData);
    rvOutput->Format();
  }
}
//---------------------------------------------------------------------------
