/********************************************************
 *  ██████╗  ██████╗████████╗██╗
 * ██╔════╝ ██╔════╝╚══██╔══╝██║
 * ██║  ███╗██║        ██║   ██║
 * ██║   ██║██║        ██║   ██║
 * ╚██████╔╝╚██████╗   ██║   ███████╗
 *  ╚═════╝  ╚═════╝   ╚═╝   ╚══════╝
 * Geophysical Computational Tools & Library (GCTL)
 *
 * Copyright (c) 2023  Yi Zhang (yizhang-geo@zju.edu.cn)
 *
 * GCTL is distributed under a dual licensing scheme. 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 
 * of the License, or (at your option) any later version. You should have 
 * received a copy of the GNU Lesser General Public License along with this 
 * program. If not, see <http://www.gnu.org/licenses/>.
 * 
 * If the terms and conditions of the LGPL v.2. would prevent you from using 
 * the GCTL, please consider the option to obtain a commercial license for a 
 * fee. These licenses are offered by the GCTL's original author. As a rule, 
 * licenses are provided "as-is", unlimited in time for a one time fee. Please 
 * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget 
 * to include some description of your company and the realm of its activities. 
 * Also add information on how to contact you by electronic and paper mail.
 ******************************************************/

#ifndef _GCTL_SURFER_IO_H
#define _GCTL_SURFER_IO_H

// library's head files
#include "../core/matrix.h"
#include "file_io.h"

namespace gctl
{
	/**
	 * @brief      Golden Software Surfer 文件格式类型
	 */
	enum surfer_file_type_e
	{
		Surfer6Text, ///< 文本格式文件
		Surfer6Binary, ///< 二进制格式文件
		Surfer7Grid, ///< 二进制格式文件
	};

	/**
	 * @brief      读入 Golden Software Surfer format 6 网格文件
	 *
	 * @param      out_data   读入的网格（二维数组引用）
	 * @param      xmin       网格的 x 方向最小值（引用）
	 * @param      xmax       网格的 x 方向最大值（引用）
	 * @param      ymin       网格的 y 方向最小值（引用）
	 * @param      ymax       网格的 y 方向最大值（引用）
	 * @param      zmin       网格数据的最小值（引用）
	 * @param      zmax       网格数据的最大值（引用）
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param[in]  file_format 文件格式 默认为文本格式
	 */
	void read_surfer6_grid(std::string filename, _2d_matrix &out_data, int &xnum, int &ynum, 
		double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax, 
		surfer_file_type_e file_format = Surfer6Text);

	/**
	 * @brief      读入 Golden Software Surfer format 6 网格文件
	 *
	 * @param      out_data   读入的网格（一维数组引用，数组的排序默认为坐下到右上，列优先）
	 * @param      xmin       网格的 x 方向最小值（引用）
	 * @param      xmax       网格的 x 方向最大值（引用）
	 * @param      ymin       网格的 y 方向最小值（引用）
	 * @param      ymax       网格的 y 方向最大值（引用）
	 * @param      zmin       网格数据的最小值（引用）
	 * @param      zmax       网格数据的最大值（引用）
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param[in]  file_format 文件格式 默认为文本格式
	 */
	void read_surfer6_grid(std::string filename, array<double> &out_data, int &xnum, 
		int &ynum, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, 
		double &zmax, surfer_file_type_e file_format = Surfer6Text);

	/**
	 * @brief      写入 Golden Software Surfer format 6 网格文件
	 *
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param[in]  out_data   需要保存的网格（二维数组的常量引用）
	 * @param[in]  xmin       网格的 x 方向最小值
	 * @param[in]  xmax       网格的 x 方向最大值
	 * @param[in]  ymin       网格的 y 方向最小值
	 * @param[in]  ymax       网格的 y 方向最大值
	 * @param[in]  zmin       网格数据的最小值，默认为 NAN 。 此时函数会自动计算数组的最小值
	 * @param[in]  zmax       网格数据的最大值，默认为 NAN 。 此时函数会自动计算数组的最大值
	 * @param[in]  file_format 文件格式 默认为文本格式
	 */
	void save_surfer6_grid(std::string filename, const _2d_matrix &out_data, 
		double xmin, double xmax, double ymin, double ymax, double zmin = NAN, 
		double zmax = NAN, surfer_file_type_e file_format = Surfer6Text);

	/**
	 * @brief      写入 Golden Software Surfer format 6 网格文件
	 *
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param[in]  out_data   需要保存的网格（一维数组的常量引用，数据排序为左下到右上，列优先）
	 * @param[in]  xmin       网格的 x 方向最小值
	 * @param[in]  xmax       网格的 x 方向最大值
	 * @param[in]  ymin       网格的 y 方向最小值
	 * @param[in]  ymax       网格的 y 方向最大值
	 * @param[in]  zmin       网格数据的最小值，默认为 NAN 。 此时函数会自动计算数组的最小值
	 * @param[in]  zmax       网格数据的最大值，默认为 NAN 。 此时函数会自动计算数组的最大值
	 * @param[in]  file_format 文件格式 默认为文本格式
	 */
	void save_surfer6_grid(std::string filename, const array<double> &out_data, int xnum, int ynum, 
		double xmin, double xmax, double ymin, double ymax, double zmin = NAN, double zmax = NAN, 
		surfer_file_type_e file_format = Surfer6Text);

	/**
	 * @brief      读入 Golden Software Surfer format 7 网格文件
	 * 
	 * @warning    此函数暂不支持读入 Fault Info 数据段
	 *
	 * @param      out_data   读入的网格（二维数组引用）
	 * @param      xmin       网格的 x 方向最小值（引用）
	 * @param      ymin       网格的 y 方向最小值（引用）
	 * @param      dx         网格的 x 方向尺寸（引用）
	 * @param      dy         网格的 y 方向尺寸（引用）
	 * @param      zmin       网格数据的最小值（引用）
	 * @param      zmax       网格数据的最大值（引用）
	 * @param      blank_val  最大有效值，大于等于此值的数据将不在 Surfer 中显示
	 * @param[in]  filename   网格文件名（无后缀名）
	 */
	void read_surfer7_grid(std::string filename, _2d_matrix &out_data, 
		double &xmin, double &ymin, double &dx, double &dy, double &zmin, 
		double &zmax, double &blank_val);

	/**
	 * @brief      读入 Golden Software Surfer format 7 网格文件
	 * 
	 * @warning    此函数暂不支持读入 Fault Info 数据段
	 *
	 * @param      out_data   读入的网格（一维数组引用，数组的排序默认为坐下到右上，列优先）
	 * @param      xmin       网格的 x 方向最小值（引用）
	 * @param      ymin       网格的 y 方向最小值（引用）
	 * @param      dx         网格的 x 方向尺寸（引用）
	 * @param      dy         网格的 y 方向尺寸（引用）
	 * @param      zmin       网格数据的最小值（引用）
	 * @param      zmax       网格数据的最大值（引用）
	 * @param      blank_val  最大有效值，大于等于此值的数据将不在 Surfer 中显示
	 * @param[in]  filename   网格文件名（无后缀名）
	 */
	void read_surfer7_grid(std::string filename, array<double> &out_data, int &xnum, 
		int &ynum, double &xmin, double &ymin, double &dx, double &dy, double &zmin, 
		double &zmax, double &blank_val);

	/**
	 * @brief      写入 Golden Software Surfer format 7 网格文件
	 * 
	 * @warning    此函数暂不支持写入 Fault Info 数据段
	 *
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param      out_data   需要保存的网格（二维数组的常量引用）
	 * @param[in]  xmin       网格的 x 方向最小值
	 * @param[in]  ymin       网格的 y 方向最小值
	 * @param[in]  dx         网格的 x 方向尺寸
	 * @param[in]  dy         网格的 y 方向尺寸
	 * @param[in]  zmin       网格数据的最小值，默认为 NAN 。 此时函数会自动计算数组的最小值
	 * @param[in]  zmax       网格数据的最大值，默认为 NAN 。 此时函数会自动计算数组的最大值
	 * @param[in]  blank_val  最大有效值，大于等于此值的数据将不在 Surfer 中显示。默认值为 1.70141e38
	 */
	void save_surfer7_grid(std::string filename, const _2d_matrix &out_data, 
		double xmin, double ymin, double dx, double dy, double zmin = NAN, 
		double zmax = NAN, double blank_val = 1.70141e38);

	/**
	 * @brief      写入 Golden Software Surfer format 7 网格文件
	 * 
	 * @warning    此函数暂不支持写入 Fault Info 数据段
	 *
	 * @param[in]  filename   网格文件名（无后缀名）
	 * @param      out_data   需要保存的网格（一维数组的常量引用，数据排序为左下到右上，列优先）
	 * @param[in]  xmin       网格的 x 方向最小值
	 * @param[in]  ymin       网格的 y 方向最小值
	 * @param[in]  dx         网格的 x 方向尺寸
	 * @param[in]  dy         网格的 y 方向尺寸
	 * @param[in]  zmin       网格数据的最小值，默认为 NAN 。 此时函数会自动计算数组的最小值
	 * @param[in]  zmax       网格数据的最大值，默认为 NAN 。 此时函数会自动计算数组的最大值
	 * @param[in]  blank_val  最大有效值，大于等于此值的数据将不在 Surfer 中显示。默认值为 1.70141e38
	 */
	void save_surfer7_grid(std::string filename, const array<double> &out_data, 
		int xnum, int ynum, double xmin, double ymin, double dx, double dy, 
		double zmin = NAN, double zmax = NAN, double blank_val = 1.70141e38);
};

#endif // _GCTL_SURFER_IO_H