//
// This source code resides at www.jaeckel.org/ImpliedNormalVolatility.7z .
//
// ======================================================================================
// Copyright © 2022 Peter Jäckel.
//
// Permission to use, copy, modify, and distribute this software is freely granted,
// provided that this notice is preserved.
//
// WARRANTY DISCLAIMER
// The Software is provided "as is" without warranty of any kind, either express or implied,
// including without limitation any implied warranties of condition, uninterrupted use,
// merchantability, fitness for a particular purpose, or non-infringement.
// ======================================================================================
//

#ifndef XLFUNCTONS_H
#define XLFUNCTONS_H

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "XLOper.h"
#include <vector>

class XLFunction {

public:

    std::string DLLName, XLName, DataCodes, ArgumentNames, FunctionDescription;
    std::vector<std::string> ArgumentDescriptions;

    static const std::vector<XLFunction> & DeclaredFunctions();

    // i=1; while [ $i -le 20 ] ; do  echo -n ", const char *a$i=0" ; i=$[ $i + 1 ] ; done
    // xl_name: if null, the dll_name is used. If it starts with period '.', then it is prefixed by the XLL name.
    // data_codes: see https://docs.microsoft.com/en-us/office/client-developer/excel/data-types-used-by-excel for the data type codes.
    static int Declare( const char *dll_name, const char *xl_name /* may be null */, const std::string & data_codes, const std::string &argument_names, const std::string & function_descripton, const char *a1=0, const char *a2=0, const char *a3=0, const char *a4=0, const char *a5=0, const char *a6=0, const char *a7=0, const char *a8=0, const char *a9=0, const char *a10=0, const char *a11=0, const char *a12=0, const char *a13=0, const char *a14=0, const char *a15=0, const char *a16=0, const char *a17=0, const char *a18=0, const char *a19=0, const char *a20=0);

    static int DeclareWithSynonyms( const char *dll_name, const char **xl_names /* must be null terminated */, const std::string & data_codes, const std::string &argument_names, const std::string & function_descripton, const char *a1=0, const char *a2=0, const char *a3=0, const char *a4=0, const char *a5=0, const char *a6=0, const char *a7=0, const char *a8=0, const char *a9=0, const char *a10=0, const char *a11=0, const char *a12=0, const char *a13=0, const char *a14=0, const char *a15=0, const char *a16=0, const char *a17=0, const char *a18=0, const char *a19=0, const char *a20=0);
    
    static int Declare( const char *dll_name, const std::vector<const char*> &xl_names /* need not be null terminated */, const std::string & data_codes, const std::string &argument_names, const std::string & function_descripton, const char *a1=0, const char *a2=0, const char *a3=0, const char *a4=0, const char *a5=0, const char *a6=0, const char *a7=0, const char *a8=0, const char *a9=0, const char *a10=0, const char *a11=0, const char *a12=0, const char *a13=0, const char *a14=0, const char *a15=0, const char *a16=0, const char *a17=0, const char *a18=0, const char *a19=0, const char *a20=0);
    
};

// NOTE: any (worksheet) function name specified with a leading '.' will be registered preceded by this XLL's name.

#define DECLARE_XL_FUNCTION( FUNCTION, EXCEL_FUNCTION_NAME, DATA_CODES, ARGUMENT_NAMES, FUNCTION_DESCRIPTION, ... ) static int xl_function_ ## FUNCTION = XLFunction::Declare( #FUNCTION, EXCEL_FUNCTION_NAME, DATA_CODES, ARGUMENT_NAMES, FUNCTION_DESCRIPTION, __VA_ARGS__ );

#define DECLARE_XL_FUNCTION_WITH_SYNOYMS( FUNCTION, EXCEL_FUNCTION_NAMES, DATA_CODES, ARGUMENT_NAMES, FUNCTION_DESCRIPTION, ... ) static int xl_function_ ## FUNCTION = XLFunction::DeclareWithSynonyms( #FUNCTION, EXCEL_FUNCTION_NAMES, DATA_CODES, ARGUMENT_NAMES, FUNCTION_DESCRIPTION, __VA_ARGS__ );

#endif // XLFUNCTONS_H
