/******************************************************************************\
|*                                                                            *|
|*                           FingerCell Matcher 2.1                           *|
|*                                                                            *|
|* FncMatcher.h                                                               *|
|* Header file for FncMatcher module                                          *|
|*                                                                            *|
|* Copyright (C) 2006-2008 Neurotechnology                                    *|
|*                                                                            *|
\******************************************************************************/

#ifndef FNC_MATCHER_H_INCLUDED
#define FNC_MATCHER_H_INCLUDED

#include "FncmMatchDetails.h"
#include "FncMatcherParams.h"

#ifdef N_CPP
extern "C"
{
#endif

/**
 * \brief Handle to FncMatcher object.
 */
N_DECLARE_HANDLE(HFncMatcher);

#ifndef N_NO_ANSI_FUNC
NResult N_API FncmGetInfoA(NLibraryInfoA * pValue);
#endif
#ifndef N_NO_UNICODE
NResult N_API FncmGetInfoW(NLibraryInfoW * pValue);
#endif
#define FncmGetInfo N_FUNC_AW(FncmGetInfo)

/**
 * \brief Checks if FncMatcher library is registered.
 * 
 * \return #NTrue if library is registered, #NFalse otherwise.
 * 
 * \sa FncMatcher Module 
 */
NBool N_API FncmIsRegistered(void);

/**
 * \brief Copies parameter values from one FncMatcher to another.
 * 
 * \param[in] hDstMatcher Handle to the destination FncMatcher object. 
 * \param[in] hSrcMatcher Handle to the source FncMatcher object. 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hDstMatcher or \p hSrcMatcher is #NULL. </td></tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td>Identification is started on \p hDstMatcher. </td></tr>
 *          </table>
 * 
 * \sa FncMatcher Module | HFncMatcher 
 */
NResult N_API FncmCopyParameters(HFncMatcher hDstMatcher, HFncMatcher hSrcMatcher);

/**
 * \brief Creates a FncMatcher.
 * 
 * \param[out] pHMatcher Pointer to HFncMatcher that receives handle to created FncMatcher object 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p pHMatcher #NULL. </td></tr>
 *            <tr><td>#N_E_OUT_OF_MEMORY</td>
 *                <td>There was not enough memory. </td></tr>
 *          </table>
 * 
 * \sa FncMatcher Module | HFncMatcher 
 */
NResult N_API FncmCreate(HFncMatcher * pHMatcher);

/**
 * \brief Deletes the FncMatcher. After the object is deleted the specified handle is no longer valid.
 * 
 * \param[out] hMatcher Handle to FncMatcher object. 
 * 
 * \remark If hMatcher is NULL, does nothing.
 * 
 * \sa FncMatcher Module | HFncMatcher 
 */
void N_API FncmFree(HFncMatcher hMatcher);

/**
 * \brief Sets default values for all parameters of the specified FncMatcher
 * 
 * \param[in] hMatcher Handle to the FncMatcher object. 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hMatcher is #NULL.  </td></tr>
 *          </table>
 * 
 * \sa FncMatcher Module | HFncMatcher 
 */
NResult N_API FncmReset(HFncMatcher hMatcher);

/**
 * \brief  Compares two packed NFRecords using the specified FncMatcher.
 * 
 * \param[in] hMatcher Handle to the FncMatcher object. 
 * \param[in] template1 Pointer to memory buffer containing first packed #NFRecord. 
 * \param[in] template1Size Size of first packed #NFRecord. 
 * \param[in] template2 Pointer to memory buffer containing second packed #NFRecord. 
 * \param[in] template2Size Size of second packed #NFRecord. 
 * \param[in] ppMatchDetails Pointer to pointer to FncmMatchDetails that receives pointer to created match details. Can be #NULL. 
 * \param[out] pScore Pointer to #NInt that receives similarity score. 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hMatcher, \p template1, \p template2, or \p pScore is #NULL.  </td></tr>
 *            <tr><td>#N_E_END_OF_STREAM</td>
 *                <td> \p template1Size or \p template2Size is less than expected. . </td></tr>
 *            <tr><td>#N_E_FORMAT</td>
 *                <td> Data in memory buffer \p template1 or \p template2 points to is inconsistent with #NFRecord format. </td></tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td> Identification is started. </td></tr>
 *          </table>
 * 
 * \remark Value received via pScore is zero if similarity is less than matching threshold, i.e. two #NFRecord do not match <br>
 *          (see FNCMP_MATCHING_THRESHOLD and #FncmSetParameter function), and is greater than or equal to matching threshold otherwise. 
 * \remark If ppMatchDetails is not #NULL, the received pointer should be examined to obtain details of the matching. 
 * \remark Finally match details should be deleted using #FncmMatchDetailsFree function. 
 * 
 * \sa FncMatcher Module | HFncMatcher | FncmMatchDetails | FNCMP_MATCHING_THRESHOLD | FncmSetParameter | FncmMatchDetailsFree | FncmIdentifyStart | FncmIdentifyNext | FncmIdentifyEnd 
 */
NResult N_API FncmVerify(HFncMatcher hMatcher, const void * template1, NSizeType template1Size,
	const void * template2, NSizeType template2Size, FncmMatchDetails * * ppMatchDetails, NInt * pScore);

/**
 * \brief Starts identification with the specified packed #NFRecord using the specified FncMatcher.
 * 
 \param[in] hMatcher Handle to the FncMatcher object. 
 \param[in] templ Pointer to memory buffer containing packed #NFRecord. 
 \param[in] templSize Size of packed #NFRecord. 
 \param[in] ppMatchDetails Pointer to pointer to FncmMatchDetails that receives pointer to created match details. Can be #NULL.  
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hMatcheror \p templ is #NULL.  </td></tr>
 *            <tr><td>#N_E_END_OF_STREAM</td>
 *                <td> \p templateSize is less than expected. . </td></tr>
 *            <tr><td>#N_E_FORMAT</td>
 *                <td> Data in memory buffer \p templ points to is inconsistent with #NFRecord format. </td></tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td> Identification is started. </td></tr>
 *          </table>
 * 
 * \remark If ppMatchDetails is not NULL, the received pointer should be sequent passed to FncmIdentifyNext function to obtain details of the matching. 
 * \remark Finally match details should be deleted using #FncmMatchDetailsFree function. 
 * \sa FncMatcher Module | HFncMatcher | FncmMatchDetails | FncmMatchDetailsFree | FncmIdentifyNext | FncmIdentifyEnd 
 */
NResult N_API FncmIdentifyStart(HFncMatcher hMatcher, const void * templ, NSizeType templSize,
	FncmMatchDetails * * ppMatchDetails);

/**
 * \brief Compares the specified packed #NFRecord with the one identification was started with using the specified FncMatcher.
 * 
 * \param[in] hMatcher Handle to the FncMatcher object. 
 * \param[in] templ Pointer to memory buffer containing packed #NFRecord. 
 * \param[in] templSize Size of packed #NFRecord. 
 * \param[in, out] pMatchDetails Pointer to #FncmMatchDetails that is filled with details of the matching. Can be #NULL
 * \param[out] pScore Pointer to #NInt that receives similarity score. 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hMatcher or \p templ or \p pScore is #NULL.  </td></tr>
 *            <tr><td>#N_E_END_OF_STREAM</td>
 *                <td> \p templateSize is less than expected. . </td></tr>
 *            <tr><td>#N_E_FORMAT</td>
 *                <td> Data in memory buffer \p templ points to is inconsistent with #NFRecord format. </td></tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td> Identification is not started. </td></tr>
 *          </table>
 * \remark Value received via pScore is zero if similarity is less than matching threshold, i.e. two NFRecords do not match <br>
 *   (see #FNCMP_MATCHING_THRESHOLD and #FncmSetParameter function), and is greater than or equal to matching threshold otherwise. 
 * \remark If pMatchDetails is not #NULL it should be a pointer obtained using #FncmIdentifyStart function. 
 * * 
 * \sa FncMatcher Module | HFncMatcher | FncmMatchDetails | FNCMP_MATCHING_THRESHOLD | FncmSetParameter | FncmIdentifyStart | FncmIdentifyEnd 
 */
NResult N_API FncmIdentifyNext(HFncMatcher hMatcher, const void * templ, NSizeType templSize,
	FncmMatchDetails * pMatchDetails, NInt * pScore);

/**
 * \brief Ends identification using the specified FncMatcher.
 * 
 * \param[in] hMatcher Handle to the FncMatcher object. 
 * 
 * \return  If the function succeeds the return value is #N_OK. 
 * \return  If the function fails, the return value is one of the following 
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT_NULL</td>
 *                <td>\p hMatcher is #NULL.  </td></tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td> Identification is not started. </td></tr>
 *          </table>
 * \remark Value received via pScore is zero if similarity is less than matching threshold, i.e. two NFRecords do not match <br>
 *   (see #FNCMP_MATCHING_THRESHOLD and #FncmSetParameter function), and is greater than or equal to matching threshold otherwise. 
 * \remark If pMatchDetails is not #NULL it should be a pointer obtained using #FncmIdentifyStart function. 
 * 
 * \sa FncMatcher Module | HFncMatcher | FncmIdentifyStart | FncmIdentifyNext 
 */
NResult N_API FncmIdentifyEnd(HFncMatcher hMatcher);

#ifdef N_DOCUMENTATION
/**
 * \brief  Retrieves value of the parameter.
 * \param[in]  hMatcher     Handle to the matcher object.
 * \param[in]  parameterId  Identifier of the parameter to retrieve.
 * \param[out] pValue       Pointer to a variable that receives parameter
 *                          value.
 * \return  If the function succeeds and \p parameterId specifies
 *          #N_TYPE_STRING type parameter and \p pValue is #NULL, the return
 *          value is length of the string (not including NULL-terminator)
 *          \p pValue should point to.
 * \return  If the function succeeds and \p pValue is not #NULL, the return
 *          value is #N_OK.
 * \return  If the function fails, the return value is one of the following
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td rowspan="2">#N_E_ARGUMENT_NULL</td>
 *                <td>\p parameterId specifies a non-static parameter and
 *                \p hMatcher is #NULL</td></tr>
 *            <tr><td>\p parameterId specifies a non-#N_TYPE_STRING type
 *                parameter and \p pValue is #NULL.</td></tr>
 *            <tr><td>#N_E_PARAMETER</td>
 *                <td>\p parameterId is invalid.</td></tr>
 *          </table>
 * \remark  The following values can be used for \p parameterId:
 *          - #FNCMP_MATCHING_THRESHOLD
 *          - #FNCMP_NAME
 *          - #FNCMP_VERSION_HIGH
 *          - #FNCMP_VERSION_LOW
 *          - #FNCMP_COPYRIGHT
 * <br>
 *          To learn the type of parameter pass a value obtained with
 *          #NParameterMakeId macro using #N_PC_TYPE_ID code, the parameter
 *          identifier via \p parameterId and pointer to #NInt that will
 *          receive one of the N_TYPE_XXX via \p pValue parameter.
 *          \p hMatcher can be #NULL in this case.
 * \sa  HFncMatcher | FncmSetParameter
 *
 * Retrieves value of the specified parameter of the specified matcher
 * object.
 */
NResult N_API FncmGetParameter(HFncMatcher hMatcher, NUInt parameterId, void * pValue);

#else

#ifndef N_NO_ANSI_FUNC
NResult N_API FncmGetParameterA(HFncMatcher hMatcher, NUInt parameterId, void * pValue);
#endif
#ifndef N_NO_UNICODE
NResult N_API FncmGetParameterW(HFncMatcher hMatcher, NUInt parameterId, void * pValue);
#endif
#define FncmGetParameter N_FUNC_AW(FncmGetParameter)

#endif

#ifdef N_DOCUMENTATION
/**
 * \brief  Sets value of the parameter.
 * \param[in]  hMatcher     Handle to the matcher object. Can be #NULL if
 *                          setting static parameter value.
 * \param[in]  parameterId  Identifier of the parameter to set.
 * \param[in]  pValue       Pointer to the parameter value to set.
 * \return  If the function succeeds the return value is #N_OK.
 * \return  If the function fails, the return value is one of the following
 *          error codes:
 *          <table>
 *            <tr><th>Error Code</th><th>Condition</th></tr>
 *            <tr><td>#N_E_ARGUMENT</td>
 *                <td>\p pValue points to invalid value.</td></tr>
 *            <tr><td rowspan="2">#N_E_ARGUMENT_NULL</td>
 *                <td>\p parameterId specifies a non-static parameter and
 *                \p hMatcher is #NULL</td></tr>
 *            <tr><td>\p parameterId specifies a non-#N_TYPE_STRING type
 *                parameter and \p pValue is #NULL.</td></tr>
 *            <tr><td>#N_E_ARGUMENT_OUT_OF_RANGE</td>
 *                <td>\p pValue points to a value that is out of range.</td>
 *                </tr>
 *            <tr><td>#N_E_INVALID_OPERATION</td>
 *                <td>\p hMatcher is not #NULL and identification process is
 *                started.</td></tr>
 *            <tr><td>#N_E_PARAMETER</td>
 *                <td>\p parameterId is invalid.</td></tr>
 *            <tr><td>#N_E_PARAMETER_READ_ONLY</td>
 *                <td>\p parameterId specifies a read-only parameter.</td></tr>
 *          </table>
 * \remark  The following values can be used for \p parameterId:
 *          - #FNCMP_MATCHING_THRESHOLD
 *          - #FNCMP_NAME
 *          - #FNCMP_VERSION_HIGH
 *          - #FNCMP_VERSION_LOW
 *          - #FNCMP_COPYRIGHT
 * \sa  HFncMatcher | FncmGetParameter
 *
 * Sets value of the specified parameter of the specified matcher object.
 */
NResult N_API FncmSetParameter(HFncMatcher hMatcher, NUInt parameterId, const void * pValue);

#else

#ifndef N_NO_ANSI_FUNC
NResult N_API FncmSetParameterA(HFncMatcher hMatcher, NUInt parameterId, const void * pValue);
#endif
#ifndef N_NO_UNICODE
NResult N_API FncmSetParameterW(HFncMatcher hMatcher, NUInt parameterId, const void * pValue);
#endif
#define FncmSetParameter N_FUNC_AW(FncmSetParameter)

#endif


#ifndef N_NO_ANSI_FUNC
NResult N_API FncmGetParameterA(HFncMatcher hMatcher, NUInt parameterId, void * pValue);
#endif
#ifndef N_NO_UNICODE
NResult N_API FncmGetParameterW(HFncMatcher hMatcher, NUInt parameterId, void * pValue);
#endif
#define FncmGetParameter N_FUNC_AW(FncmGetParameter)

#ifndef N_NO_ANSI_FUNC
NResult N_API FncmSetParameterA(HFncMatcher hMatcher, NUInt parameterId, const void * pValue);
#endif
#ifndef N_NO_UNICODE
NResult N_API FncmSetParameterW(HFncMatcher hMatcher, NUInt parameterId, const void * pValue);
#endif
#define FncmSetParameter N_FUNC_AW(FncmSetParameter)

#ifdef N_CPP
}
#endif

#endif // !FNC_MATCHER_H_INCLUDED
