/*----------------------------------------------------------------------------
  TEMPLATE EDITOR (LABEL ITEM VERSION)
  This demo creates template and saves it in TEMPLATE.RVF.

  This demo shows how to:
  - use TRVLabelItemInfo as field;
  - use TRVSeqItemInfo (only one numbered sequence ("Num") is inserted in
    this demo, but you can paste RTF files with additional sequences).
  - use "smart popups" to edit item properties.

  See mail merging application in the same directory - MAILMERGELI.

  Main settings:
  - since field names are stored in tags (see the help topic about tags)
    as strings, rvoTagsArePChars is included in Options of rve.
  - this demo uses free formatting of template (right click richviews,
    choose "Settings" from the context menu, choose "Allow adding styles
    dynamically").
----------------------------------------------------------------------------*/


//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "TEMainFrm.h"
#include "PopupFrm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "RichView"
#pragma link "RVEdit"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma resource "*.dfm"
TfrmTemplateEditor *frmTemplateEditor;
//---------------------------------------------------------------------------
__fastcall TfrmTemplateEditor::TfrmTemplateEditor(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmTemplateEditor::FormCreate(TObject *Sender)
{
  rve->LoadRVF(ExtractFilePath(Application->ExeName)+"..\\template.rvf");
  rve->Format();
}
//============================= Menu "File" =================================
void __fastcall TfrmTemplateEditor::mitSaveClick(TObject *Sender)
{
  rve->SaveRVF(ExtractFilePath(Application->ExeName)+"..\\template.rvf", false);
  rve->Modified = false;
}
//---------------------------------------------------------------------------
void __fastcall TfrmTemplateEditor::mitExitClick(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::FormCloseQuery(TObject *Sender,
      bool &CanClose)
{
  if (rve->Modified)
    switch(Application->MessageBox(L"Template was modified.\nSave?", L"Closing",
      MB_YESNOCANCEL | MB_ICONQUESTION))
    {
      case ID_YES:
        mitSaveClick(Sender);
        break;
      case ID_CANCEL:
        CanClose = false;
        break;
    }
}
//=========================== Menu "Insert" =================================
/* Inserting field.
  FieldCode - field code, saved in item's tag. Main application will search
    field by its code.
  DisplayString - will be displayed in place of field by default. Any string. */
void TfrmTemplateEditor::InsertField(UnicodeString FieldCode,
  const UnicodeString DisplayString)
{
  TRVLabelItemInfo* li = new TRVLabelItemInfo(rve->RVData, rve->CurTextStyleNo,
    DisplayString);
  li->Tag = (int)StrNew(FieldCode.w_str());
  rve->InsertItem("", li);
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitNameClick(TObject *Sender)
{
  InsertField("name", "<Name>");
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitCodeClick(TObject *Sender)
{
  InsertField("code", "<Code>");
}
//---------------------------------------------------------------------------
void __fastcall TfrmTemplateEditor::mitDateClick(TObject *Sender)
{
  TDate LDate = Date();
  InsertField("date:"+FloatToStr(LDate), "<"+DateToStr(LDate)+">");
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitNumberClick(TObject *Sender)
{
  TRVSeqItemInfo* si = new TRVSeqItemInfo(rve->RVData, "Num", rvseqDecimal,
    rve->CurTextStyleNo, 1, false);
  rve->InsertItem("", si);
}
//========================== Menu "View" ====================================
void __fastcall TfrmTemplateEditor::mitShowNeverClick(TObject *Sender)
{
  RVStyle1->FieldHighlightType = rvfhNever;
  rve->RefreshAll();
  mitShowNever->Checked   = true;
  mitShowCurrent->Checked = false;
  mitShowAlways->Checked  = false;
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitShowCurrentClick(TObject *Sender)
{
  RVStyle1->FieldHighlightType = rvfhCurrent;
  rve->RefreshAll();
  mitShowNever->Checked   = false;
  mitShowCurrent->Checked = true;
  mitShowAlways->Checked  = false;
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitShowAlwaysClick(TObject *Sender)
{
  RVStyle1->FieldHighlightType = rvfhAlways;
  rve->RefreshAll();
  mitShowNever->Checked   = false;
  mitShowCurrent->Checked = false;
  mitShowAlways->Checked  = true;
}
//======================= Smart Popups ======================================

void __fastcall TfrmTemplateEditor::rveCaretMove(TObject *Sender)
{
  TCustomRichViewEdit* tle = rve->TopLevelEditor;
  switch (tle->GetItemStyle(tle->CurItemNo))
  {
    case rvsLabel:
    {
      UnicodeString FieldCode = (wchar_t*)(tle->GetItemTag(tle->CurItemNo));
        if (FieldCode.SubString(1, 5)=="date:")
        {
          rve->SmartPopupProperties->Hint = "Change Date";
          rve->SmartPopupProperties->ImageIndex = 1;
          rve->SmartPopupProperties->Menu = NULL;
          rve->OnSmartPopupClick = rveSmartPopupClick;
        }
        else
        {
          rve->SmartPopupProperties->Hint = "Change Field Code";
          rve->SmartPopupProperties->ImageIndex = 0;
          rve->SmartPopupProperties->Menu = pmField;
          rve->OnSmartPopupClick = NULL;
        }
        rve->SmartPopupVisible = true;
      break;
    }
    case rvsSequence:
    {
      rve->SmartPopupProperties->Hint = "Change Numbering";
      rve->SmartPopupProperties->ImageIndex = 2;
      rve->SmartPopupProperties->Menu = pmSeq;
      rve->SmartPopupVisible = true;
      rve->OnSmartPopupClick = NULL;
      break;
    }
    default:
    {
      rve->SmartPopupVisible = false;
      break;
    }
  }
}
//---------------------------------------------------------------------------
// Sequences: checking appropriate numbering type in pmSeq
void TfrmTemplateEditor::SetNumberTypeToMenu(TRVSeqType NumberType)
{
  for (TRVSeqType i = rvseqDecimal; i<=rvseqUpperRoman; i=TRVSeqType(i+1))
    pmSeq->Items->Items[i]->Checked = pmSeq->Items->Items[i]->Tag==NumberType;
}
//---------------------------------------------------------------------------
// Sequences: checking pmSeq items before it is displayed
void __fastcall TfrmTemplateEditor::pmSeqPopup(TObject *Sender)
{
  if (rve->CurItemStyle!=rvsSequence)
    Beep();
  else
  {
    SetNumberTypeToMenu(((TRVSeqItemInfo*)(rve->GetCurrentItem()))->NumberType);
    mitResetTo->Checked = ((TRVSeqItemInfo*)(rve->GetCurrentItem()))->Reset;
    mitContinue->Checked = ! mitResetTo->Checked;
  }
}
//---------------------------------------------------------------------------
// Sequences: changing StartFrom and Reset properties of the current sequence
//  item as an editing operation
void TfrmTemplateEditor::ResetCurrentSeqTo(int Value, bool Reset)
{
  if (rve->CurItemStyle!=rvsSequence)
  {
    Beep();
    return;
  }
  // creating a new item with the desired properties and inserting it
  // instead the old item
  TRVSeqItemInfo* oldsi = (TRVSeqItemInfo*)(rve->GetCurrentItem());
  TRVSeqItemInfo* si = new TRVSeqItemInfo(rve->RVData);
  si->Assign(oldsi);
  if (Reset)
    si->StartFrom = Value;
  si->Reset = Reset;
  TCustomRichViewEdit* tle = rve->TopLevelEditor;
  tle->SetSelectionBounds(tle->CurItemNo, 0, tle->CurItemNo, 1);
  rve->InsertItem("", si);
}
//---------------------------------------------------------------------------
// Sequences: changing NumberType property of the current sequence
//  item as an editing operation
void __fastcall TfrmTemplateEditor::mitNumberTypeClick(TObject *Sender)
{
  if (rve->CurItemStyle!=rvsSequence)
  {
    Beep();
    return;
  }
  // creating a new item with the desired properties and inserting it
  // instead the old item
  TRVSeqItemInfo* oldsi = (TRVSeqItemInfo*)(rve->GetCurrentItem());
  TRVSeqItemInfo* si = new TRVSeqItemInfo(rve->RVData);
  si->Assign(oldsi);
  si->NumberType = (TRVSeqType)(((TMenuItem*)(Sender))->Tag);
  TCustomRichViewEdit* tle = rve->TopLevelEditor;
  tle->SetSelectionBounds(tle->CurItemNo, 0, tle->CurItemNo, 1);
  rve->InsertItem("", si);
}
//---------------------------------------------------------------------------
// Sequences: Reset to...
void __fastcall TfrmTemplateEditor::mitResetToClick(TObject *Sender)
{
  if (rve->CurItemStyle!=rvsSequence)
  {
    Beep();
    return;
  }
  UnicodeString s = IntToStr(((TRVSeqItemInfo*)(rve->GetCurrentItem()))->StartFrom);
  UnicodeString s2 = s;
  if (!((TRVSeqItemInfo*)(rve->GetCurrentItem()))->Reset)
    s = "";
  if (InputQuery("Reset","Reset &to:", s2) && s!=s2)
    ResetCurrentSeqTo(StrToIntDef(s2, 1), true);
}
//---------------------------------------------------------------------------
// Sequences: Continue numbering
void __fastcall TfrmTemplateEditor::mitContinueClick(TObject *Sender)
{
  ResetCurrentSeqTo(1/* <- ignored */, false);
}
//---------------------------------------------------------------------------
// Fields: changing field code and text as an editing operation
void TfrmTemplateEditor::ChangeFieldTo(UnicodeString FieldCode,
  const UnicodeString DisplayString)
{
  if (rve->CurItemStyle!=rvsLabel)
  {
    Beep();
    return;
  }
  // creating a new item with the desired properties and inserting it
  // instead the old item
  TRVLabelItemInfo* oldli = (TRVLabelItemInfo*)(rve->GetCurrentItem());
  TRVLabelItemInfo* li = new TRVLabelItemInfo(rve->RVData);
  li->Assign(oldli);
  li->Text = DisplayString;
  // Assign does not copy tag,
  // so do not call StrDispose((wchar_t*)(li->Tag))
  li->Tag = (int)StrNew(FieldCode.w_str());
  TCustomRichViewEdit* tle = rve->TopLevelEditor;
  tle->SetSelectionBounds(tle->CurItemNo, 0, tle->CurItemNo, 1);
  rve->InsertItem("", li);
}
//---------------------------------------------------------------------------
void __fastcall TfrmTemplateEditor::mitToNameClick(TObject *Sender)
{
  ChangeFieldTo("name", "<Name>");
}
//---------------------------------------------------------------------------

void __fastcall TfrmTemplateEditor::mitToCodeClick(TObject *Sender)
{
  ChangeFieldTo("code", "<Code>");
}
//---------------------------------------------------------------------------
// Fields: checking items in pmFields before it is displayed
void __fastcall TfrmTemplateEditor::pmFieldPopup(TObject *Sender)
{
  if (rve->CurItemStyle!=rvsLabel)
    Beep();
  else
  {
    UnicodeString FieldCode = (wchar_t*)(rve->GetCurrentTag());
    mitToName->Checked = FieldCode=="name";
    mitToCode->Checked = FieldCode=="code";
  }
}
//---------------------------------------------------------------------------
// Date field: displaying calendar popup
void __fastcall TfrmTemplateEditor::rveSmartPopupClick(
      TCustomRichView *Sender, TCustomControl *Button)
{
  if (rve->CurItemStyle!=rvsLabel)
  {
    Beep();
    return;
  }
  TRVLabelItemInfo* li = (TRVLabelItemInfo*)(rve->GetCurrentItem());
  UnicodeString FieldCode = (wchar_t*)(li->Tag);
  if (FieldCode.SubString(1, 5)!="date:")
  {
    Beep();
    return;
  }
  TfrmPopup* CalendarForm = new TfrmPopup(Application);
  CalendarForm->cal->Date = StrToInt(FieldCode.SubString(6, FieldCode.Length()));
  TPoint pt;
  pt.x = 0;
  pt.y = Button->Height;
  pt = Button->ClientToScreen(pt);
  if (pt.x+CalendarForm->Width > Screen->Width)
    pt.x = Screen->Width - CalendarForm->Width;
  if (pt.y+CalendarForm->Height > Screen->Height)
    pt.y = Screen->Height - CalendarForm->Height;
  CalendarForm->Left = pt.x;
  CalendarForm->Top = pt.y;
  CalendarForm->Show();
  rve->SmartPopupProperties->SetButtonState(true);
}
//---------------------------------------------------------------------------
// Date field: this method is called by the calendar form
void TfrmTemplateEditor::ChangeDate(TDate Date)
{
  ChangeFieldTo("date:"+FloatToStr(Date), "<"+DateToStr(Date)+">");
}
