/*==============================================================================
  This demo shows how to work with tables, mouse events, GetItemAt method
==============================================================================*/
#include <vcl\vcl.h>
#include <stdlib.h>
#include <mmsystem.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma link "RichView"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma resource "*.dfm"
TForm1 *Form1;

#define QUESTIONCOUNT 4
#define ANSWERCOUNT 9

// Sorted array of answers.
const UnicodeString Answers[QUESTIONCOUNT][ANSWERCOUNT] =
 {
  {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"},
  {"Pluto", "Neptune", "Uranus", "Saturn", "Jupiter", "Mars", "Earth", "Venus", "Mercury"},
  {"Pluto", "Mercury", "Mars", "Venus", "Earth", "Neptune", "Uranus", "Saturn", "Jupiter"},
  {"Jupiter", "Saturn", "Uranus", "Neptune", "Earth", "Venus", "Mars", "Mercury", "Pluto"}
 };

// Array of questions
const UnicodeString Questions[QUESTIONCOUNT] =
  {
    "Which of these planets is closest to the Sun?",
    "Which of these planets is the most distant from the Sun?",
    "Which of these planets is the smallest?",
    "Which of these planets is the largest?"
   };


#define TABLECOLOR (TColor)0xCCFFFF
#define HEADCOLOR  (TColor)0x990033
#define HLTCOLOR   (TColor)0x66CCFF
#define SELCOLOR   (TColor)0x3399CC
#define PASSCOLOR  (TColor)0x00FF33
#define FAILCOLOR  (TColor)0x0033FF

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// Filling RichView. Preparing the quiz
void TForm1::BuildQuiz()
{
  int CorrectAnswer;
  RichView1->Clear();
  AnsweredCount = 0;
  TStringList* sl = new TStringList;
  for (int i = 0; i<QUESTIONCOUNT; i++)
  {
    // adding questions. one question is one table
    FillQuestion(sl, Answers[i], CorrectAnswer);
    AddTable(Questions[i], sl, CorrectAnswer);
    RichView1->AddNLWTag("",0,0,0);
  }
  delete sl;
  // adding hypertext "button"
  RichView1->AddNLWTag("Ready!", 2, 1, 0);
  RichView1->Format();
  Ready = false;
  RVStyle1->TextStyles->Items[2]->HoverBackColor = FAILCOLOR;
}
//------------------------------------------------------------------------------
// This function chooses 3 answers from ARR and add them in SL.
// Index of the correct answer is returned in CORRECTANSWER
#define OPTIONCOUNT 3
void TForm1::FillQuestion(TStringList* sl, const UnicodeString arr[], int& CorrectAnswer)
{
  int Options[OPTIONCOUNT], i, j, v;
  sl->Clear();
  // Choosing 3 different random answers
  for (i = 0; i<OPTIONCOUNT; i++)
    do
    {
      v = random(ANSWERCOUNT);
      for (j = 0; j<i; j++)
        if (Options[j]==v)
        {
          v = -1;
          break;
        }
      if (v>=0)
      {
        Options[i] = v;
        sl->Add(arr[v]);
      }
    }
    while (v<0);
  // Finding the correct answer. arr is sorted so that the correct answer
  // is an answer with smaller index
  CorrectAnswer = -1;
  j = QUESTIONCOUNT+1;
  for (i = 0; i<OPTIONCOUNT; i++)
    if (Options[i]<j)
    {
      j = Options[i];
      CorrectAnswer = i;
    }
}
//------------------------------------------------------------------------------
// Adding one question
// The 0-th table row will contain the question. Other rows - answers.
// Index of the correct answer is stored in invisible table caption
void TForm1::AddTable(const UnicodeString Question, TStringList* Answers,
  int CorrectAnswer)
{

  TRVTableItemInfo* table = new TRVTableItemInfo(Answers->Count+1, 1, RichView1->RVData);
  table->BestWidth = -80;
  table->ParaNo = 1;
  table->Color = TABLECOLOR;
  table->Cells[0][0]->Clear();
  table->Cells[0][0]->AddNLWTag(Question,1,0,0);
  table->Cells[0][0]->Color = HEADCOLOR;
  for (int i=0; i<Answers->Count; i++)
  {
    table->Cells[i+1][0]->Clear();
    table->Cells[i+1][0]->AddNLWTag(Answers->Strings[i],0,0,0);
  }
  table->BorderVSpacing = 5;
  table->BorderHSpacing = 10;
  table->CellPadding     = 4;
  table->BorderWidth     = 2;
  table->CellBorderWidth = 0;
  table->BorderStyle     = rvtbColor;
  table->CellBorderStyle = rvtbColor;
  RichView1->AddItem(IntToStr(CorrectAnswer), table);
}
//------------------------------------------------------------------------------
// If RVData is a table cell, this function highlights this cell.
// Removes highlighting from the previously highlighted cell (stored in HighlightedRVData)
// Updates HighlightedRVData
// Highlighted cell has color = HLTCOLOR, others - clNone.
void TForm1::HighlightCell(TCustomRVFormattedData* RVData)
{
  if (HighlightedRVData==RVData)
    return;
  if (HighlightedRVData)
  {
    ((TRVTableCellData*)HighlightedRVData)->Color = clNone;
    HighlightedRVData->Invalidate();
    HighlightedRVData = NULL;
  }
  if (!RVData->InheritsFrom(__classid(TRVTableCellData)) ||
      ((TRVTableCellData*)RVData)->Color==SELCOLOR)
    return;
  int r,c;
  ((TRVTableCellData*)RVData)->GetTable()->GetCellPosition((TRVTableCellData*)RVData,r,c);
  if (r==0)
    return;
  ((TRVTableCellData*)RVData)->Color = HLTCOLOR;
  RVData->Invalidate();
  HighlightedRVData = RVData;
}
//------------------------------------------------------------------------------
// If RVData is a table cell, this function selects this cell.
// Selected cell has color = SELCOLOR.
// Updates number of answered questions (AnsweredCount).
// If all questions are answered, changes highlight of hypertext jump from
// red to green.
void TForm1::SelectCell(TCustomRVFormattedData* RVData)
{
  if (!RVData->InheritsFrom(__classid(TRVTableCellData)))
    return;
  TRVTableItemInfo* table = ((TRVTableCellData*)RVData)->GetTable();
  int r,c;
  table->GetCellPosition((TRVTableCellData*)RVData,r,c);
  if (r==0)
    return;
  for (r=1; r<table->Rows->Count; r++)
  {
    if (table->Cells[r][0]->Color==SELCOLOR)
      AnsweredCount--;
    table->Cells[r][0]->Color = clNone;
  }
  ((TRVTableCellData*)RVData)->Color = SELCOLOR;
  AnsweredCount++;
  RVData->Invalidate();
  if (HighlightedRVData==RVData)
    HighlightedRVData = NULL;
  if (AnsweredCount==QUESTIONCOUNT)
    RVStyle1->TextStyles->Items[2]->HoverBackColor = PASSCOLOR;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  randomize();
  BuildQuiz();
}
//---------------------------------------------------------------------------
// OnMouseMove event - highlighting cell
void __fastcall TForm1::RichView1MouseMove(TObject *Sender, TShiftState Shift,
	int X, int Y)
{
  TCustomRVFormattedData* RVData;
  int a,b;
  if (Ready)
    return;
  X += RichView1->HScrollPos;
  Y += RichView1->VScrollPos*RichView1->VSmallStep;
  RichView1->GetItemAt(X, Y, RVData, a, b, false);
  HighlightCell(RVData);
}
//---------------------------------------------------------------------------
// OnRVMouseUp event - selecting cell
void __fastcall TForm1::RichView1RVMouseUp(TCustomRichView *Sender,
	TMouseButton Button, TShiftState Shift, int ItemNo, int X, int Y)
{
  TCustomRVFormattedData* RVData;
  int a,b;
  if (Ready)
    return;
  X += RichView1->HScrollPos;
  Y += RichView1->VScrollPos*RichView1->VSmallStep;
  RichView1->GetItemAt(X, Y, RVData, a, b, false);
  SelectCell(RVData);
}
//---------------------------------------------------------------------------
// On hyperlink click.
void __fastcall TForm1::RichView1Jump(TObject *Sender, int id)
{
  if (!Ready)
  { // clicking on "Ready!"
    if (AnsweredCount<QUESTIONCOUNT)
    {
      MessageBeep(0);
      return;
    }
    Ready = true;
    HighlightCell(RichView1->RVData);
    int Score = 0;
    for (int i = 0; i< RichView1->ItemCount; i++)
      if (RichView1->GetItemStyle(i)==rvsTable)
      {
        TRVTableItemInfo* table = (TRVTableItemInfo*)(RichView1->GetItem(i));
         for (int r=1; r<table->Rows->Count; r++)
           if (table->Cells[r][0]->Color==SELCOLOR)
           {
             if (IntToStr(r-1)==RichView1->GetItemTextW(i))
             {
               table->Cells[0][0]->AddNLWTag(" (passed)", 1,-1,0);
               table->Cells[r][0]->Color = PASSCOLOR;
               Score++;
             }
             else
             {
               table->Cells[0][0]->AddNLWTag(" (failed)", 1,-1,0);
               table->Cells[r][0]->Color = FAILCOLOR;
             }
             break;
           }
      }
    RichView1->SetItemTextW(RichView1->ItemCount-1, "Try again");
    Caption = Sysutils::Format("PlanetQuiz : %d of %d", ARRAYOFCONST((Score, QUESTIONCOUNT)));
    RichView1->Format();
    RichView1->Update();
    if (Score!=QUESTIONCOUNT)
      PlaySound(L"CHORD.WAV", 0, SND_SYNC | SND_NODEFAULT);
    else
      PlaySound(L"TADA.WAV", 0, SND_SYNC | SND_NODEFAULT);
  }
  else
  {  // clicking on "Try Again"
    BuildQuiz();
    RichView1->ScrollTo(0);
    Caption = "PlanetQuiz";
  }
}
