unit fGNEncounter;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, ExtCtrls, ComCtrls, ORCtrls, fMainFrame, StdCtrls, ORDtTm,
  fPage, ORFn, uPCE, rPCE, uCore, rCore, uTIU, rTIU, uConst, rConsults,
  Menus, ToolWin, ActnList, fAddlSigners, System.Actions;

type
  TfrmGNEncounter = class(TFrmPage)
    pnlLeft: TPanel;
    lstPatients: TListBox;
    Splitter1: TSplitter;
    pnlRight: TPanel;
    pnlEncounter: TPanel;
    txtPCEData: TRichEdit;
    pnlNote: TPanel;
    lblEnctInfo: TLabel;
    pnlBottom: TPanel;
    pnlBaseNote: TPanel;
    lblBaseNoteInfo: TLabel;
    memCommNote: TRichEdit;
    Splitter2: TSplitter;
    pnlSingleNotes: TPanel;
    lblIndvNoteInfo: TLabel;
    memIndvNote: TRichEdit;
    popMenu1: TPopupMenu;
    pm1GrammarCheck: TMenuItem;
    pm1Spellcheck: TMenuItem;
    popMenu2: TPopupMenu;
    pm2SpellCheck: TMenuItem;
    pm2GrammarCheck: TMenuItem;
    MainMenu1: TMainMenu;
    mnBacktoPatientSelection: TMenuItem;
    StartNewGroupPatients1: TMenuItem;
    ActList: TActionList;
    actNewNote: TAction;
    actChangeNote: TAction;
    actSaveNoSig: TAction;
    actSignNote: TAction;
    actForAllPatients: TAction;
    actNewEncounter: TAction;
    actEditEncounter: TAction;
    CoolBar1: TCoolBar;
    ToolBar1: TToolBar;
    tbAllPatients: TToolButton;
    ToolButton1: TToolButton;
    tbNewNote: TToolButton;
    tbChangeNote: TToolButton;
    tbSaveNoSig: TToolButton;
    tbSignNote: TToolButton;
    tbNewEncounter: TToolButton;
    tbEditEncounter: TToolButton;
    pnlBasicEncounter: TPanel;
    lblBasicEnct: TLabel;
    lblSignature: TLabel;
    tbAdditionalSigner: TToolButton;
    Panel1: TPanel;
    btnBasicEnct: TButton;
    mnAction: TMenuItem;
    mnNewProgressNote: TMenuItem;
    mnChangeTitle: TMenuItem;
    mnSavewithoutSignature: TMenuItem;
    mnSignNoteNow: TMenuItem;
    mnIdentifyAdditionalSigners: TMenuItem;
    mnNewEncounter: TMenuItem;
    mnEditEncounter: TMenuItem;
    N1: TMenuItem;
    N2: TMenuItem;
    pm2NewProgressNote: TMenuItem;
    pm2ChangeTitle: TMenuItem;
    pm2NewEncounter: TMenuItem;
    pm2EditEncounter: TMenuItem;
    pm2SavewithoutSignature: TMenuItem;
    pm2SignNoteNow: TMenuItem;
    pm2IdentifyAdditionalSigner: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    pm1NewProgressNote: TMenuItem;
    pm1ChangeTitle: TMenuItem;
    pm1NewEncounter: TMenuItem;
    pm1EditEncounter: TMenuItem;
    pm1SavewithoutSignature: TMenuItem;
    pm1SignNotesNow: TMenuItem;
    pm1IdentifyAdditionalSigner: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    mnForAllPatients: TMenuItem;
    N7: TMenuItem;
    pm2ForAllPatients: TMenuItem;
    N8: TMenuItem;
    pm1ForAllPatients: TMenuItem;
    N9: TMenuItem;
    popMenu3: TPopupMenu;
    pm3ForAllPatients: TMenuItem;
    MenuItem2: TMenuItem;
    pm3NewNote: TMenuItem;
    pm3ChangeTitle: TMenuItem;
    MenuItem7: TMenuItem;
    pm3NewEncounter: TMenuItem;
    pm3EditEncounter: TMenuItem;
    MenuItem10: TMenuItem;
    pm3SaveWithoutSignature: TMenuItem;
    pm3SignNote: TMenuItem;
    pm3IdentifyAdditionalSigner: TMenuItem;
    actIdentifyAdditionalSigner: TAction;
    btnPrev: TBitBtn;
    btnStartOver: TBitBtn;
    btnExit: TBitBtn;
    N10: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure lstPatientsDrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure FormShow(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure lstPatientsClick(Sender: TObject);
    procedure pnlAllPatientsClick(Sender: TObject);
    procedure btnPrevClick(Sender: TObject);
    procedure memCommNoteExit(Sender: TObject);
    procedure memIndvNoteExit(Sender: TObject);
    procedure btnStartOverClick(Sender: TObject);
    procedure pm1SpellcheckClick(Sender: TObject);
    procedure pm1GrammarCheckClick(Sender: TObject);
    procedure pm2GrammarCheckClick(Sender: TObject);
    procedure pm2SpellCheckClick(Sender: TObject);
    procedure actNewNoteExecute(Sender: TObject);
    procedure actForAllPatientsExecute(Sender: TObject);
    procedure actChangeNoteExecute(Sender: TObject);
    procedure actSignNoteExecute(Sender: TObject);
    procedure actNewEncounterExecute(Sender: TObject);
    procedure memCommNoteEnter(Sender: TObject);
    procedure memIndvNoteEnter(Sender: TObject);
    procedure btnBasicEnctClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure actIdentifyAdditionalSignerExecute(Sender: TObject);
    procedure actSaveNoSigExecute(Sender: TObject);
    procedure memCommNoteKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure pnlBaseNoteResize(Sender: TObject);
    procedure pnlSingleNotesResize(Sender: TObject);
  private
    FVerifyNoteTitle: Integer;
    FSignRst: string;
    FChangeNote: boolean;
    FSigned: boolean;
    //PCE section
    procedure RemovePCEFromChanges(IEN: Int64; AVisitStr: string = '');
    procedure UpdateGroupPatientPCEData;
    function EditPCEData(APatientData: TPatientData): boolean;
    //note section
    procedure populatePtList;
    procedure SaveEachNote(APatientData: TPatientData);
    procedure NewNoteForIndividualPatient(APatientData: TPatientData);
    procedure SaveEditedNote(var Saved: boolean; APatientData: TPatientData);
    function LacksRequiredForCreate (ANote: TEditNoteRec): Boolean;
    function VerifyNoteTitle: Boolean;
    function HasAnyNote: boolean;
    function LockNote(AnIEN: Int64): Boolean;
    procedure MakeCommonNoteEnable(TheEnable: boolean);
    procedure MakeIndvNoteEnable(TheEnable: boolean);
    procedure MakeEncounterEnable(TheEnable: boolean);
    procedure ShowBasicEnctInfo;
    procedure AdditionalSignerForSingleNote;
    function NeedTOSign: boolean;
    procedure DeleteCurrentNotes(onlyEmptyNotes: boolean);
    //casecade update through different controls
    procedure NewNote(IsEnable: boolean);
    procedure ChangeNote(IsEnable: boolean);
    procedure NewEncounter(IsEnable: boolean);
    procedure EditEncounter(IsEnable: boolean);
    procedure SignNote(IsEnable: boolean);
    procedure SaveWithoutSign(IsEnable: boolean);
    procedure AdditionalSigner(IsEnable: boolean);
    procedure ForAllPatients(IsEnable: boolean);
    procedure BackToPtSelect(IsEnable: boolean);
    procedure UpdateControlsAfterSign(IsSigned: boolean);
  public
    procedure SetFontSize( FontSize: integer); override;
    function GetPatientData(APatient: TPatient): TPatientData;
    procedure SetPatientData(APatient: TPatient; APCEData: TPCEData; ANote: TEditNoteRec); overload;
    procedure SetPatientData(APatient: TPatient; ANote: TEditNoteRec); overload;
  end;

var
  frmGNEncounter: TfrmGNEncounter;
  SelectedPatient: string; // remember highlighted patient on individual patient edit
  StartOver: boolean;

implementation

uses fEncnt, fNoteProps, fSignItem, fEncounterFrame, fGNPtSel, uSpell, fNoteDR;

{$R *.dfm}
const
  NT_NEW_NOTE = -10;                             // Holder IEN for a new note
  NT_ADDENDUM = -20;                             // Holder IEN for a new addendum

  TX_CREATE_ERR = 'Error Creating Note';
  TX_COSIGN     = 'Cosign Note';
  TX_SIGN       = 'Sign Note';
  TX_AUTH_SIGNED    = 'Author has not signed, are you SURE you want to sign.' +CRLF;
  TX_ABSAVE       = 'It appears the session terminated abnormally when this' + CRLF +
                    'note was last edited. Some text may not have been saved.' + CRLF + CRLF +
                    'Do you wish to continue and sign the note?';
  TX_UNSIGNNOTES  = 'There are unsigned notes for group patients, would you like to sign them?';
  TC_ABSAVE       = 'Possible Missing Text';
  TC_NO_LOCK      = 'Unable to Lock Note';


procedure TfrmGNEncounter.populatePtList;
var
  i: integer;
  APatient: TPatient;
begin
  lstPatients.Clear;
  for i := 0 to GNPtList.Count - 1 do
  begin
    APatient := TPatientData(GNPtList.Items[i]).Patient;
    lstPatients.AddItem(APatient.Name,APatient);
  end;
  if Length(SelectedPatient)>0 then
  begin
    for i := 0 to lstPatients.Items.Count - 1 do
    begin
      if TPatient(lstPatients.Items.Objects[i]).DFN = SelectedPatient then
      begin
        lstPatients.ItemIndex := i;
        lstPatientsClick(Self);
      end;
    end;
  end;

end;

procedure TfrmGNEncounter.lstPatientsDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with (Control as TListBox).Canvas do
  begin
    FillRect(Rect);
    TextOut(Rect.Left,Rect.Top,(Control as TListBox).Items[Index]);
  end;
end;

procedure TfrmGNEncounter.FormShow(Sender: TObject);
begin
  inherited;
  MakeCommonNoteEnable(False);
  MakeIndvNoteEnable(False);
  MakeEncounterEnable(False);
  populatePtList;
  ShowBasicEnctInfo;
  if lstPatients.Items.Count = 1 then   // select the only patient
    begin
      if tbAllPatients.Down then
        actForAllPatientsExecute(lstPatients);
      lstPatients.ItemIndex := 0;
    end
   else
     tbAllPatients.Click;
end;

procedure TfrmGNEncounter.SetFontSize(FontSize: integer);
begin
  inherited;
end;

procedure TfrmGNEncounter.btnExitClick(Sender: TObject);
begin
  inherited;
  frmMainFrame.Close;
end;

procedure TfrmGNEncounter.UpdateGroupPatientPCEData;
var
  i: integer;
begin
  for i := 0 to GNPtlist.Count - 1 do
    BasePCE.CopyPCEData(TPatientData(GNPtList.Items[i]).PCEData);
end;

function TfrmGNEncounter.LacksRequiredForCreate (ANote: TEditNoteRec): Boolean;
var
  CurTitle: Integer;
begin
  Result := False;
  with ANote do
  begin
    if Title <= 0    then Result := True;
    if Author <= 0   then Result := True;
    if DateTime <= 0 then Result := True;
    if IsConsultTitle(Title) and (PkgIEN = 0) then Result := True;
    if (DocType = TYP_ADDENDUM) then
    begin
      if AskCosignerForDocument(Addend, Author) and (Cosigner <= 0) then Result := True;
    end else
    begin
      if Title > 0 then CurTitle := Title else CurTitle := DocType;
      if AskCosignerForTitle(CurTitle, Author) and (Cosigner <= 0) then Result := True;
    end;
  end;
end;

function TfrmGNEncounter.VerifyNoteTitle: Boolean;
const
  VNT_UNKNOWN = 0;
  VNT_NO      = 1;
  VNT_YES     = 2;
var
  AParam: string;
begin
  if FVerifyNoteTitle = VNT_UNKNOWN then
  begin
    AParam := GetUserParam('ORWOR VERIFY NOTE TITLE');
    if AParam = '1' then FVerifyNoteTitle := VNT_YES else FVerifyNoteTitle := VNT_NO;
  end;
  Result := FVerifyNoteTitle = VNT_YES;
end;

function TfrmGNEncounter.GetPatientData(APatient: TPatient): TPatientData;
var
  i: integer;
begin
  Result := nil;
  for i := 0 to GNPtList.Count - 1 do
  begin
    if ( TPatientData(GNPtList.Items[i]).Patient.DFN = APatient.DFN ) then
      Result := TPatientData(GNPtList.Items[i]);
  end;
end;

procedure TfrmGNEncounter.SetPatientData(APatient: TPatient;
  APCEData: TPCEData; ANote: TEditNoteRec);
var
  i: integer;
begin
  for i := 0 to GNPTList.Count - 1 do
  begin
    if (TPatientData(GNPTList.Items[i]).Patient.DFN = APatient.DFN) then
    begin
      APCEData.CopyPCEData(TPatientData(GNPTList.Items[i]).PCEData);
      TPatientData(GNPtList.Items[i]).PtNote := ANote;
    end;
  end;
end;

procedure TfrmGNEncounter.SaveEachNote(APatientData: TPatientData);
var
  Saved: Boolean;
  SavedDocID: string;
begin
  inherited;
  SavedDocID := IntToStr(APatientData.PtNote.NoteIEN);
  SaveEditedNote(Saved, APatientData);
end;

procedure TfrmGNEncounter.SaveEditedNote(var Saved: boolean; APatientData: TPatientData);
var
//  x: string;
  UpdatedNote: TCreatedDoc;
begin
  Saved := False;
  if APatientData.PtNote.Lines.Count = 0 then
  begin
    ShowMessage('Empty note, can not save!');
    Exit;
  end;
  UpdatedNote.IEN := APatientData.PtNote.NoteIEN;
  UpdatedNote.ErrorText := APatientData.PtNote.ErrTxt;
  try
    PutEditedNote(UpdatedNote, APatientData.PtNote, APatientData.PtNote.NoteIEN);
  finally
    //
  end;
  if UpdatedNote.IEN > 0 then
    Saved := True;
end;

procedure TfrmGNEncounter.SetPatientData(APatient: TPatient;
  ANote: TEditNoteRec);
var
  i: integer;
begin
  for i := 0 to GNPTList.Count - 1 do
  begin
    if (TPatientData(GNPTList.Items[i]).Patient.DFN = APatient.DFN) then
      TPatientData(GNPtList.Items[i]).PtNote := ANote;
  end;
end;

procedure TfrmGNEncounter.RemovePCEFromChanges(IEN: Int64;
  AVisitStr: string);
begin
  if IEN = NT_ADDENDUM then Exit;  // no PCE information entered for an addendum
  // do we need to call DeletePCE(AVisitStr), as was done with NT_NEW_NOTE (ien=-10)???
  if AVisitStr = '' then AVisitStr := VisitStrForNote(IEN);
  Changes.Remove(CH_PCE, 'V' + AVisitStr);
  Changes.Remove(CH_PCE, 'P' + AVisitStr);
  Changes.Remove(CH_PCE, 'D' + AVisitStr);
  Changes.Remove(CH_PCE, 'I' + AVisitStr);
  Changes.Remove(CH_PCE, 'S' + AVisitStr);
  Changes.Remove(CH_PCE, 'A' + AVisitStr);
  Changes.Remove(CH_PCE, 'H' + AVisitStr);
  Changes.Remove(CH_PCE, 'E' + AVisitStr);
  Changes.Remove(CH_PCE, 'T' + AVisitStr);
end;

function TfrmGNEncounter.EditPCEData(APatientData: TPatientData): boolean;
const
  TX_NEED_VISIT2 = 'A visit is required before entering encounter information.';
  TX_NOPCE_TXT1  = 'the encounter date is in the future.';
  TX_NOPCE_TXT2  = 'encounter entry has been disabled.';
  TX_NOPCE_TXT   = 'You can not edit encounter information because ';
  TX_NOPCE_HDR   = 'Can not edit encounter';
var
  Ans: integer;
  txt: string;
begin
  Result := FALSE;
  Ans := mrNo;
  if Assigned(APatientData.PCEData)  then
    Ans := mrYes;
  if ans = mrYes then
  begin
    if not CanEditPCE(APatientData.PCEData) then
    begin
      if FutureEncounter(APatientData.PCEData) then
        txt := TX_NOPCE_TXT1
      else
        txt := TX_NOPCE_TXT2;
      InfoBox(TX_NOPCE_TXT + txt, TX_NOPCE_HDR, MB_OK or MB_ICONWARNING);
      Exit;
    end;
    UpdatePCE(APatientData.PCEData);
    if not GroupEdit then
      APatientData.PCEData := uEncPCEData;
    Result := True;
  end
end;

procedure TfrmGNEncounter.lstPatientsClick(Sender: TObject);
var
  i: integer;
  APatient: TPatient;
  APatientData: TPatientData;
begin
  inherited;
  i := lstPatients.ItemIndex;
  lstPatients.MultiSelect := False;
  if i > - 1 then
  begin
    txtPCEData.Lines.Clear;
    memCommNote.Lines.Clear;
    memIndvNote.Lines.Clear;
    GroupEdit := False;
    if tbAllPatients.Down then
      tbAllPatients.Down := False;
    APatient := TPatient(lstPatients.Items.Objects[i]);
    APatientData := GetPatientData(APatient);
    if APatientData.PCEData.HasData then
    begin
      NewEncounter(False);
      if not FSigned then
        EditEncounter(True);
      APatientData.PCEData.AddStrData(txtPCEData.Lines);
    end else
    begin
      if not FSigned then
      begin
        NewEncounter(True);
        EditEncounter(FAlse);
      end;
    end;
    if APatientData.PtNote.NoteIEN > 0 then
    begin
      if not FSigned then
      begin
        MakeCommonNoteEnable(False);
        MakeIndvNoteEnable(True);
      end;
      if Assigned(APatientData.PtNote.GenLines) then
        memCommNote.Lines.Assign(APatientData.PtNote.GenLines);
      if Assigned(APatientData.PtNote.PtLines) then
        memIndvNote.Lines.Assign(APatientData.PtNote.PtLines);
      lblBaseNoteInfo.Caption := 'Common note content for ' + APatient.Name + ' (' +  APatient.SSN + ') ' +
        ' Title: ' + APatientData.PtNote.TitleName;
      lblIndvNoteInfo.Caption := 'Additional note text for ' + APatient.Name + ' (' +  APatient.SSN + ') ' +
        ' Title: ' + APatientData.PtNote.TitleName;
    end else
    begin
      MakeCommonNoteEnable(False);
      MakeIndvNoteEnable(False);
      lblBaseNoteInfo.Caption := 'Common note content for ' + APatient.Name + ' (' +  APatient.SSN + ') ' +
        ' Title: ' + APatientData.PtNote.TitleName;
      lblIndvNoteInfo.Caption := 'Additional note text for ' + APatient.Name + ' (' +  APatient.SSN + ') ' +
        ' Title: ' + APatientData.PtNote.TitleName;
    end;
    lblEnctInfo.Caption := 'Encounter data for ' + APatient.Name + ' (' +  APatient.SSN + ') ';
    ChangeNote(False);
  end;
end;

procedure TfrmGNEncounter.pnlAllPatientsClick(Sender: TObject);
begin
  inherited;
  GroupEdit := not GroupEdit;
  if GroupEdit then
  begin
    lstPatients.MultiSelect := True;
    lstPatients.SelectAll;
    MakeIndvNoteEnable(False);
  end
  else
  begin
    lstPatients.MultiSelect := False;
    lstPatients.ClearSelection;
  end;
end;

procedure TfrmGNEncounter.btnPrevClick(Sender: TObject);
begin
  inherited;
  if not GroupEdit then
  begin
    if lstPatients.ItemIndex > -1 then SelectedPatient := TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]).DFN;
  end;
  if GroupEdit then
    SelectedPatient := '';
  tbAllPatients.Down := False;
  GroupEdit := False;
  frmMainFrame.SwitchTo(frmGNPtSel, PG_GNECTER);
end;

procedure TfrmGNEncounter.NewNoteForIndividualPatient(APatientData: TPatientData);
var
  HaveRequired: Boolean;
  TmpBoilerPlate: TStringList;
  x{, WhyNot, DocInfo}: string;
  APtPCE: TPCEData;
  IndvNote: TEditNoteRec;
//  i: integer;
  CreatedNote: TCreatedDoc;
begin
  HaveRequired := False;
  APtPCE := APatientData.PCEData;
  memCommNote.Clear;
  memIndvNote.Clear;
  TmpBoilerPlate := nil;
  try
    FillChar(IndvNote, SizeOf(IndvNote), 0);
    with IndvNote do
    begin
      DocType      := TYP_PROGRESS_NOTE;
      IsNewNote    := True;
      Title        := DfltNoteTitle;
      TitleName    := DfltNoteTitleName;
      DateTime     := FMNow;
      Author       := User.DUZ;
      AuthorName   := User.Name;
      Location     := Encounter.Location;
      LocationName := Encounter.LocationName;
      VisitDate    := Encounter.DateTime;
    end;

    if LacksRequiredForCreate(IndvNote) or VerifyNoteTitle or UnresolvedConsultsExist
      then HaveRequired := ExecuteNoteProperties(IndvNote, CT_NOTES, False, False, '', 0)
    else HaveRequired := True;
    if HaveRequired then
    begin
      APtPCE.UseEncounter := True;
      //APtPCE.VisitCategory := GetVisitCat('A', Encounter.Location, APatientData.Patient.Inpatient);
      APtPCE.NoteDateTime := IndvNote.DateTime;
      IndvNote.NeedCPT  := APtPCE.CPTRequired;
      PutNewNote(CreatedNote, IndvNote, APatientData.Patient.DFN);
      if CreatedNote.IEN > 0 then LockDocument(CreatedNote.IEN, CreatedNote.ErrorText);
      if Length(CreatedNote.ErrorText)>0 then
      begin
        InfoBox('For patient ' + APatientData.Patient.Name +
          CreatedNote.ErrorText, TX_CREATE_ERR, MB_OK);
        Exit;
      end;
      APtPCE.NoteIEN := IndvNote.NoteIEN;
      Changes.Add(CH_DOC, IntToStr(CreatedNote.IEN),
            IndvNote.TitleName + ' for patient ' + APatientData.Patient.Name,
            '', CH_SIGN_YES);
      if IndvNote.ErrTxt = '' then
      begin
        with IndvNote do
          begin
            x := IntToStr(IndvNote.NoteIEN) + U + TitleName + U + FloatToStr(IndvNote.DateTime) + U +
                 Patient.Name + U + IntToStr(Author) + ';' + AuthorName + U + LocationName + U + 'new' + U +
                 U + U + U + U + U + U + U;
          end;
        if not assigned(TmpBoilerPlate) then
          TmpBoilerPlate := TStringList.Create;
        LoadBoilerPlate(TmpBoilerPlate, IndvNote.Title);
        memCommNote.Lines.Assign(TmpBoilerPlate);
        // save boilerplate text into note.genLines
        if TmpBoilerPlate.Count > 0 then
        begin
          if not Assigned(IndvNote.GenLines) then
          begin
            IndvNote.GenLines := TStringList.Create;
          end else
          begin
            IndvNote.GenLines.Clear;
          end;
          IndvNote.GenLines.Assign(TmpBoilerPlate);
        end;
        APatientData.PtNote := IndvNote;
        lblBaseNoteInfo.Caption := 'Common note content for ' + APatientData.Patient.Name + ' (' +  APatientData.Patient.SSN + ') ' +
          ' Title: ' + APatientData.PtNote.TitleName;
        lblIndvNoteInfo.Caption := 'Additional note text for ' + APatientData.Patient.Name + ' (' +  APatientData.Patient.SSN + ') ' +
          ' Title: ' + APatientData.PtNote.TitleName;
        MakeCommonNoteEnable(True);
        MakeIndvNoteEnable(True);
      end;
    end;
  finally
    if assigned(TmpBoilerPlate) then
      TmpBoilerPlate.Free;
  end;
end;

procedure TfrmGNEncounter.memCommNoteExit(Sender: TObject);
var
  i: integer;
  APatientData: TPatientData;
begin
  inherited;
  if (memCommNote.ReadOnly) or (not memCommNote.Enabled) then Exit;
  if GroupEdit then
  begin
    for i := 0 to GNPtList.Count - 1 do
    begin
      APatientData := TPatientData(GNPtList.Items[i]);
      if Assigned(APatientData.PtNote.GenLines) then APatientData.PtNote.GenLines.Clear
      else APatientData.PtNote.GenLines := TStringList.Create;
      APatientData.PtNote.GenLines.Assign(memCommNote.Lines);
      if Assigned(APatientData.PtNote.Lines) then APatientData.PtNote.Lines.Clear
      else APatientData.PtNote.Lines := TStringList.Create;
      APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.GenLines);
      if Assigned(APatientData.PtNote.PtLines) then
        APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.PtLines);
    end;
  end else
  begin
    if lstPatients.ItemIndex < 0 then exit;
    APatientData := GetPatientData(TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]));
    if Assigned(APatientData.PtNote.GenLines) then APatientData.PtNote.GenLines.Clear
    else APatientData.PtNote.GenLines := TStringList.Create;
    if Assigned(APatientData.PtNote.Lines) then APatientData.PtNote.Lines.Clear
    else APatientData.PtNote.Lines := TStringList.Create;
    APatientData.PtNote.GenLines.Assign(memCommNote.Lines);
    APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.GenLines);
    if Assigned(APatientData.PtNote.PtLines) then
      APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.PtLines);
  end;
end;

procedure TfrmGNEncounter.memIndvNoteExit(Sender: TObject);
var
  APatientData: TPatientData;
begin
  inherited;
  if (memIndvNote.ReadOnly) then Exit;
  if (lstPatients.ItemIndex < -1) then Exit;
  APatientData := GetPatientData(TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]));
  if Assigned(APatientData.PtNote.PtLines) then APatientData.PtNote.PtLines.Clear
  else APatientData.PtNote.PtLines := TStringList.Create;
  APatientData.PtNote.PtLines.Assign(memIndvNote.Lines);
  if Assigned(APatientData.PtNote.Lines) then APatientData.PtNote.Lines.Clear
  else APatientData.PtNote.Lines := TStringList.Create;
  if Assigned(APatientData.PtNote.GenLines) then
    APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.GenLines);
  APatientData.PtNote.Lines.AddStrings(APatientData.PtNote.PtLines);
end;

procedure TfrmGNEncounter.btnStartOverClick(Sender: TObject);
var
  i: integer;
begin
  inherited;
  if not FSigned then
  begin
    if Changes.Documents.Count > 0 then
    begin
      if  NeedToSign then
      begin
        if MessageDlg(TX_UNSIGNNOTES,mtWarning,[mbYes, mbNo],0) = mrNo then
        begin
          DeleteCurrentNotes(True);  // automatically delete empty notes
          actSaveNoSigExecute(Self);
          Changes.Clear;
        end
        else
        begin
          if tbSignNote.Enabled then
          begin
            DeleteCurrentNotes(True); // automatically delete empty notes
            actSignNoteExecute(Self);
          end;
        end
      end
      else
      begin
        DeleteCurrentNotes(False);
        Changes.Clear;
      end;
    end;
  end;
  if Assigned(GNPtlist) then
    for i := 0 to GNPtList.Count - 1 do
    begin
      TPatientData(GNPtList.Items[i]).Free;
    end;
  GNPtList.Clear;
  Changes.Clear;
  txtPCEData.Lines.Clear;
  memCommNote.Lines.Clear;
  MakeCommonNoteEnable(False);
  memIndvNote.Lines.Clear;
  MakeIndvNoteEnable(False);
  lstPatients.ItemIndex := -1;
  lstPatients.Items.Clear;
  SelectedPatient := '';
  GroupEdit := False;
  StartOver := True;
  NewNote(True);
  ChangeNote(False);
  SaveWithoutSign(False);
  SignNote(False);
  EditEncounter(False);
  NewEncounter(True);
  btnBasicEnct.Enabled := True;
  BackToPtSelect(True);
  lblBaseNoteInfo.Caption := 'Progress note: content shared by all patients';
  lblIndvNoteInfo.Caption := 'Progress note: content for individual patient';
  FSigned := False;
  lblSignature.Caption := '';  
  ClearNote(BaseNote);
  Changes.Clear;
  Encounter.Clear;
  BasePCE.Clear;
  frmMainFrame.SwitchTo(frmGNPtSel, PG_GNECTER);
end;

procedure TfrmGNEncounter.pm1SpellcheckClick(Sender: TObject);
begin
  inherited;
  try
    SpellCheckForControl(memCommNote);
  finally
    //
  end;
end;

procedure TfrmGNEncounter.pm1GrammarCheckClick(Sender: TObject);
begin
  inherited;
  try
    GrammarCheckForControl(memCommNote);
  finally
    //
  end;
end;

procedure TfrmGNEncounter.pm2GrammarCheckClick(Sender: TObject);
begin
  inherited;
  try
    GrammarCheckForControl(memIndvNote);
  finally
    //
  end;
end;

procedure TfrmGNEncounter.pm2SpellCheckClick(Sender: TObject);
begin
  inherited;
  try
    SpellCheckForControl(memIndvNote);
  finally
    //
  end;
end;

procedure TfrmGNEncounter.FormCreate(Sender: TObject);
begin
  FChangeNote := False;
  FSigned := False;
  FSignRst := '';
  ShowBasicEnctInfo;
end;

procedure TfrmGNEncounter.MakeCommonNoteEnable(TheEnable: boolean);
begin
  if TheEnable then
  begin
    memCommNote.Enabled := True;
    memCommNote.ReadOnly := False;
    memCommNote.Color := clWindow;
  end else
  begin
    memCommNote.Color := clInactiveCaptionText;
    memCommNote.ReadOnly := True;
    memCommNote.Font.Color := clWindowText;
  end;
end;

procedure TfrmGNEncounter.MakeIndvNoteEnable(TheEnable: boolean);
begin
  if TheEnable then
  begin
    memIndvNote.Enabled := True;
    memIndvNote.ReadOnly := False;
    memIndvNote.Color := clWindow;
  end else
  begin
    memIndvNote.Color := clInactiveCaptionText;
    memIndvNote.ReadOnly := True;
    memIndvNote.Font.Color := clWindowText;
  end;
end;

procedure TfrmGNEncounter.MakeEncounterEnable(TheEnable: boolean);
begin
  txtPCEData.Enabled := TheEnable;
  txtPCEData.ReadOnly := True;
end;

procedure TfrmGNEncounter.actNewNoteExecute(Sender: TObject);
var
  HaveRequired: Boolean;
  TmpBoilerPlate: TStringList;
//  x,
//  WhyNot, DocInfo: string;
  APatientData: TPatientData;
//  IndvNote:  TEditNoteRec;
  i: integer;
  CreatedNote: TCreatedDoc;
begin
  inherited;
  HaveRequired := False;
  if Encounter.NeedVisit then
    if not UpdateEncounter(NPF_ALL) then Exit;
  ShowBasicEnctInfo;
  if GroupEdit then  Patient := TPatient(lstPatients.Items.Objects[0])
  else
  begin
   if lstPatients.ItemIndex < 0 then
   begin
     ShowMessage('Please select a patient before creating a new note.');
     Exit;
   end;
   Patient := TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]);
  end;
  APatientData := GetPatientData(Patient);
  if not GroupEdit then
  begin
    NewNoteForIndividualPatient(APatientData);
    Exit;
  end;
  memCommNote.Clear;
  memIndvNote.Clear;
  TmpBoilerPlate := nil;
  ClearNote(BaseNote);
  try
    FillChar(BaseNote, SizeOf(BaseNote), 0);
    with BaseNote do
    begin
      DocType      := TYP_PROGRESS_NOTE;
      IsNewNote    := True;
      Title        := DfltNoteTitle;
      TitleName    := DfltNoteTitleName;
      DateTime     := FMNow;
      Author       := User.DUZ;
      AuthorName   := User.Name;
      Location     := Encounter.Location;
      LocationName := Encounter.LocationName;
      VisitDate    := Encounter.DateTime;
    end;
    if FChangeNote then
    begin
      HaveRequired := ExecuteNoteProperties(BaseNote, CT_NOTES, False, False, '', 0);
      ChangeNote(True);
      FChangeNote := False;
    end else if LacksRequiredForCreate(BaseNote) or VerifyNoteTitle or UnresolvedConsultsExist
      then HaveRequired := ExecuteNoteProperties(BaseNote, CT_NOTES, False, False, '', 0)
    else HaveRequired := True;
    if HaveRequired then
    begin
      MakeCommonNoteEnable(True);
      APatientData.PCEData.UseEncounter := True;       // set up PCE data for entry of new note
      //APatientData.PCEData.VisitCategory := GetVisitCat('A', Encounter.Location, APatientData.Patient.Inpatient);
      APatientData.PCEData.NoteDateTime := BaseNote.DateTime;
      BaseNote.NeedCPT  := APatientData.PCEData.CPTRequired;
      if (GNPtList.Count > 1 ) then       // set up PCE for group patients
      begin
        for i := 1 to GNPtList.Count - 1 do    // first patient's note is default to BaseNote.
        begin
          ClearNote(TPatientData(GNPtList.Items[i]).PtNote);
          TPatientData(GNPtList.Items[i]).PCEData.UseEncounter := True;
          TPatientData(GNPtList.Items[i]).PCEData.NoteDateTime := BaseNote.DateTime;
          TPatientData(GNPtList.Items[i]).PtNote := BaseNote;
          TPatientData(GNPtList.Items[i]).PtNote.NeedCPT := TPatientData(GNPtList.Items[i]).PCEData.CPTRequired;
        end;
      end;
      PutNewNote(CreatedNote,BaseNote);   // create the base note for GNPtList.Items[0]
      if CreatedNote.IEN > 0 then LockDocument(CreatedNote.IEN, CreatedNote.ErrorText);
      if Length(CreatedNote.ErrorText) > 0 then
      begin
        InfoBox(CreatedNote.ErrorText, TX_CREATE_ERR, MB_OK);
        Exit;
      end;
      TPatientData(GNPtlist.Items[0]).PtNote := BaseNote;
      TPatientData(GNPtList.Items[0]).PCEData.NoteIEN := BaseNote.NoteIEN;
      Changes.Add(CH_DOC, IntToStr(CreatedNote.IEN),
        BaseNote.TitleName + ' for patient ' + TPatientData(GNPtlist.Items[0]).Patient.Name,
        '', CH_SIGN_YES);
      if (GNPtList.Count > 1 ) then            // create note for each patient in the group
      begin
        for i := 1 to GNPtList.Count - 1 do    // first patient's note is default to BaseNote.
        begin
          CreatedNote.IEN := 0;
          CreatedNote.ErrorText := '';
          PutNewNote(CreatedNote, TPatientData(GNPtList.Items[i]).PtNote,TPatientData(GNPtList.Items[i]).Patient.DFN);
          if CreatedNote.IEN > 0 then LockDocument(CreatedNote.IEN, CreatedNote.ErrorText);
          if Length(CreatedNote.ErrorText)>0 then
          begin
            InfoBox('For patient ' + TPatientData(GNPtList.Items[i]).Patient.Name +
              CreatedNote.ErrorText, TX_CREATE_ERR, MB_OK);
            Continue;
          end;
          TPatientData(GNPtList.Items[i]).PCEData.NoteIEN := CreatedNote.IEN;
          Changes.Add(CH_DOC, IntToStr(CreatedNote.IEN),
            TPatientData(GNPtList.Items[i]).PtNote.TitleName + ' for patient ' + TPatientData(GNPtList.Items[0]).Patient.Name,
            '', CH_SIGN_YES);
        end;
      end;
      lblBaseNoteInfo.Caption :='Common note content for group patients.' + ' Title:' + BaseNote.TitleName;
      lblIndvNoteInfo.Caption :='Additional note text for selected patient. ' + ' Title: ' + BaseNote.TitleName;
      if GroupEdit then
        ChangeNote(True);
      if BaseNote.ErrTxt = '' then
      begin
        if not assigned(TmpBoilerPlate) then
          TmpBoilerPlate := TStringList.Create;
        LoadBoilerPlate(TmpBoilerPlate, BaseNote.Title);
        memCommNote.Lines.Clear;
        memIndvNote.Lines.Clear;
        memCommNote.Lines.Assign(TmpBoilerPlate);
        btnBasicEnct.Enabled := False;
      end else
      begin
       HaveRequired := False;
       ShowMessage(BaseNote.ErrTxt);
       Exit;
      end;
    end else
      Exit;
  finally
    if assigned(TmpBoilerPlate) then
      TmpBoilerPlate.Free;
    if haveRequired then
    begin
      memCommNote.SetFocus;
      NewNote(False);
      BackToPtSelect(False);
    end;
    LimitEditWidth(memCommNote, 70);
    LimitEditWidth(memIndvNote, 70);
    Application.ProcessMessages;
  end;
end;

procedure TfrmGNEncounter.actForAllPatientsExecute(Sender: TObject);
begin
  inherited;
  if (not memCommNote.ReadOnly) and (memCommNote.Lines.Count > 0) then
    memCommNoteExit(Self);
  if (not memIndvNote.ReadOnly) then //and (memIndvNote.Enabled) then
      memIndvNoteExit(Self);

  GroupEdit := not GroupEdit;
  if GroupEdit then
  begin
    tbAllPatients.Down := True;
    lstPatients.MultiSelect := True;
    lstPatients.SelectAll;
    if FSigned then Exit;
    if BaseNote.NoteIEN > 0 then // selecting group patients with base note was created already
    begin
      lblBaseNoteInfo.Caption :='Common note content for group patients.' + ' Title:' + BaseNote.TitleName;
      lblIndvNoteInfo.Caption :='Additional note text for selected patient. ' + ' Title: ' + BaseNote.TitleName;
      lblEnctInfo.Caption     := 'Encounter data for all patients';
      MakeCommonNoteEnable(True);
      ChangeNote(True);
    end else
    begin  //selecting group patients when note was not created yet
      lblBaseNoteInfo.Caption := 'Progress note:  content shared by all patients';
      lblIndvNoteInfo.Caption := 'Progress note:  content for individual patient';
      lblEnctInfo.Caption     := 'Encounter data for all patients';
      memCommNote.Lines.Clear;
      txtPCEData.Lines.Clear;
    end;
    if BasePCE.HasData then
    begin
      NewEncounter(False);
      EditEncounter(True);
    end else
    begin
      NewEncounter(True);
      EditEncounter(False);
    end;
    memIndvNote.Lines.Clear;
    MakeIndvNoteEnable(False);
  end
  else
  begin
    tbAllPatients.Down := False;
    lstPatients.MultiSelect := False;
    lstPatients.ClearSelection;
    MakeCommonNoteEnable(False);
    ChangeNote(False);
  end;
end;

procedure TfrmGNEncounter.actChangeNoteExecute(Sender: TObject);
begin
  inherited;
  FChangeNote := True;
  if HasAnyNote then
    if MessageDlg('All current patients'' notes will be erased, are you sure to continue?',
       mtWarning, [mbOK, mbCancel], 0) = mrCancel then  Exit;
  DeleteCurrentNotes(False);
  actNewNoteExecute(Self);
end;

procedure TfrmGNEncounter.actSignNoteExecute(Sender: TObject);
const
  SIG_COSIGN = 'COSIGNATURE';
  SIG_SIGN   = 'SIGNATURE';
  SIG_TEXT   = 'The signature will be applied to all notes for group patients.';
var
//  Saved: Boolean;
  ActionType,
  ESCode,  SignTitle: string;
  ActionSts, SignSts: TActionRec;
  OK: boolean;
//  SavedDocID, tmpItem: string;
//  EditingID: string;
  i: integer;
  APatientData: TPatientData;
//  APatient: TPatient;
//  ableToClose: boolean;
begin
  inherited;
  actSaveNoSigExecute(Self);
  if not NeedToSign then
  begin
   ShowMessage('Empty notes can not be signed');
   Exit;
  end;
  if not Assigned(GnPtList) then exit;
  if GnPtList.Count < 1 then exit;
  //if lstPatients.ItemIndex < 0 then exit;
  tbAllPatients.Down := True;
  lstPatients.MultiSelect := True;
  lstPatients.SelectAll;
  GroupEdit := True;
  OK := False;
  for i := 0 to GNPtList.Count - 1 do
  begin
    APatientData := TPatientData(GNPtList.Items[i]);
    if CosignDocument(APatientData.PtNote.NoteIEN) then
    begin
      SignTitle := TX_COSIGN;
      ActionType := SIG_COSIGN;
    end else
    begin
      SignTitle := TX_SIGN;
      ActionType := SIG_SIGN;
    end;
    ActOnDocument(ActionSts, APatientData.PtNote.NoteIEN, ActionType);
    if ActionSts.Success then
    begin
      GroupEdit := not GroupEdit;
      OK := IsOK2Sign(APatientData.PCEData, APatientData.PtNote.NoteIEN,
        APatientData.PtNote.TitleName, APatientData.Patient);
      GroupEdit := not GroupEdit;
      if APatientData.PCEData.HasData then
        MakeEncounterEnable(True);
      if not AuthorSignedDocument(APatientData.PtNote.NoteIEN) then
      begin
        if (InfoBox(TX_AUTH_SIGNED + APatientData.PtNote.TitleName,TX_SIGN ,MB_YESNO)= ID_NO) then exit;
      end;
      APatientData.OKForSign := OK;
    end
    else
    begin
      ShowMessage('Has problem to sign ' + APatientData.PtNote.TitleName
        + ' for ' + APatientData.Patient.Name + '.' + #10#13
        + 'Reason: ' + ActionSts.Reason  + #10#13
        + 'Rest of notes will be signed...');
      APatientData.OKForSign := False;
      Continue;//Exit;
    end;
  end;
  if OK then
    SignatureForItem(Font.Size, SIG_TEXT, SignTitle, ESCode, FSignRst);
  if FSignRst = 'cancel' then
    Exit;
  if FSignRst = 'notsign' then
  begin
    for i := 0 to GNPtList.count - 1 do
    begin
      APatientData := TPatientData(GNPtList.Items[i]);
      UnlockDocument(APatientData.PtNote.NoteIEN);
      RemovePCEFromChanges(APatientData.PtNote.NoteIEN);
      Changes.Remove(CH_DOC, IntToStr(APatientData.PtNote.NoteIEN));
    end;
    UpdateControlsAfterSign(False);
  end
  else if Length(ESCode) > 0 then
  begin
    for i := 0 to GNPtList.Count - 1 do
    begin
      APatientData := TPatientData(GNPtList.Items[i]);
      if APatientData.OKForSign then
      begin
        SignDocument(SignSts, APatientData.PtNote.NoteIEN, ESCode);
        UnlockDocument(APatientData.PtNote.NoteIEN);
        RemovePCEFromChanges(APatientData.PtNote.NoteIEN);
        Changes.Remove(CH_DOC, IntToStr(APatientData.PtNote.NoteIEN));
      end;
    end;
    UpdateControlsAfterSign(True);
  end;
end;

procedure TfrmGNEncounter.actNewEncounterExecute(Sender: TObject);
var
  i: integer;
  thePatient: TPatient;
//  PtEncounter: TEncounter;
  APatientData: TPatientData;
  hasData: boolean;
begin
  inherited;
  hasData := False;
  for i := 0 to lstPatients.Items.Count - 1 do
  begin
    ThePatient := TPatient(lstPatients.Items.Objects[i]);
    APatientData := GetPatientData(ThePatient);
    if APatientData.PCEData.HasData then
    begin
      hasData := True;
      Break;
    end;
  end;
  if (hasData and GroupEdit and (not BasePCE.HasData)) then
  begin
      if MessageDlg('Creating encounter for group patients will erase all patients current encounter data, Continue? ',
        mtWarning, [mbOK, mbCancel],0) = mrCancel then
          Exit;
  end;
  if Assigned(BasePCE) then
  begin
    if ((BasePCE.HasData) and GroupEdit) then
    begin
      if MessageDlg('Editting encounter for group patients will erase all patients current encounter data, Continue? ',
        mtWarning, [mbOK, mbCancel],0) = mrCancel then
          Exit;
    end;
  end;
  if Encounter.NeedVisit then
    if not UpdateEncounter(NPF_ALL) then Exit;
  ShowBasicEnctInfo;
  if (not GroupEdit) and (lstPatients.ItemIndex < 0) then
  begin
    ShowMessage('Please select patient before creating a new encounter!');
    Exit;
  end;
  if GroupEdit then
    lblEnctInfo.Caption := 'Encounter Data for all patients'
  else
    lblEnctInfo.Caption := 'Encounter data for ' + lstPatients.Items[lstPatients.itemIndex];
  txtPCEData.Enabled := True;
  Encounter.VisitCategory := GetVisitCat('A', Encounter.Location, False);
  if GroupEdit then
  begin
    Patient := TPatient(lstPatients.Items.Objects[0]);
    APatientData := GetPatientData(Patient);
  end else
  begin
    Patient := TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]);
    APatientData := GetPatientData(Patient);
  end;
  if EditPCEData(APatientData) then
  begin
    if GroupEdit then
    begin
      UpdateGroupPatientPCEData;
      txtPCEData.Lines.Clear;
      BasePCE.AddStrData(txtPCEData.Lines);
    end
    else
    begin
      txtPCEData.Lines.Clear;
      APatientData.PCEData.AddStrData(txtPCEData.Lines);
    end;
  end;
  if (not memCommNote.ReadOnly) then
    memCommNote.SetFocus;
  if GroupEdit then
  begin
   if BasePCE.HasData then
   begin
     EditEncounter(True);
     NewEncounter(False);
     btnBasicEnct.Enabled := False;
   end;
  end else
  begin
    if APatientData.PCEData.HasData then
    begin
      NewEncounter(False);
      EditEncounter(True);
      btnBasicEnct.Enabled := False;
    end;
  end;
end;

procedure TfrmGNEncounter.memCommNoteEnter(Sender: TObject);
begin
  inherited;
  SignNote(True);
  SaveWithoutSign(True);
end;

procedure TfrmGNEncounter.memIndvNoteEnter(Sender: TObject);
begin
  inherited;
  SignNote(True);
  SaveWithoutSign(True)
end;

function TfrmGNEncounter.HasAnyNote: boolean;
var
  i: integer;
begin
  Result := False;
  for i := 0 to GNPtList.Count - 1 do
  begin
    if (TPatientData(GNPtList.Items[i]).PtNote.NoteIEN > 0) then
    begin
      Result := True;
      Exit;
    end;
  end;
end;

procedure TfrmGNEncounter.ShowBasicEnctInfo;
var
  providernm, locname, datetime, dquote: string;
begin
  dquote := '''' + ' ' + '''';
  if Assigned(Encounter) then
  begin
    if length(Encounter.ProviderName) > 1 then
      providernm := Encounter.ProviderName
    else
      providernm := dquote;
    if length(Encounter.LocationName) > 1 then
      locname := Encounter.LocationName
    else
      locname := dquote;
    if Encounter.DateTime > 0 then
      datetime := FormatFMDateTime('mm/dd/yyyy hh:nn', Encounter.DateTime)
    else
      datetime := dquote;
    lblBasicEnct.Caption := ' Provider: ' +  providernm
      + '  Location: ' + LocName
      + '  Date: ' + DateTime;
  end;
end;

procedure TfrmGNEncounter.btnBasicEnctClick(Sender: TObject);
begin
  inherited;
  if not UpdateEncounter(NPF_ALL) then  Exit;
  ShowBasicEnctInfo;
end;

procedure TfrmGNEncounter.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  if CloseFromMain then
  begin
    memCommNoteExit(Self);
    memIndvNoteExit(Self);
  end;
  if not NeedToSign then
  begin
    DeleteCurrentNotes(True);
    Exit;
  end;
  if not FSigned then
  begin
    if Changes.Documents.Count > 0 then
    begin
      if MessageDlg(TX_UNSIGNNOTES,mtWarning,[mbYes, mbNo],0) = mrNo then
      begin
        DeleteCurrentNotes(True);
        actSaveNoSigExecute(Self);
        Changes.Clear;
      end
      else
      begin
        if tbSignNote.Enabled then
        begin
          DeleteCurrentNotes(True);
          if NeedToSign then actSignNoteExecute(Self);
          {while not FSigned do
            actSignNoteExecute(Self);}
        end;
      end;
    end;
  end;
end;

function TfrmGNEncounter.LockNote(AnIEN: Int64): Boolean;
var
  LockMsg: string;
begin
  Result := True;
  if Changes.Exist(CH_DOC, IntToStr(AnIEN)) then Exit;  // already locked
  if Result then
  begin
    LockDocument(AnIEN, LockMsg);
    if LockMsg <> '' then
    begin
      Result := False;
      InfoBox(LockMsg, TC_NO_LOCK, MB_OK);
    end;
  end;
end;


procedure TfrmGNEncounter.AdditionalSignerForSingleNote;
var
//  i: integer;
  APatient: TPatient;
  APatientData: TPatientData;
  Exclusions: TStrings;
//  Saved,
  x, y: boolean;
  SignerList: TSignerList;
  ActionSts: TActionRec;
  SigAction: integer;
//  SavedDocID: string;
//  ARefDate: TFMDateTime;
begin
    SigAction := -1;
    //apply additional signer to selected patient's note
    if lstPatients.ItemIndex < 0 then
    begin
      ShowMessage('Please select a patient first before identifying additional signer.');
      Exit;
    end;
    APatient := TPatient(lstPatients.Items.Objects[lstPatients.ItemIndex]);
    APatientData := GetPatientData(APatient);
    {if APatientData.AdditionalSigner then
    begin
      ShowMessage('The additional signer has already been identified.');
      Exit;
    end;}
    x := CanChangeCosigner(APatientData.PtNote.NoteIEN);
    ActOnDocument(ActionSts, APatientData.PtNote.NoteIEN, 'IDENTIFY SIGNERS');
    y := ActionSts.Success;
    if x and not y then
    begin
      if InfoBox(ActionSts.Reason + CRLF + CRLF +
          'Would you like to change the cosigner?',
           TX_IN_AUTH, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) = ID_YES then
        SigAction := SG_COSIGNER
      else	Exit;
    end
    else if y and not x then SigAction := SG_ADDITIONAL
    else if x and y then SigAction := SG_BOTH
    else
    begin
      InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK);
      Exit;
    end;
    if not LockNote(APatientData.PtNote.NoteIEN) then Exit;
    Exclusions := GetCurrentSigners(APatientData.PtNote.NoteIEN);
    SelectAdditionalSigners(Font.Size, APatientData.PtNote.NoteIEN, SigAction, Exclusions, SignerList, CT_NOTES);
    with SignerList do
      begin
        case SigAction of
          SG_ADDITIONAL:  if Changed and (Signers <> nil) and (Signers.Count > 0) then
                             UpdateAdditionalSigners(APatientData.PtNote.NoteIEN, Signers);

          SG_COSIGNER:    if Changed then
                              ChangeCosigner(APatientData.PtNote.NoteIEN, Cosigner);
          SG_BOTH:        if Changed then
                          begin
                            if (Signers <> nil) and (Signers.Count > 0) then
                                UpdateAdditionalSigners(APatientData.PtNote.NoteIEN, Signers);
                            ChangeCosigner(APatientData.PtNote.NoteIEN, Cosigner);
                          end;
        end;
        APatientData.AdditionalSigner := True;
      end;
   UnlockDocument(APatientData.PtNote.NoteIEN);
   //AdditionalSigner(False);
end;

procedure TfrmGNEncounter.actIdentifyAdditionalSignerExecute(Sender: TObject);
var
  i: integer;
  APatientData: TPatientData;
  TmpNoteList: TStringList;
  Exclusions: TStrings;
//  Saved,
  x, y: boolean;
  SignerList: TSignerList;
  ActionSts: TActionRec;
  SigAction: integer;
//  SavedDocID: string;
//  ARefDate: TFMDateTime;
begin
  inherited;
  if GroupEdit then
  begin
    //apply additional signer to all the notes of group patients
    TmpNoteList := TStringList.Create;
    for i := 0 to GNPtList.Count - 1 do
    begin
      APatientData := TPatientData(GNPtList.Items[i]);
      //if APatientData.AdditionalSigner then continue;
      x := CanChangeCosigner(APatientData.PtNote.NoteIEN);
      ActOnDocument(ActionSts, APatientData.PtNote.NoteIEN, 'IDENTIFY SIGNERS');
      y := ActionSts.Success;
      if i=0 then
      begin
        if x and not y then
        begin
          if InfoBox(ActionSts.Reason + CRLF + CRLF +
              'Would you like to change the cosigner?',
               TX_IN_AUTH, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) = ID_YES then
            SigAction := SG_COSIGNER
          else	Exit;
        end
        else if y and not x then SigAction := SG_ADDITIONAL
        else if x and y then SigAction := SG_BOTH
        else
        begin
          InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK);
          Exit;
        end;
      end;
      if not LockNote(APatientData.PtNote.NoteIEN) then
        Continue;
      APatientData.AdditionalSigner := True;
      TmpNoteList.Add(IntToStr(APatientData.PtNote.NoteIEN));
    end;
    Exclusions := GetCurrentSigners(StrToInt(TmpNoteList[0]));
    SelectAdditionalSigners(Font.Size, StrToInt(TmpNoteList[0]), SigAction, Exclusions, SignerList, CT_NOTES);
    with SignerList do
      begin
        case SigAction of
          SG_ADDITIONAL:  if Changed and (Signers <> nil) and (Signers.Count > 0) then
                          begin
                            for i := 0 to TmpNoteList.Count - 1 do
                              UpdateAdditionalSigners(StrToInt(TmpNoteList[i]), Signers);
                          end;
          SG_COSIGNER:    if Changed then
                          begin
                            for i := 0 to TmpNoteList.Count - 1 do
                              ChangeCosigner(StrToInt(tmpNoteList[i]), Cosigner);
                          end;
          SG_BOTH:        if Changed then
                          begin
                            if (Signers <> nil) and (Signers.Count > 0) then
                            begin
                              for i := 0 to TmpNoteList.Count - 1 do
                                UpdateAdditionalSigners(StrToInt(TmpNoteList[i]), Signers);
                            end;
                            for i := 0 to TmpNoteList.Count - 1 do
                              ChangeCosigner(StrToInt(tmpNoteList[i]), Cosigner);
                          end;
        end;
        for i := 0 to GNPtlist.Count - 1 do
        begin
          if not TPatientData(GNPtlist.Items[i]).AdditionalSigner then
            TPatientData(GNPtlist.Items[i]).AdditionalSigner := True;
        end;
      end;
   for i := 0 to TmpNoteList.Count - 1 do
      UnlockDocument(StrToInt(tmpNoteList[i]));
   //AdditionalSigner(False);
  end else
    AdditionalSignerForSingleNote;
end;

procedure TfrmGNEncounter.AdditionalSigner(IsEnable: boolean);
begin
  tbAdditionalSigner.Enabled := IsEnable;
  mnIdentifyAdditionalSigners.Enabled := IsEnable;
  pm1IdentifyAdditionalSigner.Enabled := IsEnable;
  pm2IdentifyAdditionalSigner.Enabled := IsEnable;
  pm3IdentifyAdditionalSigner.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.ChangeNote(IsEnable: boolean);
begin
  tbChangeNote.Enabled := IsEnable;
  mnChangeTitle.Enabled := IsEnable;
  pm1ChangeTitle.Enabled := IsEnable;
  pm2ChangeTitle.Enabled := IsEnable;
  pm3ChangeTitle.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.EditEncounter(IsEnable: boolean);
begin
  tbEditEncounter.Enabled := IsEnable;
  mnEditEncounter.Enabled := IsEnable;
  pm1EditEncounter.Enabled := IsEnable;
  pm2EditEncounter.Enabled := IsEnable;
  pm3EditEncounter.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.NewEncounter(IsEnable: boolean);
begin
  tbNewEncounter.Enabled := IsEnable;
  mnNewEncounter.Enabled := IsEnable;
  pm1NewEncounter.Enabled := IsEnable;
  pm2NewEncounter.Enabled := IsEnable;
  pm3NewEncounter.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.NewNote(IsEnable: boolean);
begin
  tbNewNote.Enabled := IsEnable;
  mnNewProgressNote.Enabled := IsEnable;
  pm1NewProgressNote.Enabled := IsEnable;
  pm2NewProgressNote.Enabled := IsEnable;
  pm3NewNote.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.SaveWithoutSign(IsEnable: boolean);
begin
  tbSaveNoSig.Enabled := IsEnable;
  mnSavewithoutSignature.Enabled := IsEnable;
  pm1SavewithoutSignature.Enabled := IsEnable;
  pm2SavewithoutSignature.Enabled := IsEnable;
  pm3SavewithoutSignature.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.SignNote(IsEnable: boolean);
begin
  tbSignNote.Enabled := IsEnable;
  mnSignNoteNow.Enabled := IsEnable;
  pm1SignNotesNow.Enabled := IsEnable;
  pm2SignNoteNow.Enabled := IsEnable;
  pm3SignNote.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.ForAllPatients(IsEnable: boolean);
begin
  tbAllPatients.Enabled := IsEnable;
  mnForAllPatients.Enabled := IsEnable;
  pm1ForAllPatients.Enabled := IsEnable;
  pm2ForAllPatients.Enabled := IsEnable;
  pm3ForAllPatients.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.actSaveNoSigExecute(Sender: TObject);
var
  i: integer;
  APatientData: TPatientData;
begin
  inherited;
  memCommNoteExit(Self);
  memIndvNoteExit(Self);
  for i := 0 to GNPtList.Count - 1 do
  begin
    APatientData := TPatientData(GNPtList.Items[i]);
    if APatientData.PtNote.Lines.count > 0 then
      SaveEachNote(APatientData);
  end;
  AdditionalSigner(False);
end;

function TfrmGNEncounter.NeedToSign: boolean;
var
  i: integer;
  APatientData: TPatientData;
begin
  Result := False;
  for i := 0 to GNPtlist.Count - 1 do
  begin
    APatientData := TPatientData(GNPtList.Items[i]);
    if (APatientData.PtNote.Lines.Count > 0) then
    begin
      Result := True;
      Break;
    end;
  end;
end;

procedure TfrmGNEncounter.BackToPtSelect(IsEnable: boolean);
begin
  btnPrev.Enabled := IsEnable;
  mnBacktoPatientSelection.Enabled := IsEnable;
end;

procedure TfrmGNEncounter.UpdateControlsAfterSign(IsSigned: boolean);
begin
  MakeCommonNoteEnable(False);
  MakeIndvNoteEnable(False);
  if IsSigned then  // signed or don't sign
  begin
    lblBaseNoteInfo.Caption := lblBaseNoteInfo.Caption + '--- Signed';
    lblIndvNoteInfo.Caption := lblIndvNoteInfo.Caption + '--- Signed';
    lblSignature.Visible := True;
    lblSignature.Enabled := True;
    lblSignature.Font.Style := [fsBold];
    lblSignature.Caption := ' Signed by: ' + User.Name + ' at ' + DateTimeToStr(Now);
    AdditionalSigner(True);
  end;
  FSigned := True;  // mark it true no matter signed or don't sign
  btnPrev.Enabled := False;
  SignNote(False);
  ChangeNote(False);
  SaveWithoutSign(False);
  NewEncounter(False);
  EditEncounter(False);
  tbAllPatients.Down := False;
  lstPatients.MultiSelect := False;
  lstPatients.ClearSelection;
  GroupEdit := False;
  Changes.Clear;
end;

procedure TfrmGNEncounter.DeleteCurrentNotes(onlyEmptyNotes: boolean);
var
  i, SavedDocIEN: integer;
  AVisitStr, ReasonForDelete, x: string;
  APatientData: TPatientData;
  DeleteSts, ActionSts: TActionRec;
begin
  for i := 0 to GNPtList.Count - 1 do
  begin
    APatientData := TPatientData(GNPtList.Items[i]);
    if onlyEmptyNotes then
    begin
      if APatientData.PtNote.Lines.Count > 0 then
        Continue;
    end;
    ActOnDocument(ActionSts, APatientData.PtNote.NoteIEN, 'DELETE RECORD');
    if ShowMsgOn(not ActionSts.Success, ActionSts.Reason, TX_IN_AUTH) then Continue;
    ReasonForDelete := SelectDeleteReason(APatientData.PtNote.NoteIEN);
    // do the appropriate locking
    if not LockNote(APatientData.PtNote.NoteIEN) then Continue;
    // retraction notification message
    if JustifyDocumentDelete(APatientData.PtNote.NoteIEN) then
      ShowMessage('Justify document message.');
    SavedDocIEN := APatientData.PtNote.NoteIEN;
    DeleteSts.Success := True;
    x := GetPackageRefForNote(SavedDocIEN);
    AVisitStr := VisitStrForNote(SavedDocIEN);
    RemovePCEFromChanges(SavedDocIEN, AVisitStr);
    DeleteDocument(DeleteSts, SavedDocIEN, ReasonForDelete);
    if not Changes.Exist(CH_DOC, IntToStr(SavedDocIEN)) then UnlockDocument(SavedDocIEN);
    Changes.Remove(CH_DOC, IntToStr(SavedDocIEN));  // this will unlock the document if in Changes
    // reset the display now that the note is gone
    if DeleteSts.Success then
    begin
      DeletePCE(AVisitStr);  // removes PCE data if this was the only note pointing to it
    end;
  end;
end;

procedure TfrmGNEncounter.memCommNoteKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if ( ( (Key=ord('c')) or (Key=ord('v'))) and (ssCtrl in Shift)) then
    Exit;
end;

procedure TfrmGNEncounter.pnlBaseNoteResize(Sender: TObject);
begin
  inherited;
  LimitEditWidth(memCommNote, 70);
end;

procedure TfrmGNEncounter.pnlSingleNotesResize(Sender: TObject);
begin
  inherited;
  LimitEditWidth(memIndvNote, 70);
end;

initialization
 SelectedPatient := '';
 StartOver := False;

end.
