unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, JvExStdCtrls, JvRichEdit, Menus, ShellApi,
  ExtCtrls, AppEvnts;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    ButtonTestBegin: TButton;
    Label3: TLabel;
    ListBoxTests: TListBox;
    ButtonTestCreate: TButton;
    ButtonTestEdit: TButton;
    ButtonTestDel: TButton;
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    Panel1: TPanel;
    Panel2: TPanel;
    Label1: TLabel;
    ListBoxTopics: TListBox;
    ListBoxTopicsLink: TListBox;
    ButtonTopicCreate: TButton;
    ButtonTopicEdit: TButton;
    ButtonTopicDel: TButton;
    ButtonTopicUp: TButton;
    ButtonTopicDown: TButton;
    JvRichEditTopicLink: TJvRichEdit;
    Label2: TLabel;
    Splitter1: TSplitter;
    ButtonLinkAdd: TButton;
    ButtonLinkSave: TButton;
    ButtonTestUp: TButton;
    ButtonTestDown: TButton;
    ListBoxTestsFile: TListBox;
    MemoTest: TMemo;
    ApplicationEvents1: TApplicationEvents;
    TabSheet4: TTabSheet;
    Label4: TLabel;
    Label8: TLabel;
    GroupBox1: TGroupBox;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    EditLogin: TEdit;
    EditPass1: TEdit;
    EditPass2: TEdit;
    ButtonOKLogin: TButton;
    ButtonEndEdit: TButton;
    MemoRes: TMemo;
    ButtonTestBegin2: TButton;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure ButtonTopicCreateClick(Sender: TObject);
    procedure ButtonTopicEditClick(Sender: TObject);
    procedure ButtonTopicDelClick(Sender: TObject);
    procedure ButtonTopicUpClick(Sender: TObject);
    procedure ButtonTopicDownClick(Sender: TObject);
    procedure ListBoxTopicsClick(Sender: TObject);
    procedure ButtonLinkSaveClick(Sender: TObject);
    procedure N1Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure ButtonLinkAddClick(Sender: TObject);
    procedure JvRichEditTopicLinkURLClick(Sender: TObject;
      const URLText: String; Button: TMouseButton);
    procedure ButtonTestBeginClick(Sender: TObject);
    procedure ButtonTestCreateClick(Sender: TObject);
    procedure ButtonTestEditClick(Sender: TObject);
    procedure ButtonTestDelClick(Sender: TObject);
    procedure ButtonTestUpClick(Sender: TObject);
    procedure ButtonTestDownClick(Sender: TObject);
    procedure ListBoxTestsClick(Sender: TObject);
    procedure ButtonOKLoginClick(Sender: TObject);
    procedure ButtonEndEditClick(Sender: TObject);
    procedure ApplicationEvents1Deactivate(Sender: TObject);
    procedure ApplicationEvents1Minimize(Sender: TObject);
    procedure ButtonTestBegin2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Editing : Boolean; // в режиме редактирования
    
    procedure SaveTopic(); // сохранить тему
    procedure SaveTest(); // сохранить тест


  end;

var
  Form1: TForm1;

implementation

uses
  UnitBegin, UnitEnd, UnitEditStr, UnitAddLink, StrUtils, UnitTest;

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
  FormBegin.ShowModal;
  // название главной формы так же как у приложения
  Caption := Application.Title;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  tf : TFormEnd;
  fn : string;
begin
  SaveTopic(); // сохранить тему
  SaveTest(); // сохранить тест

  // сохраним результаты тестирования
  fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\sys.bin';
  MemoRes.Lines.SaveToFile( fn );


  Form1.Hide;
  tf := TFormEnd.Create( Form1 );
  tf.ShowModal;
  tf.Free;
end;

procedure TForm1.SaveTopic(); // сохранить тему
var
  fn : String;
begin
  Screen.Cursor := crHourGlass;
  try
    fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\topics.sys';
    ListBoxTopics.Items.SaveToFile( fn );
    fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\topicsLink.sys';
    ListBoxTopicsLink.Items.SaveToFile( fn );
    if ListBoxTopics.ItemIndex >= 0 then
    begin
      fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\'
        + ListBoxTopicsLink.Items.Strings[ ListBoxTopics.ItemIndex ];
      JvRichEditTopicLink.Lines.SaveToFile( fn );
    end;

  finally
    Screen.Cursor := crDefault;
  end;

end;

procedure TForm1.SaveTest(); // сохранить тест
var
  fn : String;
begin
  Screen.Cursor := crHourGlass;
  try
    fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\tests.sys';
    ListBoxTests.Items.SaveToFile( fn );
    fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\testsFile.sys';
    ListBoxTestsFile.Items.SaveToFile( fn );

    if ListBoxTests.ItemIndex >= 0 then
    begin
      fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\'
        + ListBoxTestsFile.Items.Strings[ ListBoxTests.ItemIndex ];
      MemoTest.Lines.SaveToFile( fn );
    end;

  finally
    Screen.Cursor := crDefault;
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  fn : String;
begin
  PageControl1.ActivePageIndex := 0;
  Editing := false; // в режиме редактирования

  ButtonTestBegin2.Top := ButtonTestBegin.Top;
  ButtonTestBegin2.Left := ButtonTestBegin.Left + ButtonTestBegin.Width + 50;


  fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\topics.sys';
  if FileExists( fn ) then
  begin
    ListBoxTopics.Items.LoadFromFile( fn );
  end
  else
  begin
    MessageBox(Handle, 'Отсутствует системный файл "topics.sys".', 'Ошибка!', MB_OK +
      MB_ICONSTOP);
    Application.Terminate; // выход из приложения с разрушением программы
  end;

  fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\topicsLink.sys';
  if FileExists( fn ) then
  begin
    ListBoxTopicsLink.Items.LoadFromFile( fn );
  end
  else
  begin
    MessageBox(Handle, 'Отсутствует системный файл "topicsLink.sys".', 'Ошибка!', MB_OK +
      MB_ICONSTOP);
    Application.Terminate; // выход из приложения с разрушением программы
  end;

  fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\tests.sys';
  if FileExists( fn ) then
  begin
    ListBoxTests.Items.LoadFromFile( fn );
  end
  else
  begin
    MessageBox(Handle, 'Отсутствует системный файл "tests.sys".', 'Ошибка!', MB_OK +
      MB_ICONSTOP);
    Application.Terminate; // выход из приложения с разрушением программы
  end;

  fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\testsFile.sys';
  if FileExists( fn ) then
  begin
    ListBoxTestsFile.Items.LoadFromFile( fn );
  end
  else
  begin
    MessageBox(Handle, 'Отсутствует системный файл "testsFile.sys".', 'Ошибка!', MB_OK +
      MB_ICONSTOP);
    Application.Terminate; // выход из приложения с разрушением программы
  end;

  fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\sys.bin';
  if FileExists( fn ) then
  begin
    MemoRes.Lines.LoadFromFile( fn );
  end
  else
  begin
    MessageBox(Handle, 'Отсутствует системный файл "sys.bin".', 'Ошибка!', MB_OK +
      MB_ICONSTOP);
    Application.Terminate; // выход из приложения с разрушением программы
  end;

end;

procedure TForm1.ButtonTopicCreateClick(Sender: TObject);
begin
  // Создать тему
  FormEditStr.Caption := 'Создать тему';
  FormEditStr.Label1.Caption := 'Название темы:';
  FormEditStr.Edit1.Text := '';

  if FormEditStr.ShowModal = mrOk then
  begin
    SaveTopic(); // сохранить тему
    ListBoxTopics.Items.Add( Trim( FormEditStr.Edit1.Text ) );
    ListBoxTopicsLink.Items.Add( 'topic_' + IntToStr(ListBoxTopics.Items.Count) + '.sys' );
  end;

end;

procedure TForm1.ButtonTopicEditClick(Sender: TObject);
begin
  // Редактировать тему
  if ListBoxTopics.ItemIndex >= 0 then
  begin
    FormEditStr.Caption := 'Редактировать тему';
    FormEditStr.Label1.Caption := 'Название темы:';
    FormEditStr.Edit1.Text := ListBoxTopics.Items.Strings[ ListBoxTopics.ItemIndex ];

    if FormEditStr.ShowModal = mrOk then
    begin
      SaveTopic(); // сохранить тему
      ListBoxTopics.Items.Strings[ ListBoxTopics.ItemIndex ] := Trim(FormEditStr.Edit1.Text);
    end;
  end;
end;

procedure TForm1.ButtonTopicDelClick(Sender: TObject);
var
  ind : Integer;
begin
  // Удалить тему
  ind := ListBoxTopics.ItemIndex;
  if ind >= 0 then
  begin
    if MessageBox(Handle, 'Удалить тему?', 'Внимание!', MB_OKCANCEL +
      MB_ICONQUESTION) = IDOK then
    begin
      ListBoxTopics.Items.Delete( ind );
      ListBoxTopicsLink.Items.Delete( ind );
      SaveTopic(); // сохранить тему
    end;
  end;
end;

procedure TForm1.ButtonTopicUpClick(Sender: TObject);
var
  ind : Integer;
begin
  // Тему вверх
  ind := ListBoxTopics.ItemIndex;
  if ind >= 0 then
  begin
    if ind > 0 then
    begin
      SaveTopic(); // сохранить тему
      ListBoxTopics.Items.Exchange( ind, ind-1 );
      ListBoxTopicsLink.Items.Exchange( ind, ind-1 );
      ListBoxTopics.ItemIndex := ind-1;
    end;
  end;
end;

procedure TForm1.ButtonTopicDownClick(Sender: TObject);
var
  ind : Integer;
begin
  // Тему вниз
  ind := ListBoxTopics.ItemIndex;
  if ind >= 0 then
  begin
    if ind < ListBoxTopics.Items.Count-1 then
    begin
      SaveTopic(); // сохранить тему
      ListBoxTopics.Items.Exchange( ind, ind+1 );
      ListBoxTopicsLink.Items.Exchange( ind, ind+1 );
      ListBoxTopics.ItemIndex := ind+1;
    end;
  end;
end;

procedure TForm1.ListBoxTopicsClick(Sender: TObject);
var
  fn : String;
begin
  // показать линки
  if ListBoxTopics.ItemIndex >= 0 then
  begin
    fn := ExtractFilePath( Application.ExeName ) + 'System\Topics\'
      + ListBoxTopicsLink.Items.Strings[ ListBoxTopics.ItemIndex ];
    if FileExists( fn ) then
    begin
      JvRichEditTopicLink.Lines.LoadFromFile( fn );
    end
    else
    begin
      JvRichEditTopicLink.Lines.Clear;
    end;

  end;

end;

procedure TForm1.ButtonLinkSaveClick(Sender: TObject);
begin
  // Сохранить тему
  SaveTopic(); // сохранить тему
end;

procedure TForm1.N1Click(Sender: TObject);
begin
  // Добавить ссылку на теорию...
  ButtonLinkAddClick(self);
end;

procedure TForm1.N3Click(Sender: TObject);
begin
  // Сохранить
  ButtonLinkSaveClick(self);
end;

procedure TForm1.ButtonLinkAddClick(Sender: TObject);
begin
  // Добавить ссылку на теорию
  if JvRichEditTopicLink.ReadOnly = False then
  begin
    if FormAddLink.ShowModal = mrOk then
    begin
      if FormAddLink.RadioButton1.Checked then
        JvRichEditTopicLink.SelText := FormAddLink.EditHtml.Text
      else
        JvRichEditTopicLink.SelText := FormAddLink.EditHtml2.Text;
    end;
  end;


end;

procedure TForm1.JvRichEditTopicLinkURLClick(Sender: TObject;
  const URLText: String; Button: TMouseButton);
var
  lenURL, pz : Integer;
  url, url8, urlP : string;
begin
  // нажали на ссылку

  //ShellExecute(0, 'open', PChar(URLText), nil, nil, SW_SHOWNORMAL);
  //ShellExecute(Application.Handle, 'explore', PChar(URLText), nil, nil, SW_SHOWNORMAL);



  lenURL := Length( URLText );
  if lenURL >= 8 then
  begin
    url8 := LeftStr(URLText, 8);
    // если локальная на каталог System в котором файл PDF
    if url8 = 'file:///' then
    begin
      // избавляемся от 'file:///'
      url := URLText;
      Delete(url, 1, 8);
      pz := PosEx('#page=', url);
      // если #page= указан, то параметр страницы нужен
      if pz > 0 then
      begin
        urlP := '/A "page=' + MidStr(url, pz+6, Length(url)-pz-5)
          + '"';
        urlP := urlP + ' "' + ExtractFilePath( Application.ExeName ) + 'System\'
            + LeftStr(url, pz-1) + '"';
      end
      else
      begin
        urlP := '/A "page=1"';
        urlP := urlP + ' "' + ExtractFilePath( Application.ExeName ) + 'System\'
            + url + '"';
      end;

      ShellExecute(0, 'open', 'Acrobat.exe', PChar(urlP), nil, SW_SHOWNORMAL);
    end
    else // иначе гиперссылка
    begin
      ShellExecute(0, 'open', PChar(URLText), nil, nil, SW_SHOWNORMAL);
    end;


  end;


end;

procedure TForm1.ButtonTestBeginClick(Sender: TObject);
var
  res, bl : String;
  nv, pr : Integer;
begin
  // НАЧАТЬ ТЕСТИРОВАНИЕ
  if ListBoxTests.ItemIndex > -1 then
  begin
    FormTest.obTest := False; // обучающее тестирование
    FormTest.ShowModal;
    if Editing then
    begin
      SaveTest(); // сохранить тест
    end
    else
    begin
      // запишем результаты 
      res := FormTest.res;
      MemoRes.Lines.Insert(0, '');
      MemoRes.Lines.Text := res + #13#10 + MemoRes.Lines.Text;
      // сообщим результат пользователю
      bl := 'Ваш балл за тест = ' + IntToStr(FormTest.bal) + '%';
      MessageBox(Handle, PChar(bl), 'Внимание!',
        MB_OK + MB_ICONINFORMATION);
    end;
  end
  else
  begin
    MessageBox(Handle, 'Вы не выбрали тест!', 'Внимание!', MB_OK + 
      MB_ICONSTOP); 
  end;



end;

procedure TForm1.ButtonTestCreateClick(Sender: TObject);
begin
  // Создать тест
  FormEditStr.Caption := 'Создать тест';
  FormEditStr.Label1.Caption := 'Название теста:';
  FormEditStr.Edit1.Text := '';

  if FormEditStr.ShowModal = mrOk then
  begin
    SaveTest(); // сохранить тест
    ListBoxTests.Items.Add( Trim( FormEditStr.Edit1.Text ) );
    ListBoxTestsFile.Items.Add( 'test_' + IntToStr(ListBoxTests.Items.Count) + '.sys' );
  end;

end;

procedure TForm1.ButtonTestEditClick(Sender: TObject);
begin
  // Редактировать тест
  if ListBoxTests.ItemIndex >= 0 then
  begin
    FormEditStr.Caption := 'Редактировать тест';
    FormEditStr.Label1.Caption := 'Название теста:';
    FormEditStr.Edit1.Text := ListBoxTests.Items.Strings[ ListBoxTests.ItemIndex ];

    if FormEditStr.ShowModal = mrOk then
    begin
      SaveTest(); // сохранить тест
      ListBoxTests.Items.Strings[ ListBoxTests.ItemIndex ] := Trim(FormEditStr.Edit1.Text);
    end;
  end;
end;

procedure TForm1.ButtonTestDelClick(Sender: TObject);
var
  ind : Integer;
begin
  // Удалить тест
  ind := ListBoxTests.ItemIndex;
  if ind >= 0 then
  begin
    if MessageBox(Handle, 'Удалить тест?', 'Внимание!', MB_OKCANCEL +
      MB_ICONQUESTION) = IDOK then
    begin
      ListBoxTests.Items.Delete( ind );
      ListBoxTestsFile.Items.Delete( ind );
      SaveTest(); // сохранить тест
    end;
  end;
end;

procedure TForm1.ButtonTestUpClick(Sender: TObject);
var
  ind : Integer;
begin
  // Тест вверх
  ind := ListBoxTests.ItemIndex;
  if ind >= 0 then
  begin
    if ind > 0 then
    begin
      SaveTest(); // сохранить тест
      ListBoxTests.Items.Exchange( ind, ind-1 );
      ListBoxTestsFile.Items.Exchange( ind, ind-1 );
      ListBoxTests.ItemIndex := ind-1;
    end;
  end;
end;

procedure TForm1.ButtonTestDownClick(Sender: TObject);
var
  ind : Integer;
begin
  // Тест вниз
  ind := ListBoxTests.ItemIndex;
  if ind >= 0 then
  begin
    if ind < ListBoxTests.Items.Count-1 then
    begin
      SaveTest(); // сохранить тест
      ListBoxTests.Items.Exchange( ind, ind+1 );
      ListBoxTestsFile.Items.Exchange( ind, ind+1 );
      ListBoxTests.ItemIndex := ind+1;
    end;
  end;
end;

procedure TForm1.ListBoxTestsClick(Sender: TObject);
var
  fn : String;
begin
  // загрузить файл
  if ListBoxTests.ItemIndex >= 0 then
  begin
    fn := ExtractFilePath( Application.ExeName ) + 'System\Tests\'
      + ListBoxTestsFile.Items.Strings[ ListBoxTests.ItemIndex ];
    if FileExists( fn ) then
    begin
      MemoTest.Lines.LoadFromFile( fn );
    end
    else
    begin
      MemoTest.Lines.Clear;
    end;

  end;

end;

procedure TForm1.ButtonOKLoginClick(Sender: TObject);
begin
  // Ок ввода логина и пароля

  // проверка, на равенство паролей
  if EditPass1.Text <> EditPass2.Text then
  begin
    MessageBox(Handle, 'Введенные пароли не совпали. Повторите ввод паролей!', 
      'Внимание!', MB_OK + MB_ICONSTOP);
    EditPass1.SetFocus;
    EditPass1.SelectAll;
    Exit;
  end;

  // проверка на логин pdd и пароль pdd2021
  if (EditLogin.Text = 'pdd') AND (EditPass1.Text = 'pdd2021') AND (EditPass2.Text = 'pdd2021') then
  begin
    // если пароль и логин совпал, то в редактирование
    Editing := True; // в режиме редактирования
    // название главной формы так же как у приложения и сообщение, что в редактировании
    Caption := Application.Title + ' - РЕЖИМ РЕДАКТИРОВАНИЯ';
    // видимость разных кнопок
    ButtonTopicCreate.Visible := Editing;
    ButtonTopicEdit.Visible := Editing;
    ButtonTopicDel.Visible := Editing;
    ButtonTopicUp.Visible := Editing;
    ButtonTopicDown.Visible := Editing;
    ButtonLinkAdd.Visible := Editing;
    ButtonLinkSave.Visible := Editing;
    JvRichEditTopicLink.ReadOnly := not Editing;
    ButtonTestCreate.Visible := Editing;
    ButtonTestEdit.Visible := Editing;
    ButtonTestDel.Visible := Editing;
    ButtonTestUp.Visible := Editing;
    ButtonTestDown.Visible := Editing;
    ButtonEndEdit.Visible := Editing;
    ButtonTestBegin2.Visible := not Editing;
    if Editing then
    begin
      ListBoxTopics.Height := ListBoxTopics.Height - 32;
      ButtonTestBegin.Caption := 'Редактировать вопросы';
    end
    else
    begin
      ListBoxTopics.Height := ListBoxTopics.Height + 32;
      ButtonTestBegin.Caption := 'НАЧАТЬ ТЕСТИРОВАНИЕ';
    end;
    GroupBox1.Enabled := not Editing;
    // сотрем пароль и логин
    EditLogin.Text := '';
    EditPass1.Text := '';
    EditPass2.Text := '';
    MessageBox(Handle, 'Включен режим редактрирования!', 'Внимание!', MB_OK + 
      MB_ICONINFORMATION);  
  end
  else
  begin
    MessageBox(Handle, 'Логин или пароль не верен!', 'Внимание!', MB_OK + 
      MB_ICONSTOP);
  end;


end;

procedure TForm1.ButtonEndEditClick(Sender: TObject);
begin
  // ОТМЕНИТЬ РЕДАКТИРОВАНИЕ
  Editing := False; // в режиме редактирования
  // название главной формы так же как у приложения
  Caption := Application.Title;
  // видимость разных кнопок
  ButtonTopicCreate.Visible := Editing;
  ButtonTopicEdit.Visible := Editing;
  ButtonTopicDel.Visible := Editing;
  ButtonTopicUp.Visible := Editing;
  ButtonTopicDown.Visible := Editing;
  ButtonLinkAdd.Visible := Editing;
  ButtonLinkSave.Visible := Editing;
  JvRichEditTopicLink.ReadOnly := not Editing;
  ButtonTestCreate.Visible := Editing;
  ButtonTestEdit.Visible := Editing;
  ButtonTestDel.Visible := Editing;
  ButtonTestUp.Visible := Editing;
  ButtonTestDown.Visible := Editing;
  ButtonEndEdit.Visible := Editing;
  ButtonTestBegin2.Visible := not Editing;
  if Editing then
  begin
    ListBoxTopics.Height := ListBoxTopics.Height - 32;
    ButtonTestBegin.Caption := 'Редактировать вопросы';
  end
  else
  begin
    ListBoxTopics.Height := ListBoxTopics.Height + 32;
    ButtonTestBegin.Caption := 'НАЧАТЬ ТЕСТИРОВАНИЕ';
  end;
  GroupBox1.Enabled := not Editing;


end;

procedure TForm1.ApplicationEvents1Deactivate(Sender: TObject);
begin
  // если не в режиме редактирования и идет тест, то завершаем его
  if not Editing and FormTest.Visible then
  begin
    FormTest.BitBtnTestBreakClick(self);
  end;

end;

procedure TForm1.ApplicationEvents1Minimize(Sender: TObject);
begin
  // если не в режиме редактирования и идет тест, то завершаем его
  if not Editing and FormTest.Visible then
  begin
    FormTest.BitBtnTestBreakClick(self);
  end;
end;

procedure TForm1.ButtonTestBegin2Click(Sender: TObject);
begin
  // ОБУЧАЮЩЕЕ ТЕСТИРОВАНИЕ
  if ListBoxTests.ItemIndex > -1 then
  begin
    FormTest.obTest := True; // обучающее тестирование
    FormTest.ShowModal;
  end
  else
  begin
    MessageBox(Handle, 'Вы не выбрали тест!', 'Внимание!', MB_OK + 
      MB_ICONSTOP); 
  end;

end;

end.
