/*-*-c++-*-*****************************************************************
                             -------------------
    cvs         : $Id$
    begin       : Sat Aug 10 2002
    copyright   : (C) 2002, 2003 by Fabian Kaiser and Christian Stimming
    email       : fabian@openhbci.de

 ***************************************************************************
 *                                                                         *
 *   This 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.    *
 *                                                                         *
 *   This 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 library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

#include "ktoblzcheck.h"

/** @file
 * @brief Internal algorithms
 *
 * This file contains the internal algorithms that are used for
 * checking account numbers.
 */
#ifdef HAVE_LONG_LONG
# define long_long long long
#else
# define long_long long
#endif // HAVE_LONG_LONG

// forward declarations
void   multArray(const int *a, const int *b, int dest[10]);
/** @param source Must be array of size 10
 * @param dest DOCUMENTME
 * @param start DOCUMENTME
 * @param stop DOCUMENTME
*/
void   crossFoot(const int *source, int dest[10], int start, int stop);
/** @param source Must be array of size 10 */
void   crossFoot(int *source);
/** @param source Must be array of size 10
 * @param start DOCUMENTME
 * @param stop DOCUMENTME
*/
int    add(const int *source, int start, int stop);
/** @param source Must be array of size 10 */
inline int add_10(const int *source);
std::string array2Number(const int a[10]);
void   number2Array(const std::string &number, int a[10]);
long_long number2LongLong(const std::string &number);

int    algo03(const int modulus, const int weight[10], const bool crossfoot,
              const int accountId[10], const int startAdd, const int stopAdd);
int    algo03a(const int weight[10], const bool crossfoot, const int accountId[10],
               const int startAdd, const int stopAdd);
int    algo05(const int modulus1, const int modulus2, const int weight[10], const int accountId[10],
              const int startAdd, const int stopAdd);
AccountNumberCheck::Result
algo04(const std::string &bankId, const std::string accountId);
AccountNumberCheck::Result
algo04a(const std::string &bankId, const std::string accountId);
AccountNumberCheck::Result
algo06(const int accountId[10]);
AccountNumberCheck::Result
algo07(const int accountId[10], const int transform[6][10]);
AccountNumberCheck::Result
algo01(const int modulus, const int weight[10], const bool crossfoot, const int checkIndex,
       const int accountId[10]);
AccountNumberCheck::Result
algo02(const int modulus, const int weight[10], const int checkIndex, const int accountId[10],
       const int startAdd, const int stopAdd);

// std::string accnum_getRegKey(const char *value_name);
/** Returns the bankdata directory path as a string. */
std::string algorithms_get_bankdata_dir();
/** Initializes the runtime lookup code. Returns true if this was
    successful. */
bool algorithms_init_binreloc();

inline int add_10(const int *sp)
{
    return sp[0] + sp[1] + sp[2] + sp[3] + sp[4]
           + sp[5] + sp[6] + sp[7] + sp[8] + sp[9];
}
