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

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma link "RVEdit"
#pragma link "RichView"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  rve1->Clear();
  rve1->AddNLATag("John: ", 3, 0, 0);
  rve1->AddNLATag("Funny, very funny :)", 0, -1, 0);
  rve1->AddNLATag("Rob: ", 3, 0, 0);
  rve1->AddNLATag("I do not think so :(...", 0, -1, 0);
  rve1->Format();

  rve4->Clear();
  rve4->AddNLATag("La la la:):):):)", 1, 0, 0);
  rve4->AddNLATag("La la la:):):):)", 2, -1, 0);
  rve4->AddNLATag("La la la:):):):)", 0, -1, 0);
  rve4->Format();
}
//---------------------------------------------------------------------------
// Using Search feature of RichViewEdit to insert emotion icons
void SearchAndInsertIcon(const AnsiString Code, int ImageIndex,
  TCustomRichViewEdit* rve1, TCustomImageList* ImageList1)
{
  rve1->SetSelectionBounds(0, rve1->GetOffsBeforeItem(0), 0, rve1->GetOffsBeforeItem(0));
  TRVESearchOptions Options;
  Options << rvseoDown;
  while (rve1->SearchText(Code, Options))
    rve1->InsertBullet(ImageIndex, ImageList1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  LockWindowUpdate(rve1->Handle);
  try
  {
    SearchAndInsertIcon(":)", 0, rve1, ImageList1);
    SearchAndInsertIcon(":|", 1, rve1, ImageList1);
    SearchAndInsertIcon(":(", 2, rve1, ImageList1);
  }
  catch(...)
  {
  }
  LockWindowUpdate(0);
}
//---------------------------------------------------------------------------
int GetImageIndex(char mouth)
{
  switch (mouth)
  {
    case ')': return 0;
    case '|': return 1;
    default:  return 2;
  }
}
AnsiString GetSmile(int ImageIndex)
{
  switch(ImageIndex)
  {
    case 0: return ":)";
    case 1: return ":|";
    default: return ":(";
  }
}
//---------------------------------------------------------------------------
void TForm1::AddWithIcons(TCustomRichView* rv, AnsiString s, int StyleNo,
  int &ParaNo)
{
  AnsiString s2 = "";
  while (s!="")
  {
    int p = s.Pos(":"); // searching for "eyes"
    if (!p)
    {
      // not found
      rv->AddNLATag(s2+s, StyleNo, ParaNo, 0);
      ParaNo = -1;
      return;
    }
    // is it really "eyes"?
    if (s.Length()>p && (s[p+1]==')' || s[p+1]=='|' || s[p+1]=='('))
    {
      // a smile is found
      s2 += s.SubString(1, p-1);
      if (s2!="")
      {
        rv->AddNLATag(s2, StyleNo, ParaNo, 0);
        s2 = "";
        ParaNo = -1;
      }
      rv->AddBulletEx("", GetImageIndex(s[p+1]), ImageList1, ParaNo);
      ParaNo = -1;
      s = s.SubString(p+2, s.Length());
    }
    else
    {
      // this is not a smile
      s2 = s.SubString(1, p);
      s = s.SubString(p+1, s.Length());
    }
  }

  if (s2!="")
  {
    rv->AddNLATag(s2, StyleNo, ParaNo, 0);
    s2 = "";
    ParaNo = -1;
  }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if (Edit1->Text!="")
  {
    rv2->AddNLATag("Me: ",3,0,0);
    int ParaNo = -1; // adding to the same line
    AddWithIcons(rv2, Edit1->Text, 0, ParaNo);
    rv2->FormatTail();
    Edit1->Text = "";
  }
  else
    MessageBeep(0);
}
//---------------------------------------------------------------------------
// From TRichViewEdit with emoticons detection
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  // this example has the following limitations:
  // - non-text will be ignored
  // - assumes that styles of rv3 and rve4 are the same
  int ParaNo = 0;
  for (int i=0; i<rve4->ItemCount; i++)
  {
    if (rve4->IsFromNewLine(i))
      ParaNo = rve4->GetItemPara(i);
    if (rve4->GetItemStyle(i)>=0)
      AddWithIcons(rv3, rve4->GetItemTextA(i), rve4->GetItemStyle(i), ParaNo);
  }
  rv3->FormatTail();
  rve4->SetFocus();
}
//---------------------------------------------------------------------------
// From TRichViewEdit as is
void __fastcall TForm1::Button4Click(TObject *Sender)
{
  TMemoryStream*Stream = new TMemoryStream;
  rve6->SaveRVFToStream(Stream, false);
  Stream->Position = 0;
  rv5->InsertRVFFromStream(Stream, rv5->ItemCount);
  delete Stream;
  rv5->FormatTail();
  rve6->SetFocus();
}
//---------------------------------------------------------------------------
// Emoticons autodetection on typing
void __fastcall TForm1::rve6KeyPress(TObject *Sender, char &Key)
{
  if (Key!=')' && Key!='(' && Key!='|')
    return;
  TCustomRichViewEdit* rve = ((TCustomRichViewEdit*)Sender)->TopLevelEditor;
  int ItemNo = rve->CurItemNo;
  if (rve->GetItemStyle(ItemNo)<0)
    return;
  int Offs = rve->OffsetInCurItem;
  AnsiString s = rve->GetItemTextA(ItemNo);
  if (s=="" || Offs==1)
    return;
  if (s[Offs-1]==':')
  {
    rve->SetSelectionBounds(ItemNo, Offs-1, ItemNo, Offs);
    rve->InsertBullet(GetImageIndex(Key), ImageList1);
    Key = 0;
  }
}
//---------------------------------------------------------------------------
int GetBulletImageIndex(TCustomRichView* rv, int ItemNo)
{
  int tag, r;
  AnsiString s;
  TCustomImageList* il;
  rv->GetBulletInfo(ItemNo, s, r, il, tag);
  return r;
}
//---------------------------------------------------------------------------
// BACKSPACE disassembles emoticon
void __fastcall TForm1::rve6KeyDown(TObject *Sender, WORD &Key,
	TShiftState Shift)
{
  if (Key!=VK_BACK)
    return;
  TCustomRichViewEdit* rve = ((TCustomRichViewEdit*)Sender)->TopLevelEditor;
  if (rve->SelectionExists())
    return;
  int ItemNo = rve->CurItemNo;
  int Offs = rve->OffsetInCurItem;
  if (rve->GetItemStyle(ItemNo)==rvsBullet && Offs==1)
  {
    Key = 0;
    rve->SetSelectionBounds(ItemNo, 0, ItemNo, 1);
    rve->InsertText(GetSmile(GetBulletImageIndex(rve, ItemNo)), false);
  }
}
void __fastcall TForm1::rv5RVFImageListNeeded(TCustomRichView *Sender,
	int ImageListTag, TCustomImageList *&il)
{
  il = ImageList1;	
}
//---------------------------------------------------------------------------
