// ================================================================================ //
//       THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.),        //
//                  AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT.                   //
//                                                                                  //
//     REPRODUCTION, DISCLOSURE,  OR USE,  IN WHOLE OR IN PART,  OTHER THAN AS      //
//     SPECIFIED  IN THE LICENSE ARE  NOT TO BE  UNDERTAKEN  EXCEPT WITH PRIOR      //
//                       WRITTEN AUTHORIZATION OF FEI S.A.S.                        //
//                                                                                  //
//                             RESTRICTED RIGHTS LEGEND                             //
//     USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS     //
//     WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN     //
//     SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT     //
//     CLAUSE  AT FAR 52.227-19  OR SUBPARAGRAPH  (C)(1)(II)  OF  THE RIGHTS IN     //
//        TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013.         //
//                                                                                  //
//                         COPYRIGHT (C) 2022 BY FEI S.A.S,                         //
//                                 BORDEAUX, FRANCE                                 //
//                               ALL RIGHTS RESERVED                                //
//                                                                                  //
// SEE http://assets.thermofisher.com/TFS-Assets/MSD/Licensing-Information/FEI_SAS_Thermo-Fisher-EULA_GLOBAL_With Usage Log_Nov2020.pdf //
//                              FOR MORE INFORMATION.                               //
// ================================================================================ //

#pragma once

#include <memory>
#include <string>

#include <iolink/view/ImageView.h>
#include <iolink/view/MultiImageView.h>

#include <ioformat/IOFormatAPI.h>

namespace ioformat
{

/**
 * A factory to save stacks of images.
 */
class IOFORMAT_API StackWriter
{
public:
  /**
   * Remove constructor, as this class is a static factory.
   */
  StackWriter() = delete;

  /**
   * Write a list of images to many files using a pattern to generate indexed filenames.
   *
   * Each frame of the input MultiImageView will be written as a separate file.
   *
   * @param multi The list of images to write as separated files.
   * @param outputFilePathPattern The pattern for the output file path. The pattern must contain one group of
   * consecutive '\%' characters, which will be replaced by the image index.
   *
   * The count of '\%' characters sets the minimum count of digits for printing the image index, but the printed index
   * may include additional digits.
   *
   * e.g.
   *      * `outputFilePattern = "output%%%%.png"` will create files named `output0000.png, output0001.png,
   * ...,outut0010.png, outut0011.png`,etc.
   *      * `outputFilePattern = "output%%.png"` will create files named `output00.png, output01.png, ...,
   * output10.png, ..., output100.png, output101.png`, etc.
   *      * `outputFilePattern = "output%.png"` will create files named `output0.png, output1.png, ..., output10.png,
   * output11.png`, etc.
   *
   * @throw InvalidArgument If the output file pattern is invalid.
   * @throw Error If an error occurs while writing the images.
   *
   */
  static void writeFromPattern(std::shared_ptr<iolink::MultiImageView> multi, const std::string& outputFilePathPattern);

  /**
   * Write a stack of images to many files using a pattern to generate indexed filenames.
   *
   * N-dimension image will be written as many N-1-dimension images.
   * Last dimension (N) is used as the stack dimension.
   *
   * e.g. a 3D image of size (10, 20, 30) will be written as 30 images of size (10, 20).
   *
   * @param stack The stack of images to write as separated files.
   * @param outputFilePathPattern The pattern for the output file path. The pattern must contain one group of
   * consecutive '\%' characters, which will be replaced by the image index.
   *
   * The count of '\%' characters sets the minimum count of digits for printing the image index, but the printed index
   * may include additional digits.
   *
   * e.g.
   *      * `outputFilePattern = "output%%%%.png"` will create files named `output0000.png, output0001.png,
   * ...,outut0010.png, outut0011.png`,etc.
   *      * `outputFilePattern = "output%%.png"` will create files named `output00.png, output01.png, ...,
   * output10.png, ..., output100.png, output101.png`, etc.
   *      * `outputFilePattern = "output%.png"` will create files named `output0.png, output1.png, ..., output10.png,
   * output11.png`, etc.
   *
   * @throw InvalidArgument If the output file pattern is invalid.
   * @throw UnsupportedOperation If the input image cannot be written as a stack.
   * @throw Error If an error occurs while writing the images.
   *
   */
  static void writeFromPattern(std::shared_ptr<iolink::ImageView> stack, const std::string& outputFilePathPattern);
};

} // end namespace ioformat
