(********************************************************************)
(*                                                                  *)
(*  tee.s7i       Filter file which emulates the tee functionality  *)
(*  Copyright (C) 1992, 1993, 1994, 2005, 2023  Thomas Mertes       *)
(*                                                                  *)
(*  This file is part of the Seed7 Runtime Library.                 *)
(*                                                                  *)
(*  The Seed7 Runtime Library is free software; you can             *)
(*  redistribute it and/or modify it under the terms of the GNU     *)
(*  Lesser General Public License as published by the Free Software *)
(*  Foundation; either version 2.1 of the License, or (at your      *)
(*  option) any later version.                                      *)
(*                                                                  *)
(*  The Seed7 Runtime Library is distributed in the hope that it    *)
(*  will be useful, but WITHOUT ANY WARRANTY; without even the      *)
(*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *)
(*  PURPOSE.  See the GNU Lesser General Public License for more    *)
(*  details.                                                        *)
(*                                                                  *)
(*  You should have received a copy of the GNU Lesser General       *)
(*  Public License along with this program; if not, write to the    *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


(**
 *  [[file|File]] implementation type to write to several destination files at once.
 *)
const type: teeFile is sub null_file struct
    var array file: destFiles is 0 times STD_NULL;
  end struct;


(**
 *  Open a tee file to write to the destination files given in ''destFiles''.
 *  @param destFiles Array with destination files.
 *  @return the ''teeFile'' opened.
 *)
const func file: openTee (in array file: destFiles) is func
  result
    var file: newFile is STD_NULL;
  local
    var teeFile: new_teeFile is teeFile.value;
  begin
    new_teeFile.destFiles := destFiles;
    newFile := toInterface(new_teeFile);
  end func;


(**
 *  Open a tee file to write to the destination files ''destFile1'' and ''destFile2''.
 *  @param destFile1 First destination file.
 *  @param destFile2 Second destination file.
 *  @return the ''teeFile'' opened.
 *)
const func file: openTee (in file: destFile1, in file: destFile2) is
  return openTee([](destFile1, destFile2));


(**
 *  Write the [[string]] ''stri'' to ''outFile''.
 *  The characters are forwarded to all destination files.
 *)
const proc: write (inout teeFile: outFile, in string: stri) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      write(destFile, stri);
    end for;
  end func;


(**
 *  Write end-of-line to ''outFile''.
 *  The end-of-line is forwarded to all destination files.
 *)
const proc: writeln (inout teeFile: outFile) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      writeln(destFile);
    end for;
  end func;


(**
 *  Forces that all buffered data of ''outFile'' is sent to its destination.
 *  This causes that all destination files are flushed.
 *)
const proc: flush (inout teeFile: outFile) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      flush(destFile);
    end for;
  end func;


const proc: moveLeft (inout teeFile: outFile, in string: stri) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      moveLeft(destFile, stri);
    end for;
  end func;


const proc: erase (inout teeFile: outFile, in string: stri) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      erase(destFile, stri);
    end for;
  end func;


const proc: cursorOn (inout teeFile: outFile, in char: cursorChar) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      cursorOn(destFile, cursorChar);
    end for;
  end func;


const proc: cursorOff (inout teeFile: outFile, in char: cursorChar) is func
  local
    var file: destFile is STD_NULL;
  begin
    for destFile range outFile.destFiles do
      cursorOff(destFile, cursorChar);
    end for;
  end func;