//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "EditFrm.h"
#include "ecPropManager.hpp"
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ecActns"
#pragma link "ecExtHighlight"
#pragma link "ecSpell"
#pragma link "ecSyntAnal"
#pragma link "ecSyntMemo"
#pragma resource "*.dfm"

//---------------------------------------------------------------------------
__fastcall TEditorFrame::TEditorFrame(TComponent* Owner)
        : TFrame(Owner)
{
  ecSpellChecker1->Dictionary = SyntEditMain->ecDictionary1;
  EditorMaster->OnSetBookmark = EditorMasterSetBookmark;
  EditorSlave->OnSetBookmark = EditorMasterSetBookmark;
}
//---------------------------------------------------------------------------
TSyntaxMemo* __fastcall TEditorFrame::CurrentMemo()
{
  if( EditorSlave->Visible && EditorSlave->Focused() )
    return EditorSlave;
  else
    return EditorMaster;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::ToggleBookmark(TObject *Sender)
{
  CurrentMemo()->ToggleBookmark(((TComponent*)Sender)->Tag);
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::GotoBookmark(TObject *Sender)
{
  CurrentMemo()->GotoBookmark(((TComponent*)Sender)->Tag);
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::PopupMenu1Popup(TObject *Sender)
{
  for(int i = 0; i < 10; i++)
   for(int j = 1; j <= 2; j++)
    ((TMenuItem*)FindComponent("Bookmark"+IntToStr(i)+IntToStr(j)))->Checked =
      CurrentMemo()->Bookmarks[i] != -1;
  bool b = ecSpellChecker1->Dictionary &&
           (!ecSpellChecker1->HltRangeAt(CurrentMemo()->CaretStrPos).IsEmpty());
  N4->Visible = b;
  N5->Visible = b;
  N6->Visible = b;
  if( b )
   {
    N4->Enabled = ecSpellChecker1->Dictionary->SkippedDictionary->Active;
    N5->Enabled = ecSpellChecker1->Dictionary->UserDictionary->Active;
   }
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterEnter(TObject *Sender)
{
  SyntEditMain->CurrentEditor = (TSyntaxMemo*)Sender;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterSetBookmark(TObject *Sender,
  Ecsyntmemo::TBookmark *Bookmark, bool &Accept)
{
   if (Bookmark->BmIndex >= 0 && Bookmark->BmIndex < 10)
    {
     Bookmark->ImageIndex = 13 + Bookmark->BmIndex;
     Bookmark->Hint = "Bookmark " + IntToStr(Bookmark->BmIndex);
    }
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::SetFileName(const AnsiString Value)
{
  FFileName = Value;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::SaveFile(const AnsiString AFileName)
{
#ifdef EC_UNICODE
      if (TextSource->Lines->TextCoding == tcAnsi &&  TextSource->Lines->ContainUnicode() &&
         MessageBox(Handle, "Text contains Unicode characters-> Would you like to save text in Unicode format?",
          "Warning", MB_ICONWARNING | MB_YESNO) == IDYES)
        TextSource->Lines->TextCoding = tcUnicode;
#endif
      EditorMaster->SaveToFile(AFileName);
      EditorSlave->Modified = False;
      FFileName = AFileName;
      TitleChanged();
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::LoadFile(const AnsiString AFileName)
{
  EditorMaster->LoadFromFile(AFileName);
  EditorSlave->Modified = False;
  FFileName = ExpandFileName(AFileName);
  TitleChanged();
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::FrameResize(TObject *Sender)
{
  if(!EditorSlave->Visible || EditorSlave->Height == 0)
    EditorSlave->Top = 0;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::SplitterMouseDown(TObject *Sender,
  TMouseButton Button, TShiftState Shift, int X, int Y)
{
  FrameResize(this);
}
//---------------------------------------------------------------------------
bool __fastcall TEditorFrame::GetModified()
{
  return EditorSlave->Modified || EditorMaster->Modified;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::SetModified(const bool Value)
{
  EditorSlave->Modified = Value;
  EditorMaster->Modified = Value;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TEditorFrame::GetTitle()
{
  AnsiString Res;
  if(FFileName == "")
    Res = "Untitled";
  else
    Res = ExtractFileName(FFileName);
  if(Modified)
    Res = Res + "*";
  FPrevMod = Modified;
  return Res;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::TitleChanged()
{
  if(Parent)
  {
    if(Parent->InheritsFrom(__classid(TTabSheet)))
      ((TTabSheet*)Parent)->Caption = Title;
    if(Parent->InheritsFrom(__classid(TForm)))
      ((TForm*)Parent)->Caption = Title;
  }
  if( FOnTitleChanged )
    FOnTitleChanged(this);
}
//---------------------------------------------------------------------------
bool __fastcall TEditorFrame::IsTheFile(const AnsiString AFileName)
{
  // To use MS CharUpper
  if(FFileName.Length() != AFileName.Length() || FFileName.Length() == 0)
    return false;

  AnsiString s1 = FFileName.SubString(1, FFileName.Length());
  AnsiString s2 = AFileName.SubString(1, AFileName.Length());
  return !IsNewFile() &&
        (AnsiString(CharUpper(s1.c_str())) ==
         AnsiString(CharUpper(s2.c_str())));
}
//---------------------------------------------------------------------------
bool __fastcall TEditorFrame::IsNewFile()
{
  return FFileName == "";
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterGetTokenHint(TObject *Sender,
  int TokenIndex, AnsiString &HintText)
{
// This example show how to get token information and use it for hint showing
  TClientSyntAnalyzer *so = ((TSyntaxMemo*)Sender)->SyntObj;
  if(!so) return;

  HintText = "Token:      " + so->TagStr[TokenIndex] + sLineBreak;
  if(HintText.Length() > 100) HintText = "";
  HintText = HintText +
             "Rule:       " + so->Tags[TokenIndex]->Rule->DisplayName + sLineBreak +
             "Position: " + IntToStr(TokenIndex);
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterChange(TObject *Sender)
{
  if(!FPrevMod) TitleChanged();
  SyntEditMain->UpdateStatusBar(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterCaretPosChanged(TObject *Sender)
{
  SyntEditMain->UpdateStatusBar(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorSlaveGetStyleEntry(TObject *Sender,
  int CurPos, TStyleEntries* StyleList, int &NextPos)
{
  NextPos = ecSpellChecker1->GetStyleList(CurPos, StyleList);
  int tmp = HyperlinkHighlighter1->GetStyleList(CurPos, StyleList);
  if(tmp != -1 && tmp < NextPos || NextPos == -1)
    NextPos = tmp;
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::N4Click(TObject *Sender)
{
  if( ecSpellChecker1->AddToDictionary(ecSpellChecker1->HltRangeAt(CurrentMemo()->CaretStrPos),
         (TecDictionaryWords*)((int)SKIP_DICTIONARY)) )
   {
     EditorMaster->Invalidate();
     EditorSlave->Invalidate();
   }
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::N5Click(TObject *Sender)
{
  if( ecSpellChecker1->AddToDictionary(ecSpellChecker1->HltRangeAt(CurrentMemo()->CaretStrPos),
         (TecDictionaryWords*)USER_DICTIONARY) )
   {
     EditorMaster->Invalidate();
     EditorSlave->Invalidate();
   }
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterGetLineNumberStr(TObject *Sender,
  int Line, AnsiString &NumberStr)
{
  if(div(Line + 1, 10).rem == 0 ||
     EditorMaster->Collapsed->GetCollapsedIndex(Line) != -1 ||
     Line == EditorMaster->CaretPos.y)
    NumberStr = IntToStr(Line + 1);
  else
  if(div(Line + 1, 5).rem == 0)
    NumberStr = "-";
  else
    NumberStr = ".";
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::EditorMasterGetGutterImage(TObject *Sender,
  const int Line, TList* List)
{
  TSyntaxMemo *Memo = EditorMaster;
  if(Memo->SelLength > 0 &&
     Line == Memo->StrPosToCaretPos(Memo->SelStart + Memo->SelLength).y)
   {
    TGutterObject *gi = new TGutterObject(0);
    gi->OnClick = SyncEditClick;
    gi->ImageIndex = 58;
    gi->Hint = "Create sync range";
    List->Add(gi);
    return;
   }
  if(Memo->SyncEditing->RangeEndAtLine(Line) != -1)
   {
    TGutterObject *gi = new TGutterObject(0);
    gi->ImageIndex = 59;
    gi->Hint = "Remove sync range";
    gi->OnClick = SyncEditClick;
    List->Add(gi);
    return;
   }
}
//---------------------------------------------------------------------------
void __fastcall TEditorFrame::SyncEditClick(TObject *Sender, int Line,
  TShiftState Shift)
{
  if(EditorMaster->SelLength > 0)
    EditorMaster->SyncEditing->AddCurSelection();
  else
   {
    int idx = EditorMaster->SyncEditing->RangeEndAtLine(Line);
    if(idx != -1)
      EditorMaster->SyncEditing->Delete(idx);
   }
}
//---------------------------------------------------------------------------


