/****************************************************************************
** Leistungsorientierte Krankenanstaltenfinanzierung (LKF)                 **
** Scoring-C-Sourcen V2026.1                                               **
** (C) 2026 BMASGPK                                                        **
*****************************************************************************
** auf5.c - Routinen zum Zugriff auf Aufenthalts-Daten                     **
**                                                                         **
**		 Alex.Holzer@chello.at                                             **
**       Bernhard.Pesec@dothealth.at                                       **
***************************************************************************/


#include "lkfint5.h"
#include <ctype.h>


/**********************************************************************
** alloc_patient: Legt einen neuen, leeren Aufenthalts-Satz an       **
**********************************************************************/

_SCORING_EXPORT LKF_AUFENTHALT *lkf_alloc_aufenthalt2 (LKF_CONTEXT *pContext)
{
	LKF_AUFENTHALT *pAufenthalt = (LKF_AUFENTHALT *) LKF_CALLOC (pContext, "lkf_alloc_aufenthalt", 1, sizeof (LKF_AUFENTHALT));
    if (!pAufenthalt) return 0;
    
    /* V2026.1 -  memory opt. for large files */
	pAufenthalt->abt_alloc = 0;
    pAufenthalt->abt = 0;
	pAufenthalt->mel_alloc = 0;
    pAufenthalt->mel = 0;
	pAufenthalt->diag_alloc = 0;
    pAufenthalt->diag = 0;

	pAufenthalt->mark = 1;

	pAufenthalt->nSatzartFirstError = -1;
	pAufenthalt->nSatzartNextError = -1;
    pAufenthalt->indexInContext = -1;
    
	return pAufenthalt;
}

_SCORING_EXPORT LKF_AUFENTHALT *lkf_alloc_aufenthalt (void) {
    return lkf_alloc_aufenthalt2(0);
}

_SCORING_EXPORT LKF_AUFENTHALT *lkf_alloc_aufenthalt_context (LKF_CONTEXT *pContext)
{
    LKF_AUFENTHALT *pAufenthalt = lkf_alloc_aufenthalt2(pContext);
    if (pAufenthalt) {
        pAufenthalt->pScoringContext = pContext;
    }
    return pAufenthalt;
}


/**********************************************************************
** free_patient: Gibt einen Patienten frei                           **
**********************************************************************/


static void free_errorlist (LKF_ERROR_LIST **ppFirst, LKF_ERROR_LIST **ppLast)
{
	LKF_ERROR_LIST *pAct, *pNext;

	pAct = *ppFirst;
	
	while (pAct) {
		pNext = pAct->next;
		LKF_FREE (pAct->pContext, "free_errorlist", pAct);
		pAct = pNext;
	}

	*ppFirst = *ppLast = 0;
}

void lkf_free_aufenthalt_subgruppen (LKF_AUFENTHALT *pAufenthalt)
{
	
	if (pAufenthalt->subgruppe)
	{
        unsigned int i;
		for (i = 0; i < pAufenthalt->subgruppe_alloc; i++)
		{
			if (pAufenthalt->subgruppe[i].pMelZu)
				LKF_FREE (pAufenthalt->pScoringContext, "lkf_scoring_compute_subgruppen", pAufenthalt->subgruppe[i].pMelZu);
            if (pAufenthalt->subgruppe[i].plCurMELZU)
                LKF_FREE (pAufenthalt->pScoringContext, "plCurMELZU", pAufenthalt->subgruppe[i].plCurMELZU);
		}
		LKF_FREE (pAufenthalt->pScoringContext, "lkf_create_aufenthalt_subgruppen", pAufenthalt->subgruppe);
		pAufenthalt->subgruppe = 0;
	}
	pAufenthalt->subgruppe_alloc = 0;
    pAufenthalt->pat_subgruppen = 0;
}

unsigned int lkf_create_aufenthalt_subgruppen (LKF_AUFENTHALT *pAufenthalt, unsigned int nCount)
{
    lkf_free_aufenthalt_subgruppen (pAufenthalt);
	pAufenthalt->subgruppe_alloc = nCount;
	pAufenthalt->subgruppe = LKF_CALLOC (pAufenthalt->pScoringContext, "lkf_create_aufenthalt_subgruppen", sizeof (LKF_AUFENTHALT_SUBGRUPPE), nCount);
    if (pAufenthalt->subgruppe == 0) return 0;
    return nCount;
}

_SCORING_EXPORT void lkf_free_aufenthalt (LKF_AUFENTHALT *pAufenthalt)
{
    LKF_CONTEXT *pContext;
    pContext = pAufenthalt->pScoringContext;
    
	free_errorlist (&pAufenthalt->pFirstError, &pAufenthalt->pLastError);
	free_errorlist (&pAufenthalt->pFirstWarning, &pAufenthalt->pLastWarning);
	free_errorlist (&pAufenthalt->pFirstMeldeDiag, &pAufenthalt->pLastMeldeDiag);
	free_errorlist (&pAufenthalt->pFirstInfo, &pAufenthalt->pLastInfo);
	LKF_FREE (pContext, "lkf_free_aufenthalt.abt", pAufenthalt->abt);
	LKF_FREE (pContext, "lkf_free_aufenthalt.diag", pAufenthalt->diag);
	LKF_FREE (pContext, "lkf_free_aufenthalt.mel", pAufenthalt->mel);

	lkf_free_aufenthalt_subgruppen (pAufenthalt);

	if (pAufenthalt->akwarn) LKF_FREE (pContext, "lkf_free_aufenthalt.akwarn", pAufenthalt->akwarn);
	if (pAufenthalt->pOrig) LKF_FREE (pContext, "lkf_free_aufenthalt.pOrig", pAufenthalt->pOrig);
	if (pAufenthalt->kommentar) LKF_FREE (pContext, "lkf_free_aufenthalt.kommentar", pAufenthalt->kommentar);

	if (pAufenthalt->pIntAufenthalt) lkf_int_free_aufenthalt (pContext, pAufenthalt->pIntAufenthalt);
	if (pAufenthalt->pLineBuffer) lkf_drop_linebuffer (pContext, pAufenthalt->pLineBuffer);
    
	if (pAufenthalt->psLineExt) LKF_FREE (pContext, "lkf_free_aufenthalt.psLineExt", pAufenthalt->psLineExt);

	if (pAufenthalt->pMelMel) LKF_FREE (pContext, "lkf_free_aufenthalt.pMelMel", pAufenthalt->pMelMel);
    if (pAufenthalt->pMelMelInfo) LKF_FREE (pContext, "lkf_free_aufenthalt.pMelMelInfo", pAufenthalt->pMelMelInfo);
    
    if (pAufenthalt->pIntensiv) lkf_free_expandedLines(pAufenthalt->pIntensiv);
    
    if (pAufenthalt->pScoringDetails)
        lkf_scoringdetails_free (pAufenthalt);
    
    if (pAufenthalt->pCategory) {
        LKF_FREE (pContext, "lkf_free_aufenthalt.pCategory",pAufenthalt->pCategory);
    }
    
	LKF_FREE (pContext, "lkf_free_aufenthalt", pAufenthalt);
}

/**********************************************************************
** lkf_reset_patient: Löscht die Inhalte des Aufenthalts             **
**********************************************************************/

void lkf_reset_aufenthalt_internal (LKF_AUFENTHALT *pAufenthalt, int keepX01)
{
	LKF_AUFENTHALT_ABT *pAbt;
	LKF_AUFENTHALT_MEL *pMEL;
	LKF_AUFENTHALT_DIAG *pDiag;
    LKF_CONTEXT *pContext;

	unsigned int abt_alloc, diag_alloc, mel_alloc;
	    
    free_errorlist (&pAufenthalt->pFirstError, &pAufenthalt->pLastError);
    free_errorlist (&pAufenthalt->pFirstWarning, &pAufenthalt->pLastWarning);
    free_errorlist (&pAufenthalt->pFirstMeldeDiag, &pAufenthalt->pLastMeldeDiag);
    free_errorlist (&pAufenthalt->pFirstInfo, &pAufenthalt->pLastInfo);
    
    lkf_free_aufenthalt_subgruppen (pAufenthalt);
    pAufenthalt->pat_subgruppen = 0;

    if (pAufenthalt->pOrig) {
        LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.pOrig", pAufenthalt->pOrig);
        pAufenthalt->pOrig = 0;
    }

    if (pAufenthalt->kommentar) {
        LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.kommentar", pAufenthalt->kommentar);
        pAufenthalt->kommentar = 0;
        pAufenthalt->kommentar_anz = 0;
        pAufenthalt->kommentar_alloc = 0;
    }
    
    if (pAufenthalt->pIntAufenthalt) {
        lkf_int_free_aufenthalt (pAufenthalt->pScoringContext, pAufenthalt->pIntAufenthalt);
        pAufenthalt->pIntAufenthalt = 0;
    }

    if (pAufenthalt->pLineBuffer) {
        lkf_drop_linebuffer(pAufenthalt->pScoringContext, pAufenthalt->pLineBuffer);
        pAufenthalt->pLineBuffer = 0;
    }

    pAufenthalt->nSatzartFlags = 0;

    if (pAufenthalt->psLineExt)
    {
        LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.psLineExt", pAufenthalt->psLineExt);
        pAufenthalt->nLineExtAlloc = 0;
        pAufenthalt->nLineExtCount = 0;
        pAufenthalt->psLineExt = 0;
    }
    
    if (pAufenthalt->pMelMel)
    {
            LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.pMelMel", pAufenthalt->pMelMel);
            pAufenthalt->pMelMel = 0;
    }

    if (pAufenthalt->pMelMelInfo)
    {
            LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.pMelMelInfo", pAufenthalt->pMelMelInfo);
            pAufenthalt->pMelMelInfo = 0;
    }
    
    if (pAufenthalt->pIntensiv) {
        lkf_free_expandedLines(pAufenthalt->pIntensiv);
        pAufenthalt->pIntensiv = 0;
    }

    if (keepX01) {
        pAufenthalt->abt_anz = 0;
        pAufenthalt->mel_anz = 0;
        pAufenthalt->diag_anz = 0;
        pAufenthalt->hdiag_anz = 0;
        pAufenthalt->akwarn_anz = 0;
        pAufenthalt->GESVD = 0;
        pAufenthalt->GESVD_KORR = 0;
        pAufenthalt->nM01ExtOffset = 0;
        pAufenthalt->nM05ExtOffset = 0;
        pAufenthalt->nM06ExtOffset = 0;
        pAufenthalt->nM08ExtOffset = 0;
        pAufenthalt->nMelMelCount = 0;
        pAufenthalt->nStatus = 0;
        pAufenthalt->TKLModus = 0;
        pAufenthalt->melabt_ok = 0;
    }
    else {
        abt_alloc = pAufenthalt->abt_alloc;
        mel_alloc = pAufenthalt->mel_alloc;
        diag_alloc = pAufenthalt->diag_alloc;

        pAbt = pAufenthalt->abt;
        pMEL = pAufenthalt->mel;
        pDiag = pAufenthalt->diag;

        if (pAufenthalt->akwarn) {
            pAufenthalt->akwarn_anz = 0;
            pAufenthalt->akwarn_alloc = 0;
            LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.akwarn", pAufenthalt->akwarn);
            pAufenthalt->akwarn = 0;
        }

        pContext = pAufenthalt->pScoringContext;
        memset (pAufenthalt, 0, sizeof (LKF_AUFENTHALT));
        pAufenthalt->pScoringContext = pContext; /* V2019.0: Context nicht loeschen */

        pAufenthalt->abt = pAbt;
        pAufenthalt->mel = pMEL;
        pAufenthalt->diag = pDiag;
        pAufenthalt->abt_alloc = abt_alloc;
        pAufenthalt->mel_alloc = mel_alloc;
        pAufenthalt->diag_alloc = diag_alloc;
        pAufenthalt->indexInContext = -1;
        pAufenthalt->mark = 1;
    }
    pAufenthalt->nSatzartFirstError = -1;
    pAufenthalt->nSatzartNextError = -1;

    if (pAufenthalt->pCategory) {
        pAufenthalt->category_alloc = pAufenthalt->category_count = 0;
        LKF_FREE (pAufenthalt->pScoringContext, "lkf_reset_aufenthalt_internal.category", pAufenthalt->pCategory);
        pAufenthalt->pCategory = 0;
    }
}

_SCORING_EXPORT void lkf_reset_aufenthalt (LKF_AUFENTHALT *pAufenthalt)
{
    lkf_reset_aufenthalt_internal(pAufenthalt, 0);
}

/**********************************************************************
** lkf_auf_reset_diag: Löschung aller Diagnosen des Aufenthalts      **
**********************************************************************/

_SCORING_EXPORT void lkf_auf_reset_diag (LKF_AUFENTHALT *pAufenthalt)
{
	pAufenthalt->diag_anz = 0;
	pAufenthalt->hdiag_anz = 0;
	memset (pAufenthalt->HD, ' ', LKF_AUFENTHALT_DIAG_LEN);
}

/**********************************************************************
** lkf_auf_reset_mel: Löschung aller Leistungen des Aufenthalts      **
**********************************************************************/

_SCORING_EXPORT void lkf_auf_reset_mel (LKF_AUFENTHALT *pAufenthalt)
{
	pAufenthalt->mel_anz = 0;
}

/**********************************************************************
** lkf_auf_reset_abt: Löscht die Abteilungen des Aufenthalts         **
**********************************************************************/

_SCORING_EXPORT void lkf_auf_reset_abt (LKF_AUFENTHALT *pAufenthalt)
{
	pAufenthalt->abt_anz = 0;
}


/**********************************************************************
** lkf_aufenthalt_plaus_init: Initialisiert den Aufenthalt fuer die  **
**     Plausibilitaetsueberpruefung.                                 **
**********************************************************************/

void lkf_aufenthalt_plaus_init (LKF_AUFENTHALT *pAufenthalt)
{
    unsigned int i;
    
	free_errorlist (&pAufenthalt->pFirstError, &pAufenthalt->pLastError);
	free_errorlist (&pAufenthalt->pFirstWarning, &pAufenthalt->pLastWarning);
	free_errorlist (&pAufenthalt->pFirstMeldeDiag, &pAufenthalt->pLastMeldeDiag);
	free_errorlist (&pAufenthalt->pFirstInfo, &pAufenthalt->pLastInfo);

	pAufenthalt->plaus_err = 0;
	pAufenthalt->plaus_warn = 0;
	pAufenthalt->akwarn_count = 0;
	pAufenthalt->akerr_count = 0;

	pAufenthalt->plaus_info = 0;
	pAufenthalt->akinfo_count = 0;

	pAufenthalt->melde_count = 0;
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        memcpy (pAufenthalt->mel[i].MEL, pAufenthalt->mel[i].ORIG_MEL, 5);
        memcpy (pAufenthalt->mel[i].MELANZ, pAufenthalt->mel[i].ORIG_MELANZ, 4);
    }
    
    pAufenthalt->status  = 0;
}


_SCORING_EXPORT unsigned int lkf_add_kost (LKF_AUFENTHALT *pAufenthalt, const char *kost)
{
	memcpy (pAufenthalt->KOST, kost, 2);
	return 0;
}



/**********************************************************************
** lkf_add_abt, lkf_add_abt2: Fügen dem Patientensatz eine           **
** Verlegungsinformation hinzu.                                      **
**********************************************************************/

_SCORING_EXPORT unsigned int lkf_add_abt2 (LKF_AUFENTHALT *pAufenthalt, const char *abtfc, const char *abtdat, const char *abtpos, const char *intdata)
{ /* Speichert auch zusaetzliche Informationen, die fuer Intensiv-Scoring gemeldet wurden */
	return lkf_add_abt3 (pAufenthalt, abtfc, abtdat, abtpos, intdata, 0);
}

_SCORING_EXPORT unsigned int lkf_add_abt3 (LKF_AUFENTHALT *pAufenthalt, const char *abtfc, const char *abtdat, const char *abtpos, const char *intdata, const char *addinfo)
{ /* Zusatzinformationen mitspeichern und ausgeben */
 	unsigned int i;
	char pos[4];
	pAufenthalt->nStatus = 0;

	if (pAufenthalt->abt_anz == pAufenthalt->abt_alloc) {
		pAufenthalt->abt_alloc += pAufenthalt->abt_alloc > 0 ? LKF_AUFENTHALT_EXTEND_ABT : 2;
		pAufenthalt->abt = (LKF_AUFENTHALT_ABT *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_abt3", pAufenthalt->abt, sizeof (LKF_AUFENTHALT_ABT) * pAufenthalt->abt_alloc);
        if (!pAufenthalt->abt) return LKF_OUTOFMEMORY_UINTERROR;
	}

	i = pAufenthalt->abt_anz++;

    memset (pAufenthalt->abt + i, 0, sizeof (LKF_AUFENTHALT_ABT));
    
	strncpy (pAufenthalt->abt[i].ABTFC, abtfc, LKF_AUFENTHALT_ABTFC_LEN);
	strncpy (pAufenthalt->abt[i].ABTDAT, abtdat, LKF_AUFENTHALT_DAT_LEN);
	strncpy (pAufenthalt->abt[i].ABTPOS, abtpos, LKF_AUFENTHALT_ABTPOS_LEN_2017);
	strncpy(pos, abtpos, LKF_AUFENTHALT_ABTPOS_LEN_2017);
	pos[3] = 0;
	pAufenthalt->abt[i].abtposNumeric = (unsigned int) atoi(pos);
	pAufenthalt->abt[i].ABTVD = 0;
	pAufenthalt->abt[i].ABTVD_KORR = 0;
	memset (pAufenthalt->abt[i].ABT_INTSATZ, 0, LKF_AUFENTHALT_ABT_INTSATZ_LEN_FONDS + 1);
	if (intdata) {

        unsigned int l;
        strncpy (pAufenthalt->abt[i].ABT_INTSATZ, intdata, LKF_AUFENTHALT_ABT_INTSATZ_LEN_FONDS);
        l = (unsigned int) strlen (pAufenthalt->abt[i].ABT_INTSATZ);
        while (l > 0 && (pAufenthalt->abt[i].ABT_INTSATZ[l-1] == 10 || pAufenthalt->abt[i].ABT_INTSATZ[l-1] == 13))
        {
            pAufenthalt->abt[i].ABT_INTSATZ[--l] = 0;
        }
        
        if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
            LKF_AUFENTHALT_ABT *pAbt = pAufenthalt->abt + i;
            unsigned int offset = (pAufenthalt->pScoringContext->flags & LKFCONTEXT_NICHTFONDSKA) ? 22 : 0;
            unsigned int opos = 26 - offset;
            
            if (opos + 8 <= l)
                memcpy (pAbt->ENTDAT, pAbt->ABT_INTSATZ + opos, 8);
            
            if (l >= 4)
                memcpy (pAbt->ABTZEIT, pAbt->ABT_INTSATZ, 4);
            
            opos = 34 - offset;
            if (opos + 4 <= l)
                memcpy (pAbt->ENTZEIT, pAbt->ABT_INTSATZ + opos, 4);
            
            opos += 4;
            if (l > opos)
                pAbt->ENTART = pAbt->ABT_INTSATZ[opos];
        }
	}
    
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
        int opos; /* 19.1 */
        int lenAddInfo = addinfo ? (int) strlen(addinfo) : 0;
        
        if (lenAddInfo > 17) {
            CopyLTrim(pAufenthalt->abt[i].ALTERSGRUPPE, addinfo + 17, 3);
            pAufenthalt->abt[i].ALTERSGRUPPE[3] = 0;
            for (opos = 2; opos >= 0; --opos) {
                if (pAufenthalt->abt[i].ALTERSGRUPPE[opos] == ' ') pAufenthalt->abt[i].ALTERSGRUPPE[opos] = 0;
                else break;
            }
        }
        else
            pAufenthalt->abt[i].ALTERSGRUPPE[0] = 0;
        
        if (lenAddInfo > 16)
            pAufenthalt->abt[i].ISNEONAT = addinfo[16];
        else
            pAufenthalt->abt[i].ISNEONAT = ' ';
    }
	pAufenthalt->abt[i].nExtOffset = addinfo ? lkf_auf_add_ext (pAufenthalt, addinfo) : 0;

	return i;
}

_SCORING_EXPORT unsigned int lkf_add_abt (LKF_AUFENTHALT *pAufenthalt, const char *abtfc, const char *abtdat, const char *abtpos)
{
	return lkf_add_abt2 (pAufenthalt, abtfc, abtdat, abtpos, 0);
}

/**********************************************************************
** lkf_add_diag, lkf_add_diag2:                                      **
**      Fügen dem Patientensatz eine Diagnose hinzu                  **
**********************************************************************/

_SCORING_EXPORT unsigned int lkf_add_diag2 (LKF_AUFENTHALT *pAufenthalt, const char *diag, const char *type, const char *pos)
{
	return lkf_add_diag4 (pAufenthalt, diag, type, pos, 0, 0);
}

_SCORING_EXPORT unsigned int lkf_add_diag3 (LKF_AUFENTHALT *pAufenthalt, const char *diag, const char *type, const char *pos, const char *addinfo)
{
    return lkf_add_diag4 (pAufenthalt, diag, type, pos, 0, addinfo);
}

_SCORING_EXPORT unsigned int lkf_add_diag4 (LKF_AUFENTHALT *pAufenthalt, const char *diag, const char *type, const char *pos, const char *addfields, const char *addinfo)
{ /* Zusatzinformationen speichern */
	char *d;
    LKF_AUFENTHALT_DIAG *pDiag;

	pAufenthalt->nStatus = 0;

    if (pAufenthalt->diag_anz == pAufenthalt->diag_alloc) {
        pAufenthalt->diag_alloc += pAufenthalt->diag_alloc > 0 ? LKF_AUFENTHALT_EXTEND_DIAG : 2;
        pAufenthalt->diag = (LKF_AUFENTHALT_DIAG *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_diag4", pAufenthalt->diag, sizeof (LKF_AUFENTHALT_DIAG) * pAufenthalt->diag_alloc);
        if (!pAufenthalt->diag) return LKF_OUTOFMEMORY_UINTERROR;
    }

    pDiag = pAufenthalt->diag + pAufenthalt->diag_anz;
    memset (pAufenthalt->diag + pAufenthalt->diag_anz, 0, sizeof (LKF_AUFENTHALT_DIAG));
    
    if (pos) strncpy (pDiag->DIAGPOS, pos, 4);
    else pDiag->DIAGPOS[0] = 0;

    pDiag->nExtOffset = addinfo ? lkf_auf_add_ext (pAufenthalt, addinfo) : 0;
    
    if (type[0] == ' ') {
        memcpy (pDiag->DIAGTYP, type + 1, 1);
        pDiag->DIAGTYP[1] = 0;
    }
    else {
        memcpy (pDiag->DIAGTYP, type, 2);
    }
    
    pDiag->isHD = pDiag->DIAGTYP[0] == 'H';
    

    if (addfields) {
        pAufenthalt->diag[pAufenthalt->diag_anz].DIAGART = addfields[0];
    }
    d = pAufenthalt->diag[pAufenthalt->diag_anz++].DIAG;
    CopyLTrim (d, diag, LKF_AUFENTHALT_DIAG_LEN);
    if (type[0] == 'H') {
        if (pAufenthalt->hdiag_anz == 0) {
            memcpy (pAufenthalt->HD, d, LKF_AUFENTHALT_DIAG_LEN);
        }
        pAufenthalt->hdiag_anz++;
    }

	return pAufenthalt->diag_anz;
}


_SCORING_EXPORT unsigned int lkf_add_diag (LKF_AUFENTHALT *pAufenthalt, const char *diag, const char *type)
{
	return lkf_add_diag4 (pAufenthalt, diag, type, 0, 0, 0);
}

/***********************************************************************
** lkf_add_mel, lkf_add_mel2, lkf_add_mel3, lkf_add_mel4              **
**      Fügt dem Patientensatz eine med. Leistung hinzu.              **
***********************************************************************/

_SCORING_EXPORT unsigned int lkf_add_mel (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz)
{
    return lkf_add_mel5 (pAufenthalt, mel, melanz, 0, 0, 0, 0);
}

_SCORING_EXPORT unsigned int lkf_add_mel6  (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz, const char *meldat, const char *melpos, const char *melzeit, const char *seite, const char *fcleist, const char *kaleist, const char *addinfo) {
    unsigned int i,j;

    pAufenthalt->nStatus = 0; /* V12.0 */

    if (pAufenthalt->mel_anz == pAufenthalt->mel_alloc) {
        pAufenthalt->mel_alloc += pAufenthalt->mel_alloc > 0 ? LKF_AUFENTHALT_EXTEND_MEL : 2;
        pAufenthalt->mel = (LKF_AUFENTHALT_MEL *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_mel6", pAufenthalt->mel, sizeof (LKF_AUFENTHALT_MEL) * pAufenthalt->mel_alloc);
        if (!pAufenthalt->mel) return LKF_OUTOFMEMORY_UINTERROR;
    }

    i = pAufenthalt->mel_anz++;

    memset (pAufenthalt->mel + i, 0, sizeof (LKF_AUFENTHALT_MEL));

    strncpy (pAufenthalt->mel[i].MEL, mel, LKF_AUFENTHALT_NEWMEL_LEN);
    strncpy (pAufenthalt->mel[i].MELANZ, melanz, LKF_AUFENTHALT_MELANZ_LEN);
    strncpy (pAufenthalt->mel[i].ORIG_MEL, mel, LKF_AUFENTHALT_ORIGMEL_LEN);
    j = 0;
    while (j<10 && mel[j]) ++j;
    if (j < 10)
        pAufenthalt->mel[i].MEL_RELEVANT = ' ';
    else
        pAufenthalt->mel[i].MEL_RELEVANT = pAufenthalt->mel[i].ORIG_MEL[9];
    
    if (j < 9)
        pAufenthalt->mel[i].cSeite = ' ';
    else
        pAufenthalt->mel[i].cSeite = pAufenthalt->mel[i].ORIG_MEL[8];
    
    strncpy (pAufenthalt->mel[i].ORIG_MELANZ, melanz, LKF_AUFENTHALT_ORIGMELANZ_LEN);
    if (meldat) strncpy (pAufenthalt->mel[i].MELDAT, meldat, LKF_AUFENTHALT_DAT_LEN);
    else memset (pAufenthalt->mel[i].MELDAT, ' ', LKF_AUFENTHALT_DAT_LEN);
    if (melpos) strncpy (pAufenthalt->mel[i].MELPOS, melpos, 4);
    else memset (pAufenthalt->mel[i].MELPOS, ' ', 4);
    pAufenthalt->mel[i].mel_nr = -1;
    pAufenthalt->mel[i].nExtOffset = addinfo ? lkf_auf_add_ext (pAufenthalt, addinfo) : 0;
    pAufenthalt->mel[i].mel_nr = -1;
    pAufenthalt->mel[i].nMelAbtIndex = -1;
    
    if (melzeit) {
        sprintf (pAufenthalt->mel[i].MELZEIT, "%-4.4s", melzeit);
    }
    
    if (kaleist) {
        char buf[8];
        sprintf(buf, "%-6.6s", kaleist);
        memcpy (pAufenthalt->mel[i].KALEIST, buf, 6);
    }
    
    if (fcleist)  {
        char buf[10];
        sprintf(buf, "%-8.8s", fcleist);
        memcpy(pAufenthalt->mel[i].FCLEIST, buf, 8);
    }
    
    if (seite)  {
		pAufenthalt->mel[i].cSeite = *seite;
    }

    return i;

}

_SCORING_EXPORT unsigned int lkf_add_mel5  (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz, const char *meldat, const char *melpos, const char *melzeit, const char *addinfo)
{
    return lkf_add_mel6 (pAufenthalt, mel, melanz, meldat, melpos, melzeit, 0, 0, 0, addinfo);
}

_SCORING_EXPORT unsigned int lkf_add_mel4  (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz, const char *meldat, const char *melpos, const char *addinfo)
{
    return lkf_add_mel5(pAufenthalt, mel, melanz, meldat, melpos, 0, addinfo);
}

_SCORING_EXPORT unsigned int lkf_add_mel3  (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz, const char *meldat, const char *melpos)
{
	return lkf_add_mel5 (pAufenthalt, mel, melanz, meldat, melpos, 0, 0);
}

_SCORING_EXPORT unsigned int lkf_add_mel2 (LKF_AUFENTHALT *pAufenthalt, const char *mel, const char *melanz, const char *meldat)
{
	return lkf_add_mel5 (pAufenthalt, mel, melanz, meldat, 0, 0, 0);
}



/************************************************************************
** lkf_add_akwarn: Fügt dem AKWARN-Array eine Warning hinzu.           **
************************************************************************/

_SCORING_EXPORT unsigned int lkf_add_akwarn (LKF_AUFENTHALT *pAufenthalt, const char *tcode, const char *value, const char *komm)
{
	unsigned int i, l;
    int code;
	unsigned int severity;
    int valueLen;
    int maxValueLen;

	code = 0;

	if (tcode[0] == 'e' || tcode[0] == 'E') {
		if (tcode[1] == 'M' || tcode[1] == 'm' || tcode[1] == 'X') /* V21.0 */
		{
			code = (int) lkf_getErrorIntFromCode (tcode + 2);
		}
		severity = LKF_SEV_ERROR;
	}
	else if (tcode[0] == 'w' || tcode[0] == 'W') {
		if (tcode[1] == 'M' || tcode[1] == 'm' || tcode[1] == 'X') /* V21.0 */
			code = (int) lkf_getErrorIntFromCode (tcode + 2);
		severity = LKF_SEV_WARNING;
	}
	else if (tcode[0] == 'h' || tcode[0] == 'H') {
		if (tcode[1] == 'M' || tcode[1] == 'm'  || tcode[1] == 'X') /* V21.0 */
			code = (int) lkf_getErrorIntFromCode (tcode + 2);
		severity = LKF_SEV_INFO;
	}

	else return 0xFFFFFFFF;

	if (pAufenthalt->akwarn_alloc == pAufenthalt->akwarn_anz) {
        if (pAufenthalt->akwarn) {
            pAufenthalt->akwarn = LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_akwarn", pAufenthalt->akwarn, sizeof (LKF_AUFENTHALT_AKWARN) * (pAufenthalt->akwarn_alloc += 5));
            if (pAufenthalt->akwarn == 0) {
                pAufenthalt->akwarn_alloc = pAufenthalt->akwarn_count = 0;
                return LKF_OUTOFMEMORY_UINTERROR;
            }
        }
        else {
            pAufenthalt->akwarn = LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_akwarn", sizeof (LKF_AUFENTHALT_AKWARN) * (pAufenthalt->akwarn_alloc += 5));
            if (pAufenthalt->akwarn == 0) {
                pAufenthalt->akwarn_alloc = pAufenthalt->akwarn_count = 0;
                return LKF_OUTOFMEMORY_UINTERROR;
            }

        }
        if (!pAufenthalt->akwarn) {
            lkf_set_outOfMemory(pAufenthalt->pScoringContext, "lkf_add_akwarn", 0);
            return 0xFFFFFFFF;
        }
	}

	for (i = 0; i < pAufenthalt->akwarn_anz && pAufenthalt->akwarn[i].code <= code; i++) ;
	
	if (i < pAufenthalt->akwarn_anz)
		memmove (pAufenthalt->akwarn + i + 1, pAufenthalt->akwarn + i, sizeof (LKF_AUFENTHALT_AKWARN) * (pAufenthalt->akwarn_anz - i));
	pAufenthalt->akwarn_anz++;

	pAufenthalt->akwarn[i].code = code;
	strncpy (pAufenthalt->akwarn[i].kommentar, komm, 200);
	pAufenthalt->akwarn[i].kommentar[200] = 0;
	pAufenthalt->akwarn[i].severity = severity;
	pAufenthalt->akwarn[i].nHitCount = 0;
    pAufenthalt->akwarn[i].acceptedValue[0] = 0;
    pAufenthalt->akwarn[i].followUpIndex = 0;

	l = (unsigned int) strlen (pAufenthalt->akwarn[i].kommentar);
	if (l > 0 && pAufenthalt->akwarn[i].kommentar[l-1] == '\n')
		pAufenthalt->akwarn[i].kommentar[l-1] = 0;

#ifdef SUPPORT_PRE2017
    maxValueLen = (pAufenthalt->pScoringContext == 0 || pAufenthalt->pScoringContext->modelljahr >= 2017) ? 20 : 10;
#else
    maxValueLen = 20;
#endif
	valueLen = simTrim (pAufenthalt->akwarn[i].value, value, maxValueLen);
	if (valueLen < maxValueLen)
        pAufenthalt->akwarn[i].value[valueLen] = 0;
    else
        pAufenthalt->akwarn[i].value[maxValueLen] = 0;

	memcpy (pAufenthalt->akwarn[i].s4DigitCode, tcode, 4);
	return i;
}

/************************************************************************
** lkf_add_komm: Fügt dem Patienten einen Kommentar hinzu.             **
************************************************************************/

_SCORING_EXPORT unsigned int lkf_add_komm (LKF_AUFENTHALT *pAufenthalt, const char *komm)
{
	unsigned int l;
	
	if (pAufenthalt->kommentar_alloc == pAufenthalt->kommentar_anz) {
		pAufenthalt->kommentar = LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_komm", pAufenthalt->kommentar, sizeof (LKF_AUFENTHALT_KOMMENTAR) * (pAufenthalt->kommentar_alloc += 5));
	}

	strncpy (pAufenthalt->kommentar[pAufenthalt->kommentar_anz].kommentar, komm, 200);
	pAufenthalt->kommentar[pAufenthalt->kommentar_anz].kommentar[200] = 0;

	l = (unsigned int) strlen (pAufenthalt->kommentar[pAufenthalt->kommentar_anz].kommentar);
	if (l > 0 && pAufenthalt->kommentar[pAufenthalt->kommentar_anz].kommentar[l-1] == '\n')
		pAufenthalt->kommentar[pAufenthalt->kommentar_anz].kommentar[l-1] = 0;


	return pAufenthalt->kommentar_anz++;
}

/************************************************************************
** lkf_add_line_pat_bypass_check: Wie add_line_pat (siehe unten), nur  **
** dass KANR und PATID nicht mehr überprüft werden.                    **
************************************************************************/

#define LKF_M02_BETWEEN_LEN 20
#define LKF_M04_BETWEEN_LEN 14

int lkf_add_line_auf_bypass_check (LKF_AUFENTHALT *pAufenthalt, const char *srcline, int nModelljahr)
{
	int val;
	int len;
    int pos;
	int oldformat;
	char buf1[12], buf2[8], buf3[4];
	char datbuf[10], posbuf[6];
	char line[300];
	char *melbuf;
	const char *sAdditional;
    int nFormat;
    size_t nAdditionalLen;
    
	if (srcline[0] == 'M') {
		oldformat = 0;
		srcline += 2;
	}
	else oldformat = 1;

    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015)
        nFormat = 1;
    else
        nFormat = 0;
    
	switch (*srcline) {
	
		case '1': /* Satzart 1: Patienten-Stammsatz */

				  expand_string (srcline, 80, line);

/*				  pAufenthalt->abt_anz = 0;
				  pAufenthalt->mel_anz = 0;
				  pAufenthalt->diag_anz = 0;
*/
				  if (oldformat) pAufenthalt->FLAG = line[1];
				  else pAufenthalt->FLAG = line[17];
				  pAufenthalt->ORIG_PLAUS = pAufenthalt->FLAG;

				  Util_Datum_Nullen (pAufenthalt->GEBDAT, line + 18);
				  pAufenthalt->GESCHL = (char) toupper (line[26]);
				  CopyUCaseLTrim (pAufenthalt->STAATB, line + 27, 3);
				  CopyUCaseLTrim (pAufenthalt->STAATW, line + 30, 3);
				  CopyUCaseLTrim (pAufenthalt->PLZW, line + 33, 6);

				  pAufenthalt->AUFART = (char) toupper (line[39]);
				  Util_Datum_Nullen (pAufenthalt->AUFDAT, line + 50);

				  pAufenthalt->AUFART2 = (char) toupper (line[40]);
				  CopyUCaseLTrim (pAufenthalt->KANR_VON, line + 44, 6);
				  CopyUCaseLTrim (pAufenthalt->KANR_AN, line + 61, 6);

				  pAufenthalt->ENTART = (char) toupper (line[58]);
				  Util_Datum_Nullen (pAufenthalt->ENTDAT, line + 67);

                  CopyLTrim(pAufenthalt->ALTERSGRUPPE, line + 75, 3);
                  pAufenthalt->ALTERSGRUPPE[3] = 0; /* V19.0 */
                  for (pos = 2; pos >= 0; --pos) {
                      if (pAufenthalt->ALTERSGRUPPE[pos] == ' ') pAufenthalt->ALTERSGRUPPE[pos] = 0; /* 19.1 */
                      else break;
                  }

                  sAdditional = get_string_ext (srcline, 75);
                  if (nFormat > 0) {
                      nAdditionalLen = sAdditional ? strlen (sAdditional) : 0;
                      if (nAdditionalLen > 67)
                          sAdditional += 67;
                      else
                          sAdditional = 0;
                  }
				  pAufenthalt->nM01ExtOffset = sAdditional ? lkf_auf_add_ext (pAufenthalt, sAdditional) : 0;

				  pAufenthalt->nStatus = 0; /* V11.1 */

				  return 0;

		case '2': /* Satzart 2: Verlegungs-Daten */

				  expand_string (srcline, 90, line);
			
				  memcpy (buf3, line + 17, 2);
				  buf3[2] = 0;
				  Util_FC_Nullen (buf1, line + 19);
				  Util_Datum_Nullen (buf2, line + 27);

				  if (pAufenthalt->pScoringContext) 
					  sAdditional = get_string_ext (srcline, 35 + pAufenthalt->pScoringContext->m02_intlen);
				  else
					  sAdditional = get_string_ext (srcline, 35 + LKF_AUFENTHALT_ABT_INTSATZ_LEN_FONDS);

				  
				  
				  if (nFormat > 0)
                  { /* V19.0 */
                      nAdditionalLen = sAdditional ? strlen(sAdditional) : 0;
                      if (sAdditional) {
                          char *buf;
                          if (nAdditionalLen > LKF_M02_BETWEEN_LEN + 64) {
                              buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext2", nAdditionalLen - 63);
                              if (!buf) return LKF_OUTOFMEMORY_ERROR;
                              memcpy (buf, sAdditional, LKF_M02_BETWEEN_LEN);
                              strcpy (buf + LKF_M02_BETWEEN_LEN, sAdditional + LKF_M02_BETWEEN_LEN + 64);
                          } else {
                              buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext2", LKF_M02_BETWEEN_LEN + 1);
                              if (!buf) return LKF_OUTOFMEMORY_ERROR;
                              strncpy (buf, sAdditional, LKF_M02_BETWEEN_LEN);
                              buf[LKF_M02_BETWEEN_LEN] = 0;
                          }
                          lkf_add_abt3 (pAufenthalt, buf1, buf2, buf3, srcline + 35, buf);
                          LKF_FREE (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext2", buf);
                      }
                      else
                          lkf_add_abt3 (pAufenthalt, buf1, buf2, buf3, srcline + 35, 0);
                  }
                  else {
                      lkf_add_abt3 (pAufenthalt, buf1, buf2, buf3, srcline + 35, sAdditional);
                  }

				  return 0;

		case '3': /* Satzart 3: Diagnosen */

                  expand_string (srcline, (nFormat > 0) ? 100 : 40, line);

				  if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr < 2011 && pAufenthalt->pScoringContext->modelljahr)
				  {
				      CopyUCaseLTrim (buf3, line + 24, 2);
				      CopyLTrim (buf1, line + 17, LKF_AUFENTHALT_DIAG_LEN);
				  }
				  else
				  {
				      Copy (buf3, line + 24, 2);
				      Copy (buf1, line + 17, LKF_AUFENTHALT_DIAG_LEN);
				  }
 
                  sAdditional = get_string_ext (srcline, 30);
                  if (nFormat > 0) {
                      nAdditionalLen = sAdditional ? strlen(sAdditional) : 0;
                      memcpy (buf2, line + 90, 4);
                      if (nAdditionalLen > 64)
                          sAdditional += 64;
                      else
                          sAdditional = 0;
                  }
                  else {
                      memcpy (buf2, line + 26, 4);
                  }

				  lkf_add_diag3 (pAufenthalt, buf1, buf3, buf2, sAdditional);

				  return 0;

		case '4': /* Satzart 4: MELs */

                  expand_string (srcline, (nFormat > 0) ? 128: 50, line);

				  if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr < 2011 && pAufenthalt->pScoringContext->modelljahr)
				  {
				      CopyUCaseLTrim (buf1, line + 17, 10);
				      CopyUCaseLTrim (buf2, line + 27, 4);
				  }
				  else
				  {
				      Copy (buf1, line + 17, 10);
				      Copy (buf2, line + 27, 4);
				  }
			      
				  buf1[10] = 0;
				  buf2[4] = 0;
				  CopyUCaseLTrim (datbuf, line + 31, LKF_AUFENTHALT_DAT_LEN);
            
                  melbuf = buf1;

                  if (nFormat > 0) {
                      sAdditional = get_string_ext (srcline, 39);
                      nAdditionalLen = sAdditional ? strlen(sAdditional) : 0;
                      memcpy (posbuf, line + 39 + 64 + LKF_M04_BETWEEN_LEN, 4);
                      if (sAdditional) {
                          char *buf;
                          if (nAdditionalLen > 64 + LKF_M04_BETWEEN_LEN + 4) {
                              buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext4", LKF_M04_BETWEEN_LEN + nAdditionalLen - 67);
                              if (!buf) return LKF_OUTOFMEMORY_ERROR;
                              memcpy (buf, sAdditional, LKF_M04_BETWEEN_LEN);
                              strcpy (buf + LKF_M04_BETWEEN_LEN, sAdditional + LKF_M04_BETWEEN_LEN + 68);
                          }
                          else {
                              buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext4", LKF_M04_BETWEEN_LEN + 1);
                              if (!buf) return LKF_OUTOFMEMORY_ERROR;
                              strncpy (buf, sAdditional, LKF_M04_BETWEEN_LEN);
                              buf[LKF_M04_BETWEEN_LEN] = 0;
                          }
                          lkf_add_mel4 (pAufenthalt, melbuf, buf2, datbuf, posbuf, buf);
                          LKF_FREE (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext4", buf);
                      }
                      else
                          lkf_add_mel4 (pAufenthalt, melbuf, buf2, datbuf, posbuf, 0);
                  }
                  else {
                      sAdditional = get_string_ext (srcline, 43); /* V11.1 */
                      memcpy (posbuf, line + 39, 4);
                      lkf_add_mel4 (pAufenthalt, melbuf, buf2, datbuf, posbuf, sAdditional);
                  }

 				  return 0;

		case '5': /* Satzart 5: Kostenträger */


				  expand_string (srcline, 40, line);

				  CopyLTrim (buf1, line + 17, 2);
				  memcpy (pAufenthalt->KOST, buf1, 2);
				  sAdditional = get_string_ext (srcline, 19);
            
                  if (nFormat > 0 && sAdditional) {
                      char *buf;
                      nAdditionalLen = sAdditional ? strlen(sAdditional) : 0;
                      if (nAdditionalLen > 2 + 64) {
                          buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext5", nAdditionalLen - 63);
                          if (!buf) return LKF_OUTOFMEMORY_ERROR;
                          memcpy(buf, sAdditional, 2);
                          strcpy (buf + 2, sAdditional + 66);
                      } else {
                          buf = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext5", 3);
                          if (!buf) return LKF_OUTOFMEMORY_ERROR;
                          strncpy(buf, sAdditional, 2);
                          buf[2] = 0;
                      }
                      pAufenthalt->nM05ExtOffset = lkf_auf_add_ext (pAufenthalt, buf);
                      LKF_FREE (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.ext5", buf);
                  }
                  else
                      pAufenthalt->nM05ExtOffset = sAdditional ? lkf_auf_add_ext (pAufenthalt, sAdditional) : 0;
			   	  pAufenthalt->nStatus = 0;
				  return 0;

		case '6': /* Satzart 6: Scoringdaten */

				  expand_string (srcline, 120, line);


				  if (!pAufenthalt->pOrig) pAufenthalt->pOrig = (LKF_AUFENTHALT_SCORING_ORIG *) LKF_CALLOC (pAufenthalt->pScoringContext, "lkf_add_line_auf_bypass_check.pOrig", 1, sizeof (LKF_AUFENTHALT_SCORING_ORIG));
				  memcpy (pAufenthalt->pOrig->ldf_gruppe, line + 17, 8);
				  memcpy (pAufenthalt->pOrig->ldf_knoten, line + 25, 3);

				  GetInt (line + 28, 8, &val);
				  pAufenthalt->pOrig->LDFPLK = val;

				  GetInt (line + 36, 8, &val);
				  pAufenthalt->pOrig->LDFPTK = val;

				  GetInt (line + 44, 8, &val);
				  pAufenthalt->pOrig->SCULK = val;

				  GetInt (line + 52, 8, &val);
				  pAufenthalt->pOrig->SCUTK = val;

				  GetInt (line + 60, 8, &val);
				  pAufenthalt->pOrig->VDZU = val;

				  GetInt (line + 68, 8, &val);
				  pAufenthalt->pOrig->INTZU = val;

				  GetInt (line + 76, 8, &val);
				  pAufenthalt->pOrig->MELZU = val;

				  GetInt (line + 84, 8, &val);
				  pAufenthalt->pOrig->SCSPEZ = val;

				  GetInt (line + 92, 8, &val);
				  pAufenthalt->pOrig->SCGES = val;

				  sAdditional = get_string_ext (srcline, 100);
                  if (nFormat > 0) {
                      nAdditionalLen = sAdditional ? strlen(sAdditional) : 0;
                      if (nAdditionalLen > 64) sAdditional += 64;
                      else sAdditional = 0;
                  }
				  pAufenthalt->nM06ExtOffset = sAdditional ? lkf_auf_add_ext (pAufenthalt, sAdditional) : 0;

				  return 0;

		case '7': /* akzeptierte Errors und Warnings */
				  expand_string (srcline, 250, line);

				  CopyUCaseLTrim (buf1, line + 27, 4);
				  len = (int) strlen (line);
#ifdef SUPPORT_PRE2017
            if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2017 && buf1[1] == 'M' /* V21.2 */) {
                      buf1[1] = 'X';
                  }
#endif
				  lkf_add_akwarn (pAufenthalt, buf1, line + 17, (len > 31) ? line + 31 : "");
				  return 0;

		case '8': /* Kommentare */

#ifdef SUPPORT_PRE2017
                if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
#else
                {
#endif
                    char kommline[1300];
                    
                    expand_string (srcline, 1280, kommline);
                    len = (int) strlen (srcline);
                    if (len >= 17) {
                        lkf_add_komm(pAufenthalt, kommline + 17);
                        if (len >= 217) {
                            lkf_add_komm(pAufenthalt, kommline + 217);
                            if (len >= 417) {
                                lkf_add_komm(pAufenthalt, kommline + 417);
                                if (len >= 617) {
                                    lkf_add_komm(pAufenthalt, kommline + 617);
                                    if (len >= 817) {
                                        lkf_add_komm(pAufenthalt, kommline + 817);
                                        if (len >= 1017) {
                                            lkf_add_komm(pAufenthalt, kommline + 1017);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    return 0;
                }
                    
#ifdef SUPPORT_PRE2017
				if (pAufenthalt->kommentar_anz == 0)
				{ /* V16.1 */
					sAdditional = get_string_ext (srcline, 217);
                    
                    if (nFormat > 0 && sAdditional) {
                        char *buf;
                        nAdditionalLen = strlen(sAdditional);
                        if (nAdditionalLen > 1064) {
                            buf = (char *) LKF_MALLOC (nAdditionalLen - 63); /* V19.1 */
                            memcpy(buf, sAdditional, 1000);
                            strcpy(buf + 1000, sAdditional + 1064);
                        } else {
                            buf = (char *) LKF_MALLOC (1002); /* V19.1 */
                            strncpy(buf, sAdditional, 1000);
                            buf[nAdditionalLen] = 0;
                        }
                        pAufenthalt->nM08ExtOffset = lkf_auf_add_ext (pAufenthalt, buf);
                        LKF_FREE (buf);
                    }
                    else
                        pAufenthalt->nM08ExtOffset = sAdditional ? lkf_auf_add_ext (pAufenthalt, sAdditional) : 0;
				}

				  expand_string (srcline, 250, line);
				  lkf_add_komm (pAufenthalt, line + 17);
				  return 0;
#endif
		  default:
				  return -1;	
	
	}
}

/************************************************************************
** lkf_add_linebuf_line: Fügt dem Linebuffer des Aufenthalts eine      **
**     Zeile hinzu.                                                    **
************************************************************************/

#ifdef SUPPORT_PRE2017
unsigned int lkf_add_linebuf_line (LKF_AUFENTHALT *pAufenthalt, const char *line)
{

    if (pAufenthalt->pScoringContext->modelljahr >= 2017 && !(pAufenthalt->pScoringContext->flags & LKFCONTEXT_SATZART_INPUT_M)) {
        lkf_add_xline_auf_intensiv(pAufenthalt, line, 0);
    }

	if (!pAufenthalt->pLineBuffer) pAufenthalt->pLineBuffer = lkf_create_linebuffer(pAufenthalt->pScoringContext);
	return lkf_add_dynamic_line (pAufenthalt->pLineBuffer, line);
}
#endif

/*************************************************************************
** lkf_auf_getdiff: Ermittelt eventuelle Differenzen zwischen den       **
**    gemeldeten Scoring-Daten und den ermittelten.                     **
*************************************************************************/

_SCORING_EXPORT int lkf_auf_getdiff (LKF_AUFENTHALT *pAufenthalt)
{
	int differences = 0;
	if (pAufenthalt->ORIG_PLAUS != pAufenthalt->FLAG) differences |= LKFDIFF_PLAUS;

	if (!pAufenthalt->pOrig) {
		if (pAufenthalt->SCGES) differences |= LKFDIFF_SCGES;
	}
	else if (pAufenthalt->SCGES != pAufenthalt->pOrig->SCGES) differences |= LKFDIFF_SCGES;
	return differences;
}


/************************************************************************
** lkf_add_line_pat: Fügt eine Zeile zu einem bestimmten Patienten     **
**  hinzu; die Einträge aus KANR und PATID werden überprüft            **
************************************************************************/
#ifdef SUPPORT_PRE2017
_SCORING_EXPORT int lkf_add_line_auf (LKF_AUFENTHALT *pAufenthalt, const char *line)
{
	int i;
	int oldformat;
    int bmFormat;
	int bIntensiv; /* V10.1 - Unterstuetzung von I-Saetzen */
	char kanr[LKF_AUFENTHALT_KANR_LEN];
	char patid[LKF_AUFENTHALT_LONGID_LEN];
    size_t comparePATIDLen;

	bIntensiv = 0;
    if (*line == 'I') {
		bIntensiv = 1;
        oldformat = 0;
    }
	else if (*line == 'M') {
		oldformat = 0;
		line += 2; 
    }
    else if (*line == 'X') {
        return lkf_add_xline_auf(pAufenthalt, line, 0);
    }
	else oldformat = 1;

    bmFormat = pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->isBM;
    comparePATIDLen = bmFormat ? LKF_AUFENTHALT_LONGID_LEN : LKF_AUFENTHALT_PATID_LEN;
	
    switch (*line) {

		case '1':

				if (oldformat) {
				    memcpy (pAufenthalt->KANR, line + 2, LKF_AUFENTHALT_KANR_LEN);
                    memcpy (pAufenthalt->PATID, line + 8, LKF_AUFENTHALT_PATID_LEN);
                    if (bmFormat) {
                        memcpy(pAufenthalt->UCASE_PATID, line + pAufenthalt->pScoringContext->patidPos[1]->nPos, LKF_AUFENTHALT_LONGID_LEN);
                    }
				}
				else {
				  memcpy (pAufenthalt->KANR, line + 1, LKF_AUFENTHALT_KANR_LEN);
                  memcpy (pAufenthalt->PATID, line + 7, LKF_AUFENTHALT_PATID_LEN);
				}
                if (!bmFormat) {
                    for (i = 0; i < LKF_AUFENTHALT_PATID_LEN; i++)
					pAufenthalt->UCASE_PATID[i] = (char) toupper (pAufenthalt->PATID[i]);
                }
				  break;
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
				  CopyUCaseLTrim (kanr, line + 1, LKF_AUFENTHALT_KANR_LEN);
                  if (bmFormat)
                      CopyUCaseLTrim (patid, line + pAufenthalt->pScoringContext->patidPos[(*line)-'0']->nPos, LKF_AUFENTHALT_LONGID_LEN);
				  else
                      CopyUCaseLTrim (patid, line + 7, LKF_AUFENTHALT_PATID_LEN);
				  break;


		case 'I':
            
                  if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2017 && !(pAufenthalt->pScoringContext->flags & LKFCONTEXT_SATZART_INPUT_M)) {
                      return lkf_add_xline_auf_intensiv (pAufenthalt, line, 0);
                  }
            
				  CopyUCaseLTrim (kanr, line + 3, LKF_AUFENTHALT_KANR_LEN);
                  if (bmFormat) {
                      int nSatzart = 11;
                      if (line[2] == '2') nSatzart = 12;
                      CopyUCaseLTrim (patid, line + pAufenthalt->pScoringContext->patidPos[nSatzart]->nPos, LKF_AUFENTHALT_LONGID_LEN);
                      
                  }
                  else
                      CopyUCaseLTrim (patid, line + 9, LKF_AUFENTHALT_PATID_LEN);
				  break;

		default:
				  return -1;
	}

	if (*line != '1' && (strncmp (kanr, pAufenthalt->KANR, LKF_AUFENTHALT_KANR_LEN) ||
		strncmp (patid, pAufenthalt->UCASE_PATID, comparePATIDLen))) return -1;
	else if (bIntensiv)
	{
		lkf_add_linebuf_line (pAufenthalt, line);
		return 0;
	}
	else if (oldformat) return lkf_add_line_auf_bypass_check (pAufenthalt, line, 0);
	else return lkf_add_line_auf_bypass_check (pAufenthalt, line - 2, 0);
}
#else
_SCORING_EXPORT int lkf_add_line_auf (LKF_AUFENTHALT *pAufenthalt, const char *line) {
    if (line[0] == 'I') {
        return lkf_add_xline_auf_intensiv(pAufenthalt, line, 0);
    }
    return lkf_add_xline_auf(pAufenthalt, line, 0);
}
#endif

/*************************************************************************
** lkf_sort_auf_abt: Sortiert die Abteilungen des Aufenthalts nach der  **
**     mitgeg. Abteilungsposition.                                      **
*************************************************************************/

#ifdef SUPPORT_PRE2017
static int compare_aufabt (const void *a1, const void *a2)
{
	return memcmp (((LKF_AUFENTHALT_ABT *) a1)->ABTPOS,
				   ((LKF_AUFENTHALT_ABT *) a2)->ABTPOS,
				   LKF_AUFENTHALT_ABTPOS_LEN);
}
#endif

static int compare_aufabt2017 (const void *a1, const void *a2)
{
    return memcmp (((LKF_AUFENTHALT_ABT *) a1)->ABTPOS,
                   ((LKF_AUFENTHALT_ABT *) a2)->ABTPOS,
                   LKF_AUFENTHALT_ABTPOS_LEN_2017);
}

void lkf_sort_auf_abt (LKF_AUFENTHALT *pAufenthalt)
{
#ifdef SUPPORT_PRE2017
    if (pAufenthalt->abt_anz > 1) {
        if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2017)
            qsort (pAufenthalt->abt, pAufenthalt->abt_anz, sizeof (LKF_AUFENTHALT_ABT), compare_aufabt2017);
        else
            qsort (pAufenthalt->abt, pAufenthalt->abt_anz, sizeof (LKF_AUFENTHALT_ABT), compare_aufabt);
    }
#else
    qsort (pAufenthalt->abt, pAufenthalt->abt_anz, sizeof (LKF_AUFENTHALT_ABT), compare_aufabt2017);
#endif
}

int lkf_auf_getidfrompos (LKF_AUFENTHALT *pAufenthalt, const char *pos)
{ /* V8.1: Liefert den Index des Aufenthalts der angeg. Aufenthaltsposition */
    unsigned int i;
	
	for (i = 0; i < pAufenthalt->abt_anz; i++) {
		if (!memcmp (pAufenthalt->abt[i].ABTPOS, pos, 2)) return (int) i;
	}
	return -1;
}

int lkf_auf_getidfrompos_2017 (LKF_AUFENTHALT *pAufenthalt, const char *pos)
{ /* V21.1 - Numeric check */
    unsigned int i;
	unsigned int posNr = (unsigned int) atoi(pos);
    for (i = 0; i < pAufenthalt->abt_anz; i++) {
        if (pAufenthalt->abt[i].abtposNumeric == posNr) return (int) i;
    }
    return -1;
}
/**************************************************************************
** lkf_auf_get_abtanz: Liefert die Anzahl Abteilungen zum Patienten      **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_abtanz (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->abt_anz;
}

/***************************************************************************
** lkf_auf_get_customanz: Liefert die Anzahl Custom Lines zurück          **
**     (1, wenn definiert, sonst 0)                                       **
***************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_customanz (LKF_AUFENTHALT *pAufenthalt)
{
	LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
	if (pContext && pContext->custom_field_anz) return 1;
	else return 0;
}

/****************************************************************************
** lkf_auf_get_fieldvalue: Liefert einen Feldwert des Aufenthalts zurück.  **
**     THREAD-SAFE version                                                 **
****************************************************************************/


_SCORING_EXPORT unsigned int lkf_auf_get_fieldvalue (LKF_AUFENTHALT *pAufenthalt, unsigned int fieldnum, char *buf, unsigned int buflen)
{
	unsigned int i;
	const char *field;
	unsigned int fieldlen, copylen;
	char internal_buf[66];

	switch (fieldnum) {
		case SCORFIELD_FLAG:    fieldlen =  1; field = &pAufenthalt->FLAG; break;
		case SCORFIELD_KANR:	fieldlen =  4; field = pAufenthalt->KANR; break;
		case SCORFIELD_AUFNR:   if (SAFEIS2017ORLATER(pAufenthalt))
                                    fieldlen = 12;
                                else
                                    fieldlen = 10;
                                field = pAufenthalt->PATID;
                                break;
        case SCORFIELD_AUFID:   fieldlen = 64; field = pAufenthalt->UCASE_PATID; break;
        case SCORFIELD_AUFKEY:  if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->isBM) {
                                    fieldlen = 64;
                                    field = pAufenthalt->UCASE_PATID;
                                }
                                else {
                                    fieldlen = 12;
                                    field = pAufenthalt->PATID;
                                }
            break;
		case SCORFIELD_GEBDAT:	fieldlen =  8; field = pAufenthalt->GEBDAT; break;
		case SCORFIELD_ALTER:   fieldlen =  4; sprintf (internal_buf, "%d", pAufenthalt->Alter); field = internal_buf; break;
		case SCORFIELD_GESCHL:	fieldlen =  1; field = &pAufenthalt->GESCHL; break;
        case SCORFIELD_BEHANDLUNGSART:
                                fieldlen =  1; field = &pAufenthalt->BEHANDLUNGSART; break;
		case SCORFIELD_STAATB:  fieldlen =  3; field = pAufenthalt->STAATB; break;
		case SCORFIELD_STAATW:  fieldlen =  3; field = pAufenthalt->STAATW; break;
		case SCORFIELD_PLZW:    fieldlen =  6; field = pAufenthalt->PLZW; break;
		case SCORFIELD_AUFART:  fieldlen =  1; field = &pAufenthalt->AUFART; break;
		case SCORFIELD_GESVD:   fieldlen =  5; sprintf (internal_buf, "%ld", pAufenthalt->GESVD+pAufenthalt->GESVD_KORR); field = internal_buf; break;
        case SCORFIELD_GESVD_MINUS:   fieldlen =  5; sprintf (internal_buf, "%ld", pAufenthalt->GESVD); field = internal_buf; break;
        case SCORFIELD_GESVD_SPEZ:    fieldlen =  5; sprintf (internal_buf, "%ld", pAufenthalt->GESVD_KORR); field = internal_buf; break;
		case SCORFIELD_ENTART:  fieldlen =  1; field = &pAufenthalt->ENTART; break;
		case SCORFIELD_ENTDAT:  fieldlen =  8; field = pAufenthalt->ENTDAT; break;
		case SCORFIELD_HD:      fieldlen =  6; field = pAufenthalt->HD; break;
		case SCORFIELD_KOST:    fieldlen =  2; field = pAufenthalt->KOST; break;
		case SCORFIELD_GRP:		fieldlen =  8; field = pAufenthalt->GRP; break;
		case SCORFIELD_KNO:     fieldlen =  1; field = pAufenthalt->KNT; break;
        case SCORFIELD_ALTERSGRUPPE:
                                fieldlen =  3;  fieldlen = 3; field = pAufenthalt->ALTERSGRUPPE; break;
		case SCORFIELD_VDU:     fieldlen =  4; sprintf (internal_buf, "%d", pAufenthalt->VDU); field = internal_buf; break;
		case SCORFIELD_VDO:     fieldlen =  4; sprintf (internal_buf, "%d", pAufenthalt->VDO); field = internal_buf; break;
		case SCORFIELD_VDMW:    fieldlen =  6; sprintf (internal_buf, "%6.1f", pAufenthalt->VDMW); field = internal_buf; break;
		case SCORFIELD_LDFPTK:  fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->LDFPTK); field = internal_buf; break;
		case SCORFIELD_LDFPLK:  fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->LDFPLK); field = internal_buf; break;
		case SCORFIELD_SCUTK:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCUTK); field = internal_buf; break;
		case SCORFIELD_SCULK:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCULK); field = internal_buf; break;
		case SCORFIELD_VDZU:    fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->VDZU); field = internal_buf; break;
		case SCORFIELD_INTZU:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->INTZU); field = internal_buf; break;
		case SCORFIELD_MELZU:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->MELZU); field = internal_buf; break;
		case SCORFIELD_SCSPEZ:  fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCSPEZ); field = internal_buf; break;
		case SCORFIELD_SCGES:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCGES); field = internal_buf; break;
        case -SCORFIELD_SCGES:  if (pAufenthalt->pOrig) {
                                    fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->pOrig->SCGES); field = internal_buf; break;
                                }
                                fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCGES); field = internal_buf; break;
		case SCORFIELD_LDFPK:   fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->LDFPTK + pAufenthalt->LDFPLK); field = internal_buf; break;
		case SCORFIELD_SCUK:    fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCULK + pAufenthalt->SCUTK); field = internal_buf; break;
		case SCORFIELD_ENTABT:  
			fieldlen =  8; field = pAufenthalt->abt_anz ? pAufenthalt->abt[pAufenthalt->abt_anz-1].ABTFC : "        "; break;
		case SCORFIELD_AUFABT:  
			fieldlen =  8; field = pAufenthalt->abt_anz ? pAufenthalt->abt[0].ABTFC : "        "; break;
		case SCORFIELD_AUFDAT:  fieldlen =  8; field = pAufenthalt->AUFDAT; break;
		case SCORFIELD_SCUTK_TKL: /* V5.1T */
								fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCUTK_TKL); field = internal_buf; break;
		case SCORFIELD_SCUTK_NOTKL: /* V9.2 */
								fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCUTK_NOTKL); field = internal_buf; break;
		case SCORFIELD_SCGES_TKL: /* V5.1T */
								fieldlen = 10; sprintf (internal_buf, "%ld", pAufenthalt->SCGES_TKL); field = internal_buf; break;
		case SCORFIELD_MARK:    fieldlen = 1; field = pAufenthalt->mark ? "1" : "0"; break;
		case SCORFIELD_NR:		fieldlen = 8; sprintf (internal_buf, "%8d", pAufenthalt->nr); field = internal_buf; break; 
		default: return 0;
	}

	copylen = fieldlen > buflen ? buflen : fieldlen;
	memcpy (buf, field, copylen);
	if (copylen + 1 < buflen)
		buf[copylen] = 0;

	for (i = 0; i < fieldlen; i++)
	{
		if (buf[i] == 0) return i;
	}
	return fieldlen;
}

/****************************************************************************
** lkf_auf_get_field: Liefert einen Feldwert des Aufenthalts zurück        **
**    DO NOT USE THIS FUNCTION IN MULTITHREADING ENVIRONMENTS !!!          **
**    (use lkf_auf_get_fieldvalue instead)                                 **
****************************************************************************/


_SCORING_EXPORT int lkf_auf_get_field (LKF_AUFENTHALT *pAufenthalt, unsigned int fieldnum, const char **field, unsigned int *len)
{
	static char buf[66];
	*len = lkf_auf_get_fieldvalue (pAufenthalt, fieldnum, buf, 66);
	if (!*len) return 2;
	else {
		*field = buf;
		return 0;
	}
}

_SCORING_EXPORT const char *lkf_auf_get_ident (LKF_AUFENTHALT *pAufenthalt, char *buf)
{
    if (SAFEIS2017ORLATER(pAufenthalt)) {
        if (pAufenthalt->pScoringContext->isBM)
            sprintf (buf, "%4.4s  %64.64s %8.8s", pAufenthalt->KANR, pAufenthalt->UCASE_PATID, pAufenthalt->AUFDAT);
        else
            sprintf (buf, "%4.4s  %12.12s %8.8s", pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->AUFDAT);
    }
    else
        sprintf (buf, "%4.4s  %10.10s", pAufenthalt->KANR, pAufenthalt->PATID);
	return buf;
}


/****************************************************************************
** lkf_auf_line_custom: Liefert die Custom Line zurück.                    **
****************************************************************************/

_SCORING_EXPORT int lkf_auf_line_custom (LKF_AUFENTHALT *pAufenthalt, char *line)
{
	unsigned int i;
	char *cont_line;
	char field[50];
	unsigned int len;
	
	LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;

	if (!pContext || !pContext->custom_field_anz) return 0;

	if (pContext->custom_char) {
		line[0] = pContext->custom_char;
		if (pContext->custom_flags & 1) {
			line[1] = ';';
			cont_line = line + 2;
		}
		else cont_line = line + 1;
	}
	else cont_line = line;

	for (i = 0; i < pContext->custom_field_anz; i++) {

		len = lkf_auf_get_fieldvalue (pAufenthalt, pContext->custom_fields[i], field, 50); 

		if (pContext->custom_flags & 1) sprintf (cont_line, "%.*s;", len, field);
		else sprintf (cont_line, "%.*s", len, field);
		cont_line += strlen (cont_line);
	}

	return 0;
}

/**************************************************************************
** lkf_auf_get_melanz: Liefert die Anzahl Leistungen zum Patienten       **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_melanz (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->mel_anz;
}

/**************************************************************************
** lkf_auf_get_diaganz: Liefert die Anzahl Diagnosen zum Patienten       **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_diaganz (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->diag_anz;
}

_SCORING_EXPORT unsigned int lkf_auf_get_hdiaganz(LKF_AUFENTHALT *pAufenthalt) 
{ /* V21.1 */
	return pAufenthalt->hdiag_anz;
}

/**************************************************************************
** lkf_auf_getlineanz: Liefert die Anzahl Zeilen des Aufenthalts im      **
**    relationalen Ausgabe-File                                          **
** V6.0 ******************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_getlineanz (LKF_AUFENTHALT *pAufenthalt)
{

	return 1 + pAufenthalt->abt_anz + pAufenthalt->mel_anz + pAufenthalt->diag_anz + pAufenthalt->akwarn_anz
		     + (unsigned int) lkf_auf_get_kommentaranz(pAufenthalt) + (unsigned int) lkf_auf_get_kostanz (pAufenthalt)
			 + lkf_auf_get_scoringanz (pAufenthalt);
}

/**************************************************************************
** lkf_auf_getline: Liefert eine Zeile des Aufenthalts - index muß       **
**    zwischen 0 und lkf_auf_getlineanz - 1 liegen.                      **
**************************************************************************/

_SCORING_EXPORT int lkf_auf_getline (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *line)
{
    return lkf_auf_getLineAndIdent(pAufenthalt, index, line, 0);
}

_SCORING_EXPORT int lkf_getLineIdent(LKF_CONTEXT *pContext, const char *satzart, unsigned int index, char *buf, unsigned int buflen) {
        
    char localbuf[128];
    int localBufLen = 0;
    
    if (satzart[0] == 'X') {
        switch (satzart[2]) {
            case '1':
                strcpy (localbuf, "AUF:X01");
                break;
            case '2':
                sprintf (localbuf, "AUF:X02:%d", index);
                break;
            case '3':
                sprintf (localbuf, "AUF:X03:%d", index);
                break;
            case '4':
                sprintf (localbuf, "AUF:X04:%d", index);
                break;
            case '5':
                strcpy (localbuf, "AUF:X05");
                break;
            case '6':
                sprintf (localbuf, "AUF:X06:%d", index);
                break;
            case '7':
                strcpy (localbuf, "AUF:X07");
                break;
            default:
                localBufLen = -1;
                break;
        }
    }
    
    if (localBufLen < 0) {
        if (buf) *buf = 0;
        return localBufLen;
    }
    
    localBufLen = (int) strlen(localbuf);
    
    if (buf && (!buflen || localBufLen < (int) buflen)) {
        strcpy (buf, localbuf);
    }
    return localBufLen;
}
    
_SCORING_EXPORT int lkf_auf_getLineAndIdent (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *line, char *ident)
{

	unsigned int anz;

    if (index == 0) {
        if (ident) {
            strcpy (ident, "AUF:X01");
        }
        return lkf_auf_line_root (pAufenthalt, line);
    }
	else --index;

    if (index < pAufenthalt->abt_anz) {
        if (ident) {
            sprintf (ident, "AUF:X02:%d", index);
        }
        return lkf_auf_line_abt (pAufenthalt, index, line);
    }
	else index -= pAufenthalt->abt_anz;

    if (index < pAufenthalt->diag_anz) {
        if (ident) {
            sprintf (ident, "AUF:X03:%d", index);
        }
        return lkf_auf_line_diag (pAufenthalt, index, line);
    }
    else index -= pAufenthalt->diag_anz;

    if (index < pAufenthalt->mel_anz) {
        if (ident) {
            sprintf (ident, "AUF:X04:%d", index);
        }
        return lkf_auf_line_mel (pAufenthalt, index, line);
    }
	else index -= pAufenthalt->mel_anz;

	anz = (unsigned int) lkf_auf_get_kostanz (pAufenthalt);

    if (index < anz) {
        if (ident) {
            sprintf (ident, "AUF:M05:%d", index);
        }
        return lkf_auf_line_kost (pAufenthalt, index, line);
    }
	else index -= anz;

	anz = (unsigned int) lkf_auf_get_scoringanz (pAufenthalt);

    if (index < anz) {
        if (ident) {
            strcpy (ident, "AUF:X05");
        }
        return lkf_auf_line_scoring (pAufenthalt, line);
    }
	else index -= anz;

    if (index < pAufenthalt->akwarn_anz) {
        if (ident) {
            sprintf (ident, "AUF:X06:%d", index);
        }
        return lkf_auf_line_akwarn (pAufenthalt, index, line);
    }
	else index -= pAufenthalt->akwarn_anz;
    
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
        if (index < 1 && pAufenthalt->kommentar_anz) {
            if (ident) {
                strcpy (ident, "AUF:X07");
            }
            return lkf_auf_xline_kommentar(pAufenthalt, line);
        }
        else index--;
    }
#ifdef SUPPORT_PRE2017
    else {
        if (index < pAufenthalt->kommentar_anz) {
            if (ident) {
                sprintf (ident, "AUF:M08:%d", index);
            }
            return lkf_auf_line_kommentar (pAufenthalt, index, line);
        }
        else index -= pAufenthalt->kommentar_anz;
    }
#endif
    if (ident) {
        *ident = 0;
    }
	return 0;
}

_SCORING_EXPORT unsigned int lkf_auf_get_abtfield (LKF_AUFENTHALT *pAufenthalt, unsigned int index, unsigned int field, char *buf, unsigned int buflen)
{ /* V19.0 */
    
    unsigned int fieldlen = 0;
    const char *fieldValue = 0;
    
    if (index < pAufenthalt->abt_anz) {
        switch (field) {
            case SCORFIELD_ALTERSGRUPPE:
                fieldValue = pAufenthalt->abt[index].ALTERSGRUPPE;
                fieldlen = 3;
                break;
            case SCORFIELD_NEUGEB:
                fieldValue = &pAufenthalt->abt[index].ISNEONAT;
                fieldlen = 1;
                break;
            case LKF_ABTFIELD_K01TEXT:
                fieldValue = "";
                fieldlen = 0;
                break;
            case LKF_ABTFIELD_FUNKTEXT:
                {
                    FUNK_LIST_STRING *f = FunkInArray(pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->abt[index].ABTFC);
                    if (f) {
                        fieldValue = ((const char *)f) + 6;
                        fieldlen = 80;
                    }
                    else {
                        fieldValue = "";
                        fieldlen = 0;
                    }
                }
                break;
            case LKF_ABTFIELD_K01ORFUNK:
                {
                    FUNK_LIST_STRING *f = FunkInArray(pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->abt[index].ABTFC);
                    if (f) {
                        fieldValue = ((const char *)f) + 6;
                        fieldlen = 80;
                    }
                    else {
                        fieldValue = "";
                        fieldlen = 0;
                    }
                }
                break;
            default:
                break;
        }
        
        if (fieldlen > 0) {
			unsigned int i, copylen = fieldlen > buflen ? buflen : fieldlen;
            memcpy (buf, fieldValue, copylen);
            if (copylen + 1 < buflen) buf[copylen] = 0;
            
            for (i = 0; i < fieldlen; i++)
            {
                if (buf[i] == 0) return i;
            }
            return fieldlen;
        }
    }
    return 0;
}


/**************************************************************************
** lkf_auf_get_abt: Liefert eine Verlegungsmeldung zurueck               **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_abt  (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *abtfc, char *abtdat, char *abtpos)
{
	if (index < pAufenthalt->abt_anz) {
		strncpy (abtdat, pAufenthalt->abt[index].ABTDAT, 8);
		abtdat[8] = 0;
		strncpy (abtfc, pAufenthalt->abt[index].ABTFC, 8);
		abtfc[8] = 0;
        if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2017) {
            strncpy (abtpos, pAufenthalt->abt[index].ABTPOS, 3);
            abtpos[3] = 0;
        }
#ifdef SUPPORT_PRE2017
        else {
            strncpy (abtpos, pAufenthalt->abt[index].ABTPOS, 2);
            abtpos[2] = 0;
        }
#endif
		return 1;
	}
	else {
		*abtdat = *abtfc = *abtpos = 0;
		return 0;
	}
}

/**************************************************************************
** lkf_auf_get_abtdb: Liefert die Abteilungsbelagsdauer zurück.          **
**************************************************************************/


_SCORING_EXPORT unsigned int lkf_auf_get_abtbd (LKF_AUFENTHALT *pAufenthalt, unsigned int index, long *abtbd)
{
	if (index < pAufenthalt->abt_anz) {
		*abtbd = pAufenthalt->abt[index].ABTVD + pAufenthalt->abt[index].ABTVD_KORR;
		return 1;
	}
	else {
		*abtbd = 0;
		return 0;
	}
}


/**************************************************************************
** lkf_auf_get_mel, lkf_auf_get_mel2, lkf_auf_get_mel3:                  **
**     Liefern eine Einzelleistung zurück                                **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_mel3  (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *mel, char *melanz, char *meldat, char *melpos)
{
	if (index < pAufenthalt->mel_anz) {
        strncpy (mel, pAufenthalt->mel[index].MEL, 5);
        mel[5] = 0;
		strncpy (melanz, pAufenthalt->mel[index].MELANZ, 4);
		melanz[4] = 0;

		if (meldat) {
			strncpy (meldat, pAufenthalt->mel[index].MELDAT, 8);
			meldat[8] = 0;
		}

		if (melpos) {
			strncpy (melpos, pAufenthalt->mel[index].MELPOS, 4);
			melpos[4] = 0;
		}
		
		return 1;
	}
	else {
		*melanz = *mel = 0;
		if (meldat) *meldat = 0;
		return 0;
	}
}

_SCORING_EXPORT unsigned int lkf_auf_get_mel2  (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *mel, char *melanz, char *meldat)
{
	return lkf_auf_get_mel3 (pAufenthalt, index, mel, melanz, meldat, 0);
}

_SCORING_EXPORT unsigned int lkf_auf_get_mel  (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *mel, char *melanz)
{
	return lkf_auf_get_mel2 (pAufenthalt, index, mel, melanz, 0);
}



/**************************************************************************
** lkf_copy_aufenthalt: Legt einen neuen Aufenthalt an und kopiert einen **
**     bestehenden in diesen Aufenthalt.                                 **
** V6.0 ******************************************************************/

_SCORING_EXPORT LKF_AUFENTHALT *lkf_copy_aufenthalt (LKF_AUFENTHALT *pAufenthalt)
{
	char buf[512];
	unsigned int i, anz;
	
	LKF_AUFENTHALT *pNewAufenthalt = lkf_alloc_aufenthalt ();
    if (!pNewAufenthalt) return 0;
    
    anz = lkf_auf_getlineanz (pAufenthalt);

	for (i = 0; i < anz; i++) {
	
		lkf_auf_getline (pAufenthalt, i, buf);
		
		lkf_add_line_auf (pNewAufenthalt, buf);
	}
	return pNewAufenthalt;
}

_SCORING_EXPORT LKF_AUFENTHALT *lkf_copy_aufenthalt2 (LKF_AUFENTHALT *pAufenthalt, LKF_CONTEXT *pContext, int copyIntensiv) {
    char buf[512];
    unsigned int i, anz;
    
    LKF_AUFENTHALT *pNewAufenthalt = lkf_alloc_aufenthalt ();
    if (!pNewAufenthalt) return 0;
    
    anz = lkf_auf_getlineanz (pAufenthalt);
    pNewAufenthalt->pScoringContext = pContext;
    for (i = 0; i < anz; i++) {
    
        lkf_auf_getline (pAufenthalt, i, buf);
        lkf_add_line_auf (pNewAufenthalt, buf);
    }
    
    if (copyIntensiv && pAufenthalt->pIntensiv) {
        char line[1024];
        for (i = 0; i < pAufenthalt->pIntensiv->lineCount; i++) {
            lkf_write_expLine(line, pAufenthalt->pIntensiv->lines[i]);
            lkf_add_line_auf(pNewAufenthalt, line);
        }
    }
    
    return pNewAufenthalt;
}

/**************************************************************************
** lkf_auf_get_diag: Liefert eine Diagnose zurück                        **
** V6.0 ******************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_diag2 (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *diag, char *diagtype, char *diagpos)
{
	if (index < pAufenthalt->diag_anz) {
		strncpy (diag, pAufenthalt->diag[index].DIAG, 6);
		diag[6] = 0;
        if (diagtype) {
            *diagtype = pAufenthalt->diag[index].DIAGTYP[0];
        }
		if (diagpos) {
			strncpy (diagpos, pAufenthalt->diag[index].DIAGPOS, 4);
			diagpos[4] = 0;
		}
		return 1;		
	}
	else {
		*diag = 0;
		return 0;
	}
}

_SCORING_EXPORT unsigned int lkf_auf_get_diag (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *diag, char *diagtype)
{
	return lkf_auf_get_diag2 (pAufenthalt, index, diag, diagtype, 0);
}

_SCORING_EXPORT unsigned int lkf_auf_get_diagfield (LKF_AUFENTHALT *pAufenthalt, unsigned int index, unsigned int fieldIndex, char *buffer)
{ /* V2022.0 */
        
    ICD_LIST_STRING *pIcd;

    switch (fieldIndex) {
        case LKF_DIAGFIELD_DIAG:
            if (index < pAufenthalt->diag_anz) {
                strncpy (buffer, pAufenthalt->diag[index].DIAG, 6);
                buffer[6] = 0;
            }
            else {
                *buffer = 0;
                return 1;
            }
            break;
        case LKF_DIAGFIELD_TYPE:
            if (index < pAufenthalt->diag_anz) {
                strcpy (buffer, pAufenthalt->diag[index].DIAGTYP);
                buffer[1] = 0;
            }
            else {
                *buffer = 0;
                return 1;
            }
            break;
        case LKF_DIAGFIELD_POS:
            if (index < pAufenthalt->diag_anz) {
                strncpy (buffer, pAufenthalt->diag[index].DIAGPOS, 4);
                buffer[4] = 0;
            }
            else {
                *buffer = 0;
                return 1;
            }
            break;
        case LKF_DIAGFIELD_TEXT:
            if (index < pAufenthalt->diag_anz) {
                pIcd = FindDiag(pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->diag[index].DIAG);
            }
            else {
                pIcd = 0;
            }
            
            if (pIcd) {
                memcpy (buffer, (*pIcd) + 50, 200);
                buffer[200] = 0;
                return 0;
            }
            else {
                *buffer = 0;
                return 1;
            }
            
            break;

        case LKF_DIAGFIELD_GRUPPE:
            if (index < pAufenthalt->diag_anz) {
                pIcd = FindDiag(pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->diag[index].DIAG);
            }
            else {
                pIcd = 0;
            }
            
            if (pIcd) {
                memcpy (buffer, (*pIcd) + 9, 8);
                buffer[8] = 0;
                return 0;
            }
            else {
                *buffer = 0;
                return 1;
            }
            
            break;

        default:
            *buffer = 0;
            return 2;
    }
    return 0;
}

/**************************************************************************
** lkf_auf_get_akwarnanz: Liefert die Anzahl akzeptierter Warnings zum   **
**     Patienten.                                                        **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_akwarnanz (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->akwarn_anz;
}
/**************************************************************************
** lkf_auf_get_kommentaranz: Liefert die Anzahl Kommentare zum Patienten **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_kommentaranz (LKF_AUFENTHALT *pAufenthalt)
{
#ifdef SUPPORT_PRE2017
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2017) {
        return pAufenthalt->kommentar_anz ? 1 : 0;
    }
	return pAufenthalt->kommentar_anz;
#else
    return pAufenthalt->kommentar_anz ? 1 : 0;
#endif
}

_SCORING_EXPORT unsigned int lkf_auf_get_kommentaranz2 (LKF_AUFENTHALT *pAufenthalt)
{
    return pAufenthalt->kommentar_anz;
}

/**************************************************************************
** lkf_auf_get_scoring_anz: Liefert 1, wenn es einen Scoring-Satz gibt,  **
**     sonst 0.                                                          **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_scoringanz (LKF_AUFENTHALT *pAufenthalt)
{
	if (pAufenthalt->status & 2) return 1;
	else return 0;
}

/**************************************************************************
** lkf_auf_get_kostanz: Liefert die Anzahl Kostenträger zum Patienten    **
**************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_kostanz (LKF_AUFENTHALT *pAufenthalt)
{
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr < 2017)
    {
        if (IsBlank (pAufenthalt->KOST, sizeof (pAufenthalt->KOST))) return 0;
        else return 1;
    }
    return 0;
}

/***************************************************************************
** lkf_auf_line_root: Liefert die Satzart 1 zurück                        **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_root (LKF_AUFENTHALT *pAufenthalt, char *line)
{
#ifdef SUPPORT_PRE2017
	const char *sAdditional; /* V11.1 */
    char sAufIdBuf[68]; /* V19.0 */
    
    if (!pAufenthalt->pScoringContext || pAufenthalt->pScoringContext->modelljahr >= 2017)
        return lkf_auf_xline_root(pAufenthalt, line);
    
	if (pAufenthalt->nM01ExtOffset)
		sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->nM01ExtOffset);
	else
		sAdditional = "";

    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
        if (pAufenthalt->pScoringContext->isBM)
            sprintf (sAufIdBuf, "%3.3s%-64.64s", pAufenthalt->ALTERSGRUPPE, pAufenthalt->UCASE_PATID);
        else if (sAdditional) {
            sprintf (sAufIdBuf, "%3.3s", pAufenthalt->ALTERSGRUPPE);
            memset (sAufIdBuf + 3, ' ', 64);
            sAufIdBuf[67] = 0;
        }
        else if (!IsBlank(pAufenthalt->ALTERSGRUPPE, 3)) {
            sprintf (sAufIdBuf, "%3.3s", pAufenthalt->ALTERSGRUPPE);
        }
        else
            sAufIdBuf[0] = 0;
    } else
        sAufIdBuf[0] = 0;
    
    sprintf (line, "M01%4.4s  %10.10s%c%8.8s%c%3.3s%3.3s%6.6s%c%c   %6.6s%8.8s%c  %6.6s%8.8s%s%s",
             pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->FLAG, pAufenthalt->GEBDAT,
             pAufenthalt->GESCHL, pAufenthalt->STAATB, pAufenthalt->STAATW, pAufenthalt->PLZW,
             pAufenthalt->AUFART, pAufenthalt->AUFART2, pAufenthalt->KANR_VON, pAufenthalt->AUFDAT,
             pAufenthalt->ENTART, pAufenthalt->KANR_AN, pAufenthalt->ENTDAT, sAufIdBuf, sAdditional);
	return 1;
#else
    return lkf_auf_xline_root(pAufenthalt, line);
#endif
}

_SCORING_EXPORT int lkf_auf_line_svnr (LKF_AUFENTHALT *pAufenthalt, char *line)
{
	unsigned int i;
	char *cont_line;

	sprintf (line, "K07000000%10.10s  00%2.2s%s%4.4s  %c%4.4s %10.10s%8.8s%c%3.3s%3.3s%6.6s%c",
		pAufenthalt->PATID, pAufenthalt->KOST, 
		"      0000000000000000 0000000000                                               00000000                      0000000000                                               00000000              ",
		pAufenthalt->KANR, pAufenthalt->FLAG, pAufenthalt->KANR,
		pAufenthalt->PATID, pAufenthalt->GEBDAT, pAufenthalt->GESCHL, pAufenthalt->STAATB,
		pAufenthalt->STAATW, pAufenthalt->PLZW, pAufenthalt->AUFART);
	cont_line = line + strlen (line);

	for (i = 0; i < 5; i++) {
		if (i < pAufenthalt->abt_anz) 
			 sprintf (cont_line, "%8.8s%8.8s", pAufenthalt->abt[i].ABTFC, pAufenthalt->abt[i].ABTDAT);
		else sprintf (cont_line, "                ");
		cont_line += 16;
	}

	sprintf (cont_line, "%c%8.8s%3.3s%2.2s", pAufenthalt->ENTART, pAufenthalt->ENTDAT, pAufenthalt->HD, pAufenthalt->HD + 4);
	cont_line += 14;

	for (i = 0; i < 9; i++) {
		if (i < pAufenthalt->diag_anz)
			 sprintf (cont_line, "%3.3s%2.2s", pAufenthalt->diag[i].DIAG, pAufenthalt->diag[i].DIAG + 4);
		else sprintf (cont_line, "     ");
		cont_line += 5;
	}

	for (i = 0; i < 9; i++) {
		if (i < pAufenthalt->mel_anz) {
			 int val;
			 GetInt (pAufenthalt->mel[i].MELANZ, LKF_AUFENTHALT_MELANZ_LEN, &val);
			 sprintf (cont_line, "%7.7s%2d", pAufenthalt->mel[i].MEL, val);
		}
		else sprintf (cont_line, "         ");
		cont_line += 9;
	}

	sprintf (cont_line, "%2.2s%-8.8s %1.1s  ", pAufenthalt->KOST, pAufenthalt->GRP, pAufenthalt->KNT);
	cont_line += 14;

	sprintf (cont_line, "%8ld%8ld%8ld%8ld%8ld%8ld%8ld%8ld%8ld",
						pAufenthalt->LDFPTK, pAufenthalt->LDFPLK, pAufenthalt->SCUTK_TKL, pAufenthalt->SCULK,
						pAufenthalt->VDZU, pAufenthalt->INTZU, pAufenthalt->MELZU, pAufenthalt->SCSPEZ, pAufenthalt->SCGES_TKL);

	return 1;
}	

/***************************************************************************
** lkf_auf_line_abt: Liefert die Satzart 2 zurück                         **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_abt (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
#ifdef SUPPORT_PRE2017
	const char *sAdditional;
    unsigned int m02_intlen;
    LKF_AUFENTHALT_ABT *pAbt;

	if (i >= pAufenthalt->abt_anz) return 0;
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) return lkf_auf_xline_abt(pAufenthalt, i, line);
    
    pAbt = pAufenthalt->abt + i;
    
	if (pAufenthalt->abt[i].nExtOffset)
		sAdditional = lkf_auf_get_ext (pAufenthalt, pAbt->nExtOffset);
	else
		sAdditional = "";
    
    m02_intlen = pAufenthalt->pScoringContext->m02_intlen;
    
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015)
    { /* V19.0 */
        char betweenBuf[LKF_M02_BETWEEN_LEN + 6];
        char sAufIdBuf[65];
        int nAdditionalLen = (int) strlen (sAdditional);
        
        if (pAufenthalt->pScoringContext->isBM) {
            sprintf (sAufIdBuf, "%-64.64s", pAufenthalt->UCASE_PATID);
            if (nAdditionalLen > LKF_M02_BETWEEN_LEN) {
                memcpy(betweenBuf, sAdditional, LKF_M02_BETWEEN_LEN);
                betweenBuf[LKF_M02_BETWEEN_LEN] = 0;
                sAdditional += LKF_M02_BETWEEN_LEN;
            } else {
                if (nAdditionalLen > 0)
                    memcpy(betweenBuf, sAdditional, nAdditionalLen);
                if (nAdditionalLen < LKF_M02_BETWEEN_LEN)
                    memset(betweenBuf + nAdditionalLen, ' ', LKF_M02_BETWEEN_LEN - nAdditionalLen);
                betweenBuf[LKF_M02_BETWEEN_LEN] = 0;
                sAdditional = "";
            }
        }
        else {
            if (nAdditionalLen > LKF_M02_BETWEEN_LEN) {
                memset(sAufIdBuf, ' ', 64);
                sAufIdBuf[64] = 0;
                memcpy (betweenBuf, sAdditional, LKF_M02_BETWEEN_LEN - 4);
                betweenBuf[LKF_M02_BETWEEN_LEN - 4] = 0;
                sAdditional += LKF_M02_BETWEEN_LEN;
            } else if (nAdditionalLen > 16) {
                strncpy (betweenBuf, sAdditional, 16);
                betweenBuf[16] = 0;
                sAufIdBuf[0] = 0;
                sAdditional = "";
            } else {
                sAufIdBuf[0] = 0;
                betweenBuf[0] = 0;
            }
        }
        
        if ((pAbt->ISNEONAT != 0 && pAbt->ISNEONAT != ' ') ||
            !IsBlank(pAbt->ALTERSGRUPPE, 3)) {
            
            int lenbetween = (int) strlen(betweenBuf);
            
            if (lenbetween < 16) {
                memset (betweenBuf + lenbetween, ' ', 16 - lenbetween);
            }
            sprintf (betweenBuf+16, "%c%3.3s", pAbt->ISNEONAT, pAbt->ALTERSGRUPPE);
            
        }
        
        sprintf (line, "M02%4.4s  %10.10s%2.2s%8.8s%8.8s%-*.*s%s%s%s",
                 pAufenthalt->KANR, pAufenthalt->PATID,
                 pAbt->ABTPOS, pAbt->ABTFC, pAbt->ABTDAT,
                 m02_intlen, m02_intlen, pAbt->ABT_INTSATZ, betweenBuf, sAufIdBuf, sAdditional);
    }
    else {
        sprintf (line, "M02%4.4s  %10.10s%2.2s%8.8s%8.8s%-*.*s%s",
			 pAufenthalt->KANR, pAufenthalt->PATID,
			 pAbt->ABTPOS, pAbt->ABTFC, pAbt->ABTDAT,
			 m02_intlen, m02_intlen, pAbt->ABT_INTSATZ, sAdditional);
    }
	return 1;
#else
    return lkf_auf_xline_abt(pAufenthalt, i, line);
#endif
}

/***************************************************************************
** lkf_auf_line_diag: Liefert die Satzart 3 zurück                        **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_diag (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
#ifdef SUPPORT_PRE2017
	const char *sAdditional;
    char sAufIdBuf[65]; /* V19.0 */
    char diagTyp;
    const char *diagPos;
    const char *diag;

	if (i >= pAufenthalt->diag_anz) return 0;
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) return lkf_auf_xline_diag(pAufenthalt, i, line);

    if (pAufenthalt->diag[i].nExtOffset)
        sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->diag[i].nExtOffset);
    else
        sAdditional = "";
    diagTyp = pAufenthalt->diag[i].DIAGTYP[0];
    diagPos = pAufenthalt->diag[i].DIAGPOS;
    diag = pAufenthalt->diag[i].DIAG;
    
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
        if (pAufenthalt->pScoringContext->isBM)
            sprintf (sAufIdBuf, "%-64.64s", pAufenthalt->UCASE_PATID);
        else if (strlen(sAdditional) > 0) {
            memset (sAufIdBuf, ' ', 64);
            sAufIdBuf[64] = 0;
        }
        else {
            sAufIdBuf[0] = 0;
            if (!memcmp(diagPos, "    ", 4)) diagPos = 0;
        }
        
        if (diagPos) {
            sprintf (line, "M03%4.4s  %10.10s%6.6s %c %s%-4.4s%s",
                 pAufenthalt->KANR, pAufenthalt->PATID, diag, diagTyp,
                 sAufIdBuf, diagPos, sAdditional);
        } else {
            sprintf (line, "M03%4.4s  %10.10s%6.6s %c %s%s",
                     pAufenthalt->KANR, pAufenthalt->PATID, diag, diagTyp,
                     sAufIdBuf, sAdditional);
        }
    } else {
		sprintf (line, "M03%4.4s  %10.10s%6.6s %c %-4.4s%s",
			pAufenthalt->KANR, pAufenthalt->PATID, diag, diagTyp,
			diagPos, sAdditional);
	}
	return 1;
#else
    return lkf_auf_xline_diag(pAufenthalt, i, line);
#endif
}

/***************************************************************************
** lkf_auf_line_mel: Liefert die Satzart 4 zurück                         **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_mel (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
#ifdef SUPPORT_PRE2017
	int j;
	char melbuf[LKF_AUFENTHALT_ORIGMEL_LEN + 1];
	char melanzbuf[LKF_AUFENTHALT_ORIGMELANZ_LEN + 1];
	const char *sAdditional;

	if (i >= pAufenthalt->mel_anz) return 0;
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) return lkf_auf_xline_mel(pAufenthalt, i, line);
	
	memcpy (melanzbuf, pAufenthalt->mel[i].ORIG_MELANZ, LKF_AUFENTHALT_ORIGMELANZ_LEN);	
	memcpy (melbuf, pAufenthalt->mel[i].ORIG_MEL, LKF_AUFENTHALT_ORIGMEL_LEN);

	for (j = LKF_AUFENTHALT_MELANZ_LEN - 1; j >= 0 && melanzbuf[j] == ' '; j--) melanzbuf[j] = 0;

	if (pAufenthalt->mel[i].nExtOffset)
		sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->mel[i].nExtOffset);
	else
		sAdditional = "";
    
    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
        char sAufIdBuf[65]; /* V19.0 */
        char betweenBuf[LKF_M04_BETWEEN_LEN + 1];
        int nAdditionalLen = (int)strlen(sAdditional);
        const char *posBuf = pAufenthalt->mel[i].MELPOS;
        if (pAufenthalt->pScoringContext->isBM) {
            if (nAdditionalLen > 0)
                strncpy(betweenBuf, sAdditional, LKF_M04_BETWEEN_LEN);
            if (nAdditionalLen < LKF_M04_BETWEEN_LEN) {
                memset (betweenBuf + nAdditionalLen, ' ', LKF_M04_BETWEEN_LEN - nAdditionalLen);
            }
            betweenBuf[LKF_M04_BETWEEN_LEN] = 0;
            sprintf (sAufIdBuf, "%-64.64s", pAufenthalt->UCASE_PATID);
            if (nAdditionalLen > LKF_M04_BETWEEN_LEN)
                sAdditional += LKF_M04_BETWEEN_LEN;
            else
                sAdditional = "";
        }
        else {
            if (nAdditionalLen > LKF_M04_BETWEEN_LEN) {
                memset(sAufIdBuf, ' ', 64);
                sAufIdBuf[64] = 0;
                memcpy(betweenBuf, sAdditional, LKF_M04_BETWEEN_LEN);
                betweenBuf[LKF_M04_BETWEEN_LEN] = 0;
                sAdditional += LKF_M04_BETWEEN_LEN;
            }
            else if (memcmp (posBuf, "    ", 4)) {
                memset(sAufIdBuf, ' ', 64);
                sAufIdBuf[64] = 0;
                if (nAdditionalLen)
                    memcpy(betweenBuf, sAdditional, nAdditionalLen);
                if (nAdditionalLen < LKF_M04_BETWEEN_LEN)
                    memset(betweenBuf + nAdditionalLen, ' ', LKF_M04_BETWEEN_LEN - nAdditionalLen);
                betweenBuf[LKF_M04_BETWEEN_LEN] = 0;
                sAdditional = "";
            }
            else {
                sAufIdBuf[0] = 0;
                if (nAdditionalLen)
                    memcpy(betweenBuf, sAdditional, nAdditionalLen);
                betweenBuf[nAdditionalLen] = 0;
                posBuf = 0;
                sAdditional = "";
            }
        }
        
        if (posBuf) {
            sprintf (line, "M04%4.4s  %10.10s%10.10s%4.4s%-8.8s%s%s%4.4s%s",
                     pAufenthalt->KANR, pAufenthalt->PATID,
                     melbuf, melanzbuf, pAufenthalt->mel[i].MELDAT, betweenBuf, sAufIdBuf, posBuf, sAdditional);
        }
        else {
            sprintf (line, "M04%4.4s  %10.10s%10.10s%4.4s%-8.8s%s%s%s",
                     pAufenthalt->KANR, pAufenthalt->PATID,
                     melbuf, melanzbuf, pAufenthalt->mel[i].MELDAT, betweenBuf, sAufIdBuf, sAdditional);
        }
    }
    else {
        sprintf (line, "M04%4.4s  %10.10s%10.10s%4.4s%-8.8s%4.4s%s",
                 pAufenthalt->KANR, pAufenthalt->PATID,
                 melbuf, melanzbuf, pAufenthalt->mel[i].MELDAT, pAufenthalt->mel[i].MELPOS, sAdditional);
    }
    
    return 1;
#else
    return lkf_auf_xline_mel(pAufenthalt, i, line);
#endif
}

/***************************************************************************
** lkf_auf_line_kost: Liefert die Satzart 5 zurück                        **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_kost (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
	if (pAufenthalt->pScoringContext->modelljahr < 2017 && !i) {
		const char *sAdditional;

		if (pAufenthalt->nM05ExtOffset) /* V11.1 */
			sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->nM05ExtOffset);
		else
			sAdditional = "";

        if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
            char betweenBuf[3];
            char sAufIdBuf[65]; /* V19.0 */
            
            int nAdditionalLen = (int) strlen(sAdditional);
            
            if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->isBM) {
                sprintf (sAufIdBuf, "%-64.64s", pAufenthalt->UCASE_PATID);
                if (nAdditionalLen > 2) {
                    memcpy(betweenBuf, sAdditional, 2);
                    sAdditional += 2;
                }
                else {
                    if (nAdditionalLen > 0)
                        memcpy(betweenBuf, sAdditional, nAdditionalLen);
                    if (nAdditionalLen < 2)
                        memset(betweenBuf, ' ', 2 - nAdditionalLen);
                    sAdditional = "";
                }
                betweenBuf[2] = 0;

            }
            else {
                if (nAdditionalLen > 2) {
                    memset(sAufIdBuf, ' ', 64);
                    sAufIdBuf[64] = 0;
                    memcpy(betweenBuf, sAdditional, 2);
                    sAdditional += 2;
                } else {
					sAufIdBuf[0] = 0;
                    if (nAdditionalLen > 0)
                        memcpy(betweenBuf, sAdditional, nAdditionalLen);
                    if (nAdditionalLen < 2)
                        memset(betweenBuf + nAdditionalLen, ' ', 2 - nAdditionalLen);
                    sAdditional = "";
                }
                betweenBuf[2] = 0;
            }
            sprintf (line, "M05%4.4s  %10.10s%2.2s%s%s%s",
                     pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->KOST, betweenBuf, sAufIdBuf, sAdditional);
        }
        else {
            sprintf (line, "M05%4.4s  %10.10s%2.2s%s",
                     pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->KOST, sAdditional);
		}
        return 1;
	}
	else return 0;
}


/***************************************************************************
** lkf_auf_line_scoring: Liefert die Satzart 6 zurück                     **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_scoring (LKF_AUFENTHALT *pAufenthalt, char *line)
{
#ifdef SUPPORT_PRE2017
	LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
	const char *gruppe;
	char knoten;
	const char *sAdditional;
    char sAufIdBuf[65]; /* V19.0 */
	long scutk, scges;

    if (pAufenthalt->pScoringContext->modelljahr >= 2017) return lkf_auf_xline_scoring(pAufenthalt, line);
    
	if (pAufenthalt->subgruppe)
		pSubgruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
	else
		pSubgruppe = 0;

	if (pSubgruppe) {
		gruppe = pSubgruppe->gruppe;
		knoten = pSubgruppe->knoten_char;
	}
	else {
		gruppe = pAufenthalt->GRP;
		knoten = ' ';
	}

    scutk = pAufenthalt->SCUTK_TKL;
    scges = pAufenthalt->SCGES_TKL;
	
	if (pAufenthalt->nM06ExtOffset)
		sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->nM06ExtOffset);
	else
		sAdditional = "";

    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->modelljahr >= 2015) {
        
        if (pAufenthalt->pScoringContext->isBM) {
            sprintf (sAufIdBuf, "%-64.64s", pAufenthalt->UCASE_PATID);
        } else if (strlen(sAdditional) > 0) {
            memset (sAufIdBuf, ' ', 64);
            sAufIdBuf[64] = 0;
        } else
            sAufIdBuf[0] = 0;
    }
    else
        sAufIdBuf[0] = 0;

	sprintf (line, "M06%4.4s  %10.10s%8.8s%c  %8ld%8ld%8ld%8ld%8ld%8ld%8ld%8ld%8ld%s%s",
					pAufenthalt->KANR, pAufenthalt->PATID,
					gruppe, knoten,
					pAufenthalt->LDFPLK, pAufenthalt->LDFPTK,
					pAufenthalt->SCULK, scutk,
					pAufenthalt->VDZU, pAufenthalt->INTZU,
					pAufenthalt->MELZU, pAufenthalt->SCSPEZ,
					scges, sAufIdBuf, sAdditional);
	return 1;
#else
    return lkf_auf_xline_scoring(pAufenthalt, line);
#endif
}


/***************************************************************************
** lkf_auf_line_akwarn: Liefert die Satzart 7 zurück                       **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_akwarn2 (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line, unsigned int *pHitCount)
{
#ifdef SUPPORT_PRE2017
    unsigned int code;
	char sCode[6], sErrorIdent[6];
    char mCode;


	if (i >= pAufenthalt->akwarn_anz) return 0;
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) return lkf_auf_xline_akwarn(pAufenthalt, i, line, pHitCount);

	code = (unsigned int) pAufenthalt->akwarn[i].code;
	
    if (code > 0) {
        mCode = pAufenthalt->pScoringContext->modelljahr >= 2017 ? 'X' : 'M';
    
        if (pAufenthalt->akwarn[i].severity & LKF_SEV_ERROR)
        {
            sprintf (sCode, "E%c%2s", mCode, lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
        else if (pAufenthalt->akwarn[i].severity & LKF_SEV_INFO)
        {
            sprintf (sCode, "H%c%2s", mCode, lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
        else
        {
            sprintf (sCode, "W%c%2s", mCode, lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
    }
    else
    { /* V20.2: Fix WI-Codes */
        memcpy (sCode, pAufenthalt->akwarn[i].s4DigitCode, 4);
        sCode[4] = 0;
    }

    if (pAufenthalt->pScoringContext && pAufenthalt->pScoringContext->isBM)
        sprintf (line, "M07%4.4s  %10.10s%-10.10s%4.4s%s%-64.64s",
                 pAufenthalt->KANR, pAufenthalt->PATID,
                 pAufenthalt->akwarn[i].value, sCode,
                 pAufenthalt->akwarn[i].kommentar, pAufenthalt->UCASE_PATID);
    else
        sprintf (line, "M07%4.4s  %10.10s%-10.10s%4.4s%s",
                 pAufenthalt->KANR, pAufenthalt->PATID,
                 pAufenthalt->akwarn[i].value, sCode,
                 pAufenthalt->akwarn[i].kommentar);
    

	if (pHitCount)
		*pHitCount = pAufenthalt->akwarn[i].nHitCount;

	return 1;
#else
    return lkf_auf_xline_akwarn(pAufenthalt, i, line, pHitCount);
#endif
}

_SCORING_EXPORT int lkf_auf_line_akwarn (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{ /* liefert Anzahl Treffer des akzeptierten Warnings zurueck */
	return lkf_auf_line_akwarn2 (pAufenthalt, i, line, 0);
}

/***************************************************************************
** lkf_auf_line_kommentar: Liefert die Satzart 8 zurück                   **
***************************************************************************/

_SCORING_EXPORT int lkf_auf_line_kommentar (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
#ifdef SUPPORT_PRE2017
	const char *sAdditional;
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
        if (i == 0) return lkf_auf_xline_kommentar(pAufenthalt, line);
        else return 0;
    }
    else if (i >= pAufenthalt->kommentar_anz) return 0;


	if (!i) {
		if (pAufenthalt->nM08ExtOffset) /* V16.1 */
			sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->nM08ExtOffset);
		else
			sAdditional = "";
	} else {
		sAdditional = "";
	}
    
    if (pAufenthalt->pScoringContext->modelljahr >= 2015) {
        char betweenBuf[1001];
        char sAufIdBuf[65];
        int nAdditionalLen = (int) strlen(sAdditional);
        
        if (pAufenthalt->pScoringContext->isBM) {
            strcpy(sAufIdBuf, pAufenthalt->UCASE_PATID);
        } else {
            if (nAdditionalLen > 1000) {
                memset (sAufIdBuf, ' ', 64);
                sAufIdBuf[64] = 0;
                memcpy (betweenBuf, sAdditional, 1000);
                betweenBuf[1000] = 0;
                sAdditional += 1000;
            } else {
                sAufIdBuf[0] = 0;
                betweenBuf[0] = 0;
            }
        }
        sprintf (line, "M08%4.4s  %10.10s%-200.200s%s%s%s",
                 pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->kommentar[i].kommentar, betweenBuf, sAufIdBuf, sAdditional);
    } else {
        sprintf (line, "M08%4.4s  %10.10s%-200.200s%s",
                  pAufenthalt->KANR, pAufenthalt->PATID, pAufenthalt->kommentar[i].kommentar, sAdditional);
	}
    return 1;
#else
    return lkf_auf_xline_kommentar(pAufenthalt, line);
#endif
}



/***************************************************************************
** Routinen zur Ermittlung der Errors und Warnings:                       **
***************************************************************************/

_SCORING_EXPORT LKF_ERROR_LIST * lkf_auf_firsterror (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->pFirstError;
}

_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_nexterror (const LKF_ERROR_LIST *pError)
{
	if (pError) return pError->next;
	else return 0;
}

_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_firstwarning (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->pFirstWarning;
}

_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_firstinfo (LKF_AUFENTHALT *pAufenthalt)
{ /* V13.1 */
	return pAufenthalt->pFirstInfo;
}


_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_nextwarning (const LKF_ERROR_LIST *pError)
{
	if (pError) return pError->next;
	else return 0;
}

_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_nextinfo (const LKF_ERROR_LIST *pError)
{
	if (pError) return pError->next;
	else return 0;
}


static void lkf_auf_getEWLine (int bWarning, LKF_AUFENTHALT *pAufenthalt, const LKF_ERROR_LIST *pList, char *sBuf, unsigned int nBufLen)
{
	char sInternalBuf[1024];

	if (pList->nNewError >= 0 && pList->pContext)
	{
		char sCodeBuf[5];
		char sValueBuf[22];
        char sErrorTextBuf[256];
		LKF_SATZART_ERROR *pError = pList->pContext->pSatzartErrors->pErrors + pList->nNewError;
		lkf_getErrorIdent (pList->pContext, pError->pErrorDef, 5, sCodeBuf);
		lkf_getErrorFieldValue (pList->pContext, pError, CHECKFIELD_FELD_LANG, 22, sValueBuf, 0);
		sprintf (sInternalBuf, "%4.4s ; %-20.20s ; %s", sCodeBuf, sValueBuf, lkf_context_formatted_text(pAufenthalt->pScoringContext, pError->pErrorDef->sText, sErrorTextBuf));
	}
	else
	{
        sInternalBuf[0] = 0;
    }

	if (nBufLen > 0)
	{
		strncpy (sBuf, sInternalBuf, nBufLen);
		if (((unsigned int) strlen (sInternalBuf)) > nBufLen-1)
			sBuf[nBufLen-1] = 0;
	}
}

_SCORING_EXPORT void lkf_auf_getErrorLine (LKF_AUFENTHALT *pAufenthalt, const LKF_ERROR_LIST *pList, char *sBuf, unsigned int nBufLen)
{
	lkf_auf_getEWLine (0, pAufenthalt, pList, sBuf, nBufLen);
}

_SCORING_EXPORT void lkf_auf_getWarningLine (LKF_AUFENTHALT *pAufenthalt, const LKF_ERROR_LIST *pList, char *sBuf, unsigned int nBufLen)
{
	lkf_auf_getEWLine (1, pAufenthalt, pList, sBuf, nBufLen);
}

_SCORING_EXPORT void lkf_auf_getInfoLine (LKF_AUFENTHALT *pAufenthalt, const LKF_ERROR_LIST *pList, char *sBuf, unsigned int nBufLen)
{
	lkf_auf_getEWLine (2, pAufenthalt, pList, sBuf, nBufLen);
}


_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_firstmeldediag (LKF_AUFENTHALT *pAufenthalt)
{ /* V7.0 */
	return pAufenthalt->pFirstMeldeDiag;
}

_SCORING_EXPORT LKF_ERROR_LIST *lkf_auf_nextmeldediag (const LKF_ERROR_LIST *pMeldeDiag)
{ /* V7.0 */
	if (pMeldeDiag) return pMeldeDiag->next;
	else return 0;
}

_SCORING_EXPORT int lkf_auf_geterrorcode (const LKF_ERROR_LIST *pError, int *index)
{
	if (!pError) return 0;
	if (pError->nNewError >= 0) 
	{
		LKF_SATZART_ERROR *pNewError = pError->pContext->pSatzartErrors->pErrors + pError->nNewError;
		if (index) *index = (int) pNewError->nAddInfo;
        return (int) pNewError->pErrorDef->nCode;
	}
    return 0;
}


_SCORING_EXPORT int lkf_auf_getwarningcode (const LKF_ERROR_LIST *pError, int *index)
{
	if (!pError) return 0;
	if (pError->nNewError >= 0) 
	{
		LKF_SATZART_ERROR *pNewError = pError->pContext->pSatzartErrors->pErrors + pError->nNewError;
		if (index) *index = (int) pNewError->nAddInfo;
        return (int) pNewError->pErrorDef->nCode;
	}
    return 0;
}

/***************************************************************************
** lkf_auf_getvalue: Liefert bestimmte Werte zum Aufenthalt zurück.       **
***************************************************************************/

_SCORING_EXPORT const char *lkf_auf_getvalue (LKF_AUFENTHALT *pAufenthalt, unsigned int i, unsigned int j, char *buf)
{
	switch (i) {
	
		case SCORFIELD_KANR:
			if (buf) {
				sprintf (buf, "%4.4s", pAufenthalt->KANR);
				return buf;
			}
			else return pAufenthalt->KANR;

		default:
			break;
	}
	return 0;
}

/****************************************************************************
** lkf_sort_aufenthalt: Sortiert im Aufenthalt die Diagnosen und           **
**     Leistungen.                                                         **
****************************************************************************/

static int sort_auf_diag (const void *p1, const void *p2)
{
    LKF_AUFENTHALT_DIAG *d1, *d2;
    d1 = ((LKF_AUFENTHALT_DIAG *)p1);
    d2 = ((LKF_AUFENTHALT_DIAG *)p2);
    
    if (d1->isHD != d2->isHD) {
        if (d1->isHD) return -1;
        return 1;
    }
    
	return memcmp (d1->DIAG, d2->DIAG, LKF_AUFENTHALT_DIAG_LEN);
}

#ifdef SUPPORT_PRE2017
static int sort_auf_mel_2009 (const void *p1, const void *p2)
{ /* MEL 5stellig und ORIGMEL beruecksichtigen */
    int ret;
    
    LKF_AUFENTHALT_MEL *pM1 = ((LKF_AUFENTHALT_MEL *)p1),
    *pM2 = ((LKF_AUFENTHALT_MEL *)p2);
    
    ret = memcmp (pM1->MEL, pM2->MEL, LKF_AUFENTHALT_NEWMEL_LEN);
    if (ret) return ret;
    
    ret = memcmp (pM1->MELDAT, pM2->MELDAT, LKF_AUFENTHALT_DAT_LEN);
    if (ret) return ret;
    
    ret = memcmp (pM1->MELPOS, pM2->MELPOS, 4);
    if (ret) return ret;
    
    ret = memcmp(pM1->MELANZ, pM2->MELANZ, LKF_AUFENTHALT_MELANZ_LEN);
    if (ret) return ret;
    return memcmp(pM1->ORIG_MEL, pM2->ORIG_MEL, 10);
    
}
#endif
    
static int sort_auf_mel_2018 (const void *p1, const void *p2)
{
    int ret;
    
    LKF_AUFENTHALT_MEL *pM1 = ((LKF_AUFENTHALT_MEL *)p1),
    *pM2 = ((LKF_AUFENTHALT_MEL *)p2);
    
    ret = memcmp (pM1->MEL, pM2->MEL, LKF_AUFENTHALT_NEWMEL_LEN);
    if (ret) return ret;
    
    ret = memcmp (pM1->MELDAT, pM2->MELDAT, LKF_AUFENTHALT_DAT_LEN);
    if (ret) return ret;
    
    if (pM1->cSeite != pM2->cSeite)
        return pM1->cSeite - pM2->cSeite;
    
    ret = memcmp (pM1->MELZEIT, pM2->MELZEIT, 4);
    if (ret) return ret;
    
    ret = memcmp (pM1->FCLEIST, pM2->FCLEIST, 8);
    if (ret) return ret;
    
    ret = memcmp (pM1->MELPOS, pM2->MELPOS, 4);
    if (ret) return ret;
    
    ret = memcmp(pM1->MELANZ, pM2->MELANZ, LKF_AUFENTHALT_MELANZ_LEN);
    if (ret) return ret;
    return memcmp(pM1->ORIG_MEL, pM2->ORIG_MEL, 10);
}

_SCORING_EXPORT void lkf_sort_aufenthalt (LKF_AUFENTHALT *pAufenthalt)
{

    if (pAufenthalt->diag_anz) {
		qsort (pAufenthalt->diag, pAufenthalt->diag_anz, sizeof (LKF_AUFENTHALT_DIAG), sort_auf_diag);
    }
        
	if (pAufenthalt->mel_anz > 0) {
		if (pAufenthalt->mel[0].mel_nr == -1) {
			unsigned int i;
			for (i = 0; i < pAufenthalt->mel_anz; i++) pAufenthalt->mel[i].mel_nr = (int) i;
		}
#ifdef SUPPORT_PRE2017
        if (pAufenthalt->pScoringContext) {
            if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
                qsort (pAufenthalt->mel, pAufenthalt->mel_anz, sizeof (LKF_AUFENTHALT_MEL), sort_auf_mel_2018);
            }
            else {
                qsort (pAufenthalt->mel, pAufenthalt->mel_anz, sizeof (LKF_AUFENTHALT_MEL), sort_auf_mel_2009);
            }
        }
        else {
            qsort (pAufenthalt->mel, pAufenthalt->mel_anz, sizeof (LKF_AUFENTHALT_MEL), sort_auf_mel_2009);
        }
#else
        qsort (pAufenthalt->mel, pAufenthalt->mel_anz, sizeof (LKF_AUFENTHALT_MEL), sort_auf_mel_2018);
#endif
	}
    lkf_sort_auf_abt (pAufenthalt);
}

/**************************************************************************************
** lkf_auf_get_scorvalue: Liefert die Scoring-Werte des Aufenthalts zurück.          **
**************************************************************************************/

_SCORING_EXPORT long lkf_auf_get_scorvalue (LKF_AUFENTHALT *pAufenthalt, unsigned int field)
{

	if (field >= 1000)
	{
		MELZU_DATA *pMelZu;
		if (!pAufenthalt->subgruppe)
			return 0;
		pMelZu = pAufenthalt->subgruppe[pAufenthalt->max_index].pMelZu;
		if (!pMelZu)
			return 0;
		field -= 1000;
		if (field >= pAufenthalt->mel_anz)
			return 0;
		return pMelZu[field].lMelZu;
	}
	else
	{
		switch (field) {
            case SCORFIELD_ALTER:  return pAufenthalt->Alter;
            case SCORFIELD_GESVD:  return pAufenthalt->GESVD;
			case SCORFIELD_LDFPTK: return pAufenthalt->LDFPTK;
			case SCORFIELD_LDFPLK: return pAufenthalt->LDFPLK;
			case SCORFIELD_SCUTK:  return pAufenthalt->SCUTK;
			case SCORFIELD_SCULK:  return pAufenthalt->SCULK;
			case SCORFIELD_VDZU:   return pAufenthalt->VDZU;
			case SCORFIELD_INTZU:  return pAufenthalt->INTZU;
			case SCORFIELD_MELZU:  return pAufenthalt->MELZU;
			case SCORFIELD_SCSPEZ: return pAufenthalt->SCSPEZ;
			case SCORFIELD_SCGES:  return pAufenthalt->SCGES;
			case SCORFIELD_SCUK:   return pAufenthalt->SCULK + pAufenthalt->SCUTK;
			case SCORFIELD_LDFPK:  return pAufenthalt->LDFPTK + pAufenthalt->LDFPLK;

            case SCORFIELD_ERRORCOUNT:
                return (long) pAufenthalt->plaus_err;
                
			case SCORFIELD_SCUTK_TKL:
								   return pAufenthalt->SCUTK_TKL;
			case SCORFIELD_SCGES_TKL:
								   return pAufenthalt->SCGES_TKL;
			case SCORFIELD_TKLMEL:
								   return (long) pAufenthalt->TKLModus;
			case SCORFIELD_MAX_SUBINDEX:
								   return (long) pAufenthalt->max_index;
			case SCORFIELD_MAXMELINDEX:
								   if (pAufenthalt->max_index >= 0 && pAufenthalt->max_index < (int) pAufenthalt->subgruppe_alloc)
									   return (long) pAufenthalt->subgruppe[pAufenthalt->max_index].mel_id;
								   else
									   return 0;
            case SCORFIELD_MAXMELMELINDEX:
                return (long) pAufenthalt->nMelMelCount;
			default: return 0;	
		}
	}
}

/***************************************************************************************
** Routinen zur Abfrage Subgruppen-spezifischer Daten                                 **
***************************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_get_maxsubgruppe (LKF_AUFENTHALT *pAufenthalt)
{
    if (pAufenthalt->pat_subgruppen) {
        return (unsigned int) pAufenthalt->max_index;
    }
	else return 0;
}

_SCORING_EXPORT unsigned int lkf_auf_get_subgruppenanz (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->pat_subgruppen;
}

_SCORING_EXPORT const char *lkf_auf_get_gruppe (LKF_AUFENTHALT *pAufenthalt, char *gruppe, char *knoten)
{
	memcpy (gruppe, pAufenthalt->GRP, 8);
	gruppe[8] = 0;
	if (knoten) {
		memcpy (knoten, pAufenthalt->KNT, 2);
		knoten[2] = 0;
	}
	return gruppe;
}

_SCORING_EXPORT const char *lkf_auf_get_gruppe_mel (LKF_AUFENTHALT *pAufenthalt, char *mel)
{
	if (pAufenthalt->subgruppe) {
		memcpy (mel, pAufenthalt->subgruppe[pAufenthalt->max_index].gruppe + 8, 4);
		mel[4] = 0;

		if (IsBlank (mel, 4)) return 0;
		else return mel;
	}
	else return 0;
}

_SCORING_EXPORT const char *lkf_auf_get_subgruppe_gruppe (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *gruppe, char *knoten)
{
	if (i >= pAufenthalt->pat_subgruppen) return 0;

	memcpy (gruppe, pAufenthalt->subgruppe[i].gruppe, 8);
	gruppe[8] = 0;
	if (knoten) {
		knoten[0] = pAufenthalt->subgruppe[i].knoten_char;
		knoten[1] = ' ';
		knoten[2] = 0;
	}
	return gruppe;

}


_SCORING_EXPORT const char *lkf_auf_get_subgruppe_mel (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *mel)
{
	if (i >= pAufenthalt->pat_subgruppen) return 0;

	memcpy (mel, pAufenthalt->subgruppe[i].gruppe + 8, 6);
	
    mel[5] = 0;
    if (IsBlank (mel, 5)) return 0;
    else return mel;
}

_SCORING_EXPORT const char *lkf_auf_get_subgruppe_diag (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *diag)
{
	if (i >= pAufenthalt->pat_subgruppen) return 0;

	memcpy (diag, pAufenthalt->subgruppe[i].diag, 12);
	diag[12] = 0;

	if (IsBlank (diag, 12)) return 0;
	else return diag;
}


_SCORING_EXPORT long lkf_auf_get_subgruppe_scorvalue (LKF_AUFENTHALT *pAufenthalt, unsigned int i, unsigned int field)
{
	if (i >= pAufenthalt->pat_subgruppen) return 0;
	
	if (field >= 1000)
	{
		field -= 1000;
		if (pAufenthalt->subgruppe[i].pMelZu && pAufenthalt->mel_anz > field)
			return pAufenthalt->subgruppe[i].pMelZu[field].lMelZu;
		return 0;
	}
	else
	{

		switch (field) {
			
			case SCORFIELD_LDFPTK: return pAufenthalt->subgruppe[i].LDFPTK;
			case SCORFIELD_LDFPLK: return pAufenthalt->subgruppe[i].LDFPLK;
			case SCORFIELD_SCUTK:  return pAufenthalt->subgruppe[i].SCUTK;
			case SCORFIELD_SCULK:  return pAufenthalt->subgruppe[i].SCULK;
			case SCORFIELD_VDZU:   return pAufenthalt->subgruppe[i].VDZU;
			case SCORFIELD_MELZU:  return pAufenthalt->subgruppe[i].MELZU;
			case SCORFIELD_SCGES:  return pAufenthalt->subgruppe[i].SCGES;
			case SCORFIELD_LKA:	   return pAufenthalt->subgruppe[i].leistungs_anteil * pAufenthalt->subgruppe[i].anz;
			case SCORFIELD_MELANZ: return pAufenthalt->subgruppe[i].anz;
			case SCORFIELD_MAXMELINDEX:  
								   return (long) pAufenthalt->subgruppe[i].mel_id;
			case SCORFIELD_TKLMEL: return (long) pAufenthalt->TKLModus;
			case SCORFIELD_MAX_SUBINDEX:
								   return (long) pAufenthalt->max_index;
			default: return 0;	
		}
	}
}

/**************************************************************************************
** Routinen zum Setzen und zum Abfragen der Markierung (Filter)                      **
**************************************************************************************/

_SCORING_EXPORT int lkf_auf_is_marked (LKF_AUFENTHALT *pAufenthalt)
{
    return pAufenthalt->mark;
}

_SCORING_EXPORT int lkf_auf_mark (LKF_AUFENTHALT *pAufenthalt, int m)
{
	int om;
	om = pAufenthalt->mark;
	pAufenthalt->mark = m;
	return om;
}

/**************************************************************************************
** Routinen für den Optimizer                                                        **
**************************************************************************************/

_SCORING_EXPORT int lkf_auf_is_optimizable (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->optimizeable;
}

_SCORING_EXPORT int lkf_auf_get_opt_subgruppe (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->optimized_subgruppe;
}

_SCORING_EXPORT int lkf_auf_get_min_subgruppe (LKF_AUFENTHALT *pAufenthalt)
{
	unsigned int i;
	int min_gruppe;
	long scorvalue;
	
	if (pAufenthalt->pat_subgruppen < 1) return -1;

	min_gruppe = 0;
	scorvalue = pAufenthalt->subgruppe[0].SCGES;

	for (i = 1; i < pAufenthalt->pat_subgruppen; i++) {
		if (pAufenthalt->subgruppe[i].SCGES < scorvalue) {
			min_gruppe = (int) i;
			scorvalue = pAufenthalt->subgruppe[i].SCGES;
		}
	}
	return min_gruppe;
}

_SCORING_EXPORT double lkf_auf_get_opt_percentage (LKF_AUFENTHALT *pAufenthalt)
{
	return pAufenthalt->optimized_percentage;
}

/****************************************************************************************
** function lkf_auf_getmeldediag: Liefert Informationen zur meldepflichtigen Diagnose  **
****************************************************************************************/

_SCORING_EXPORT char lkf_auf_getmeldediag (const LKF_ERROR_LIST *pMeldeDiag, long *index)
{
	if (!pMeldeDiag) return 0; 
	if (index) *index = pMeldeDiag->index;
	return (char) pMeldeDiag->code;
}

/****************************************************************************************
** function lkf_auf_getintlineanz: Liefert die Anzahl Intensiv-Scoring-Zeilen, die für **
**     diesen Aufenthalt gemeldet wurden, zurück (V8.1)                                **
****************************************************************************************/

_SCORING_EXPORT unsigned int lkf_auf_getintlineanz (LKF_AUFENTHALT *pAufenthalt)
{
#ifdef SUPPORT_PRE2017
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
        if (pAufenthalt->pIntensiv)
            return pAufenthalt->pIntensiv->lineCount;
    }
    else if (pAufenthalt->pLineBuffer)
		return (unsigned int) pAufenthalt->pLineBuffer->lLineCount;
#else
    if (pAufenthalt->pIntensiv) return pAufenthalt->pIntensiv->lineCount;
#endif
	return 0;
}

/****************************************************************************************
** function lkf_auf_getintline: Liefert eine Zeile des Intensiv-Scoring zurück         **
****************************************************************************************/
_SCORING_EXPORT int lkf_auf_getintline (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *l) {
    return lkf_auf_getintLineAndIdent(pAufenthalt, index, l, 0);
}

_SCORING_EXPORT int lkf_auf_getintLineAndIdent (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *l, char *ident)
{
#ifdef SUPPORT_PRE2017
    if (pAufenthalt->pScoringContext->modelljahr >= 2017) {
        return lkf_auf_getintxline (pAufenthalt, index, l, ident);
    }
    
	if (pAufenthalt->pLineBuffer && pAufenthalt->pLineBuffer->lLineCount > index) {	
        if (ident) {
            sprintf (ident, "INT:%d", index);
        }
        if (pAufenthalt->pScoringContext->isBM & 2)
        { /* V19.0 */
            unsigned long sl;
			strcpy (l, pAufenthalt->pLineBuffer->pBuf + pAufenthalt->pLineBuffer->plOffsets[index]);
            sl = (unsigned long) strlen (l);
            
            if (l[2] == '1') {
                if (sl < 116) memset (l + sl, ' ', 116 - sl);
                strncpy (l + 116, pAufenthalt->UCASE_PATID, 64);
                l[180] = 0;
                memset (l + 9, ' ', 10);
            } else {
                if (sl < 59) memset (l + sl, ' ', 59 - sl);
                strncpy (l + 59, pAufenthalt->UCASE_PATID, 64);
                l[59+64] = 0;
                memset (l + 9, ' ', 10);
            }
            return 0;
        }
		strcpy (l, pAufenthalt->pLineBuffer->pBuf + pAufenthalt->pLineBuffer->plOffsets[index]);

	}
    else {
        l[0] = 0;
        if (ident) {
            *ident = 0;
        }
    }
	return 0;
#else
    return lkf_auf_getintxline (pAufenthalt, index, l, ident);
#endif
}

/*******************************************************************************************
** function lkf_auf_add_ext: Speichert Zusatzinformationen zum Aufenthalt (Null-term.     **
**                           String) und retourniert den Offset.                          **
** function lkf_auf_add_ext_len: Speichert Zusatzinfo und retourniert Offset.             **
** function lkf_auf_get_ext: Retourniert zum Offset den entsprechenden Buffer.            **
*******************************************************************************************/

#define LKF_AUFEXT_INITLEN     512
#define LKF_AUFEXT_EXTLEN     1024

unsigned int lkf_auf_add_ext_len (LKF_AUFENTHALT *pAufenthalt, const char *sBuf, unsigned int nBufLen)
{
	unsigned int nOffset = pAufenthalt->nLineExtCount + nBufLen + 1;

	if (nOffset > pAufenthalt->nLineExtAlloc)
	{
		char *psOldBuffer = pAufenthalt->psLineExt;

		if (pAufenthalt->psLineExt)
			pAufenthalt->nLineExtAlloc += LKF_AUFEXT_EXTLEN;
		else
			pAufenthalt->nLineExtAlloc = LKF_AUFEXT_INITLEN;
		if (pAufenthalt->nLineExtAlloc < nOffset + 1) pAufenthalt->nLineExtAlloc = nOffset + 1;

		pAufenthalt->psLineExt = (char *) LKF_MALLOC (pAufenthalt->pScoringContext, "lkf_auf_add_ext_len", pAufenthalt->nLineExtAlloc);
        if (!pAufenthalt->psLineExt) return 0;

		if (psOldBuffer)
		{
			memcpy (pAufenthalt->psLineExt, psOldBuffer, pAufenthalt->nLineExtCount);
			LKF_FREE (pAufenthalt->pScoringContext, "lkf_auf_add_ext_len", psOldBuffer);
		}
		else
		{ /* Zero-Length Buffer werden als Index 0 abgebildet */
			pAufenthalt->psLineExt[0] = 0;
			pAufenthalt->nLineExtCount = 1;
		}
	}

	memcpy (pAufenthalt->psLineExt + pAufenthalt->nLineExtCount, sBuf, nBufLen);
	nOffset = pAufenthalt->nLineExtCount;
	pAufenthalt->psLineExt[pAufenthalt->nLineExtCount+=nBufLen] = 0;
	pAufenthalt->nLineExtCount++;
	return nOffset;
}

unsigned int lkf_auf_add_ext (LKF_AUFENTHALT *pAufenthalt, const char *sBuf)
{
	unsigned int nBufLen = (unsigned int) strlen (sBuf);
	while (nBufLen > 0 && (sBuf[nBufLen-1] == ' ' || sBuf[nBufLen-1] == '\r' || sBuf[nBufLen-1] == '\n')) -- nBufLen;
	if (nBufLen > 0)
		return lkf_auf_add_ext_len (pAufenthalt, sBuf, nBufLen);
	else
		return 0;
}

const char *lkf_auf_get_ext (LKF_AUFENTHALT *pAufenthalt, unsigned int nOffset)
{
	if (pAufenthalt->psLineExt && pAufenthalt->nLineExtCount > nOffset)
		return pAufenthalt->psLineExt + nOffset;
	else
		return 0;
}

/***** lkf_auf_get_abtvalue */

_SCORING_EXPORT long lkf_auf_get_abtscor100 (LKF_AUFENTHALT *pAufenthalt, unsigned int abtIndex, char *abtpos, long *tp100, long *lp100)
{ /* V21.4 */
    LKF_AUFENTHALT_ABT *pAbt = pAufenthalt->abt + abtIndex;
	if (abtpos) {
		memcpy (abtpos, pAbt->ABTPOS, 3);
		abtpos[3] = 0;
	}
	if (tp100) *tp100 = pAbt->tp100;
    if (lp100) *lp100 = pAbt->lp100;
    return pAbt->tp100 + pAbt->lp100;
}

_SCORING_EXPORT double lkf_auf_get_abtscor (LKF_AUFENTHALT *pAufenthalt, unsigned int abtIndex, char *abtpos, double *tp, double *lp)
{ /* V21.4 */
    LKF_AUFENTHALT_ABT *pAbt = pAufenthalt->abt + abtIndex;
	if (abtpos) {
		memcpy (abtpos, pAbt->ABTPOS, 3);
		abtpos[3] = 0;
	}
	if (tp) *tp = (pAbt->tp100 / 100.0);
    if (lp) *lp = (pAbt->lp100 / 100.0);
    return (pAbt->tp100 + pAbt->lp100) / 100.0;
}

/*** V22.1: MEL-Daten **/

_SCORING_EXPORT int lkf_auf_get_melIndexForPos (LKF_AUFENTHALT *pAufenthalt, char *melpos) 
{
	unsigned int i;
	unsigned int sigLen = 4;

	for (i = 0; i < 4; i++) {
		if (melpos[i] == 0) {
			sigLen = i;
			break;
		}
	}

	while (sigLen > 0 && melpos[sigLen - 1] == ' ')
		--sigLen;

	for (i = 0; i < pAufenthalt->mel_anz; i++) 
	{
		const char *compare_melpos = pAufenthalt->mel[i].MELPOS;
		if (!memcmp (compare_melpos, melpos, sigLen)) 
		{
			int hit = 1;
			unsigned int j;
			for (j = sigLen; j < 4; j++) {
				if (compare_melpos[i] == 0) return (int) i;
				else if (compare_melpos[i] != ' ') {
					hit = 0;
					break;
				}
			}
			if (hit) return (int) i;
		}
	}
	return -1;
}


_SCORING_EXPORT const char *lkf_auf_get_mel_value (LKF_AUFENTHALT *pAufenthalt, unsigned int melId, unsigned int melFieldIndex, unsigned int buflen, char *buf)
{
    char internalbuf[256];
    LKF_AUFENTHALT_MEL *mel;
    LKF_AUFENTHALT_SUBGRUPPE *pSubGruppe;
    MEL_ARRAY_STRUC *pMelStruc;
    unsigned int melGruppeIndex;
    unsigned int i;
    unsigned int subgruppenIndex = 0;

    mel = pAufenthalt->mel + melId;

    switch (melFieldIndex) {
        case LKF_MELFIELD_MELZU:
        case LKF_MELFIELD_LDFPLK:
        case LKF_MELFIELD_LEIST:
            sprintf (internalbuf, "%ld", lkf_auf_get_mel_field(pAufenthalt, melId, melFieldIndex));
            break;
        case LKF_MELFIELD_RELEVANT:
            melGruppeIndex = mel->gruppeIndex;
            mel = pAufenthalt->mel + melGruppeIndex;
            internalbuf[0] = '0' + mel->punkteRelevant;
            internalbuf[1] = 0;
            break;
        case LKF_MELFIELD_MELMELINFO:
            sprintf (internalbuf, "%s", mel->melmelInfo);
            break;
        case LKF_MELFIELD_MELMELPOOL:
            sprintf (internalbuf, "%d", mel->nMelMelIndexSep);
            break;

        case LKF_MELFIELD_HAUPTINDEX:
            melGruppeIndex = mel->gruppeIndex;
            mel = pAufenthalt->mel + melGruppeIndex;
            internalbuf[0] = mel->punkteRelevant == 2 ? '2' : 0;
            internalbuf[1] = 0;
            break;
        case LKF_MELFIELD_MELPOS:
            strncpy (internalbuf, mel->MELPOS, 4);
            internalbuf[4] = 0;
            break;
        case LKF_MELFIELD_MEL:
            strncpy (internalbuf, mel->MEL, 5);
            internalbuf[5] = 0;
            break;
            
        case LKF_MELFIELD_ORIGMEL:
            if (mel->ORIG_MEL[0]) {
                strncpy (internalbuf, mel->ORIG_MEL, 5);
            }
            else {
                strncpy (internalbuf, mel->MEL, 5);
            }
            internalbuf[5] = 0;
            break;

        case LKF_MELFIELD_ORIGMELANZ:
            if (mel->ORIG_MELANZ[0]) {
                sprintf (internalbuf, "%-4.4s", mel->ORIG_MELANZ);
            }
            else {
                sprintf (internalbuf, "%-4.4s", mel->MELANZ);
            }
            break;

        case LKF_MELFIELD_SEITE:
            internalbuf[0] = mel->cSeite;
            internalbuf[1] = 0;
            break;
        case LKF_MELFIELD_COUNT:
            sprintf (internalbuf, "%-4.4s", mel->MELANZ);
            break;
            
        case LKF_MELFIELD_TEXT:
            pMelStruc = FindMel(pAufenthalt->pScoringContext, mel->MEL);
            if (!pMelStruc) {
                internalbuf[0] = 0;
            }
            else {
                strcpy (internalbuf, pMelStruc->sText);
                internalbuf[100] = 0;
            }
            break;
        case LKF_MELFIELD_AMBGRP:
            pMelStruc = FindMel(pAufenthalt->pScoringContext, mel->MEL);
            if (!pMelStruc) {
                internalbuf[0] = 0;
            }
            else {
                strcpy (internalbuf, pMelStruc->sAmbGruppe);
                internalbuf[100] = 0;
            }
            break;
        case LKF_MELFIELD_STATGRP:
            pMelStruc = FindMel(pAufenthalt->pScoringContext, mel->MEL);
            if (!pMelStruc) {
                internalbuf[0] = 0;
            }
            else {
                strcpy (internalbuf, pMelStruc->sGruppe);
                internalbuf[100] = 0;
            }
            break;

        case LKF_MELFIELD_DATE:
            strncpy (internalbuf, mel->MELDAT, 8);
            internalbuf[8] = 0;
            break;

        case LKF_MELFIELD_UHRZEIT:
             strncpy (internalbuf, mel->MELZEIT, 4);
             internalbuf[4] = 0;
             break;

        case LKF_MELFIELD_FCLEIST:
            strncpy (internalbuf, mel->FCLEIST, 8);
            internalbuf[8] = 0; /* V2024.0: 6 -> 8 */
            break;
        case LKF_MELFIELD_KALEIST:
            strncpy (internalbuf, mel->KALEIST, 6);
            internalbuf[6] = 0;
            break;
        case LKF_MELFIELD_ABTINDEX:
            sprintf (internalbuf, "%d", mel->nMelAbtIndex);
            break;
        case LKF_MELFIELD_ABTPOS:
            if (mel->nMelAbtIndex >= 0 && mel->nMelAbtIndex < (int) pAufenthalt->abt_anz) {
                strncpy (internalbuf, pAufenthalt->abt[mel->nMelAbtIndex].ABTPOS, 4);
                internalbuf[3] = 0;
            }
            else {
                internalbuf[0] = 0;
            }
            break;
        case LKF_MELFIELD_SUBGRUPPENINDEX:
        case LKF_MELFIELD_GRUPPE:
        case LKF_MELFIELD_KNOTEN:
            melGruppeIndex = mel->gruppeIndex;
 
            if (pAufenthalt->isAmb == 1) {
                mel = pAufenthalt->mel + melGruppeIndex;
               if (melFieldIndex == LKF_MELFIELD_GRUPPE) {
                    sprintf (internalbuf, "%8.8s", mel->ambGruppe);
                }
                else {
                    internalbuf[0] = mel->ambKnoten;
                    internalbuf[1] = 0;
                }
            }
            else {
                pSubGruppe = 0;
                for (i = 0; !pSubGruppe && i < pAufenthalt->pat_subgruppen; i++) {
                    if (pAufenthalt->subgruppe[i].mel_id == melGruppeIndex) {
                        pSubGruppe = pAufenthalt->subgruppe + i;
                        subgruppenIndex = i;
                    }
                }
                if (!pSubGruppe) {
                    buf[0] = 0;
                    return buf;
                }
                
                if (melFieldIndex == LKF_MELFIELD_GRUPPE) {
                    sprintf (internalbuf, "%8.8s", pSubGruppe->gruppe);
                }
                else if (melFieldIndex == LKF_MELFIELD_SUBGRUPPENINDEX) {
                    sprintf (internalbuf, "%d", subgruppenIndex);
                }
                else {
                    internalbuf[0] = pSubGruppe->knoten_char;
                    internalbuf[1] = 0;
                }
            }
            break;
        case LKF_MELFIELD_SUBGRUPPE_HAUPTX04:
            if (mel->gruppeIndex == mel->mel_nr) {
                sprintf (internalbuf, "%-4.4s", mel->MELANZ);
            }
            else {
                internalbuf[0] = 0;
            }
            break;
        default:
            return 0;
    }
    
    if (buflen && buflen <= (unsigned int) strlen(internalbuf)) {
        memcpy (buf, internalbuf, buflen);
    }
    else {
        strcpy (buf, internalbuf);
    }
    
    return buf;
}

_SCORING_EXPORT long lkf_auf_get_mel_field (LKF_AUFENTHALT *pAufenthalt, unsigned int melId, unsigned int melFieldIndex) 
{
    long v;
	LKF_AUFENTHALT_MEL *mel;
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
	if (melId >= pAufenthalt->mel_anz) return 0;
	mel = pAufenthalt->mel + melId;
 
	switch (melFieldIndex) {
	case LKF_MELFIELD_MELZU:
        return mel->melzu + mel->ambFixPunkte;
    case LKF_MELFIELD_LDFPLK:
    case LKF_MELFIELD_LEIST:
        if (pAufenthalt->isAmb == 1){
            v = 0;
        } else {
            pSubgruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
            if (pSubgruppe) {
                v = (pSubgruppe->mel_id == melId) ? pAufenthalt->LDFPLK + pAufenthalt->SCULK : 0;
            }
            else {
                v = 0;
            }
        }
        if (melFieldIndex == LKF_MELFIELD_LEIST)
            v += mel->melzu + mel->ambFixPunkte;
        return v;
	default:
		return 0;
	
	}
}

_SCORING_EXPORT const LKF_SATZART_ERROR *lkf_auf_getSatzartError (LKF_AUFENTHALT *pAufenthalt) {
    if (pAufenthalt->nSatzartFirstError >= 0) {
        return Satzart_GetSatzartError (pAufenthalt->pScoringContext->pSatzartErrors, pAufenthalt->nSatzartFirstError);
    }
    return 0;
}

_SCORING_EXPORT const LKF_SATZART_ERROR *lkf_auf_getNextSatzartError (const LKF_SATZART_ERROR *pError) {
    if (pError->nAufNextErrorIndex >= 0) {
        return Satzart_GetSatzartError(pError->pAufenthalt->pScoringContext->pSatzartErrors, pError->nAufNextErrorIndex);
    }
    return 0;
}

_SCORING_EXPORT int lkf_auf_isAmb (LKF_AUFENTHALT *pAufenthalt) {
    return pAufenthalt->isAmb;
}


static int lkf_diag_match (LKF_AUFENTHALT_DIAG *pDiag, long long diagLongKey) {
    if (pDiag->diagLongKey == 0) {
        pDiag->diagLongKey = lkf_get_diagLongKey (0, pDiag->DIAG);
    }
    return pDiag->diagLongKey == diagLongKey;
}

_SCORING_EXPORT int lkf_auf_findFirstDiagIndex (LKF_AUFENTHALT *pAufenthalt, long long diagLongKey)
{ /* V2022.1 */
    unsigned int i;
    for (i = 0; i < pAufenthalt->diag_anz; i++) {
        if (lkf_diag_match(pAufenthalt->diag + i, diagLongKey))
        {
            return (int) i;
        }
    }
    return -1;
}

static int lkf_mel_match (LKF_AUFENTHALT_MEL *pMel, long long melLongKey)
{ /* V2022.1 */
    if (pMel->melLongKey == 0) {
        pMel->melLongKey = lkf_get_melLongKey(0, pMel->MEL);
    }
    return pMel->melLongKey == melLongKey;
}

_SCORING_EXPORT int lkf_auf_findFirstMelIndex (LKF_AUFENTHALT *pAufenthalt, long long melLongKey)
{ /* V2022.1 */
    unsigned int i;
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        if (lkf_mel_match(pAufenthalt->mel + i, melLongKey)) {
            return (int) i;
        }
    }
    return -1;
}
    
_SCORING_EXPORT int lkf_auf_findFirstDiagString (LKF_AUFENTHALT *pAufenthalt, const char *diag, unsigned int diaglen)
{ /* V2025.2 */
    unsigned int i;
    for (i = 0; i < pAufenthalt->diag_anz; i++) {
        if (!memcmp (pAufenthalt->diag[i].DIAG, diag, diaglen)) {
            return (int) i;
        }
    }
    return -1;
}
    
_SCORING_EXPORT int lkf_auf_findFirstAbtString (LKF_AUFENTHALT *pAufenthalt, const char *abtfc, unsigned int abtlen)
{ /* V2025.2 */
    unsigned int i;
    for (i = 0; i < pAufenthalt->abt_anz; i++) {
        if (!memcmp (pAufenthalt->abt[i].ABTFC, abtfc, abtlen)) {
            return (int) i;
        }
    }
    return -1;
}


_SCORING_EXPORT int lkf_auf_findFirstMelString (LKF_AUFENTHALT *pAufenthalt, const char *mel, unsigned int mellen)
{ /* V2025.2 */
    unsigned int i;
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        if (!memcmp (pAufenthalt->mel[i].MEL, mel, mellen)) {
            return (int) i;
        }
    }
    return -1;
}

_SCORING_EXPORT int lkf_auf_matchGroupString (LKF_AUFENTHALT *pAufenthalt, const char *groupString, unsigned int grouplen)
{ /* V2025.2 */
    if (grouplen >= 10) {
        if (memcmp (pAufenthalt->GRP, groupString, 8)) {
            return 0;
        }
        return pAufenthalt->KNT[0] == groupString[9];
    }
    return memcmp (pAufenthalt->GRP, groupString, grouplen) == 0;
}


void lkf_scoringdetails_alloc (LKF_AUFENTHALT *pAufenthalt)
{ /* V2023.0 */
    
    LKF_SCORINGDETAILS *pScoring;
    if (pAufenthalt->pScoringDetails) {
        lkf_scoringdetails_free (pAufenthalt);
    }
    pScoring = (LKF_SCORINGDETAILS *) LKF_MALLOC(pAufenthalt->pScoringContext, "lkf_scoringdetails_alloc", sizeof(LKF_SCORINGDETAILS));
    pAufenthalt->pScoringDetails = pScoring;
    memset (pScoring, 0, sizeof(LKF_SCORINGDETAILS));
    pScoring->pAufenthalt = pAufenthalt;
    if (pAufenthalt->abt_anz) {
        pScoring->pAbt = (LKF_SCORINGDETAILS_ABT *) LKF_CALLOC(pAufenthalt->pScoringContext, "lkf_scoringdetails_alloc.abt", pAufenthalt->abt_anz, sizeof(LKF_SCORINGDETAILS_ABT));
    }
    if (pAufenthalt->mel_anz) {
        pScoring->pGroup = (LKF_SCORINGDETAILS_GROUP *) LKF_CALLOC(pAufenthalt->pScoringContext, "lkf_scoringdetails_alloc.group", pAufenthalt->mel_anz, sizeof(LKF_SCORINGDETAILS_GROUP));
    }
    if (pAufenthalt->diag_anz > 0) {
        pScoring->pDiagGroup = (LKF_SCORINGDETAILS_GROUP *) LKF_CALLOC(pAufenthalt->pScoringContext, "lkf_scoringdetails_alloc.diag", sizeof(LKF_SCORINGDETAILS_GROUP), pAufenthalt->diag_anz);
    }
}

void lkf_scoringdetails_free (LKF_AUFENTHALT *pAufenthalt)
{ /* V2023.0 */
    LKF_SCORINGDETAILS *pScoring;
    LKF_CONTEXT *pContext;
    pScoring = pAufenthalt->pScoringDetails;
    pContext = pAufenthalt->pScoringContext;
    pAufenthalt->pScoringDetails = 0;
    if (pScoring->pAbt) {
        LKF_FREE (pContext, "lkf_scoringdetails_free.abt", pScoring->pAbt);
    }
    if (pScoring->pGroup) {
        LKF_FREE(pContext, "lkf_scoringdetails_free.group", pScoring->pGroup);
    }
    if (pScoring->pDiagGroup) {
        LKF_FREE(pContext, "lkf_scoringdetails_free.diag", pScoring->pDiagGroup);
    }
    LKF_FREE (pContext, "lkf_scoringdetails_free", pScoring);
}

void lkf_scoringdetails_addComment (LKF_AUFENTHALT *pAufenthalt, const char *comment) {
    LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pAufenthalt->pScoringDetails ? pAufenthalt->pScoringDetails->pCurrentGroup : 0;
    
    if (pScoringDetailsGroup && pScoringDetailsGroup->comment_count < LKF_SCORINGDETAILS_MAXCOMMENTCOUNT) {
        strncpy (pScoringDetailsGroup->comment[pScoringDetailsGroup->comment_count], comment, LKF_SCORINGDETAILS_COMMENTLEN);
        pScoringDetailsGroup->comment[pScoringDetailsGroup->comment_count++][LKF_SCORINGDETAILS_COMMENTLEN-1] = 0;
    }
}

_SCORING_EXPORT int lkf_scoringdetails_getHead (LKF_AUFENTHALT *pAufenthalt, char *buf, unsigned int buflen)
{ /* V2023.0 */
    LKF_SCORINGDETAILS *pScoringDetails;
    char localbuf[1024];
    localbuf[0] = 0;
    pScoringDetails = pAufenthalt->pScoringDetails;
    
    if (pScoringDetails) {
        sprintf (localbuf, "%d|%d|1", pAufenthalt->max_index, pScoringDetails->isDIAGGroup);
    }
    else {
        sprintf (localbuf, "%d|%d|0", pAufenthalt->pat_subgruppen, pAufenthalt->optimizeable);
    }
    
    if (buflen > 0) {
        strncpy (buf, localbuf, buflen);
        return 1;
    }
    return 0;
}

_SCORING_EXPORT unsigned int lkf_scoringdetails_getMELCommentCount (LKF_AUFENTHALT *pAufenthalt, unsigned int group)
{
    LKF_SCORINGDETAILS *pScoringDetails =  pAufenthalt->pScoringDetails;
    
    if (pScoringDetails) {
        LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pScoringDetails->pGroup + group;
        if (pScoringDetailsGroup)
            return pScoringDetailsGroup->comment_count;
    }
    return 0;
}

_SCORING_EXPORT unsigned int lkf_scoringdetails_getDIAGCommentCount (LKF_AUFENTHALT *pAufenthalt, unsigned int group)
{
    LKF_SCORINGDETAILS *pScoringDetails = pAufenthalt->pScoringDetails;
    if (pScoringDetails) {
        
        LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pScoringDetails->pDiagGroup + group;
        if (pScoringDetailsGroup)
            return pScoringDetailsGroup->comment_count;
    }
    return 0;
}

static int lkf_scoringdetails_getGroupComment (LKF_AUFENTHALT *pAufenthalt, LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup, unsigned int index, char *buf, unsigned int buflen)
{ /* V2023.0 */
    
    if (pScoringDetailsGroup && index < pScoringDetailsGroup->comment_count) {
        if (buflen > 0) {
            strncpy (buf, pScoringDetailsGroup->comment[index], buflen);
        }
        return 1;
    }
    if (buflen) buf[0] = 0;
    return 0;
}


_SCORING_EXPORT int lkf_scoringdetails_getMELComment (LKF_AUFENTHALT *pAufenthalt, unsigned int group, unsigned int index, char *buf, unsigned int buflen)
{ /* V2023.0 */
    LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pAufenthalt->pScoringDetails->pGroup + group;
    return lkf_scoringdetails_getGroupComment (pAufenthalt, pScoringDetailsGroup, index, buf, buflen);
}

_SCORING_EXPORT int lkf_scoringdetails_getDIAGComment (LKF_AUFENTHALT *pAufenthalt, unsigned int group, unsigned int index, char *buf, unsigned int buflen)
{ /* V2023.0 */
    LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pAufenthalt->pScoringDetails->pDiagGroup + group;
    return lkf_scoringdetails_getGroupComment (pAufenthalt, pScoringDetailsGroup, index, buf, buflen);
}


_SCORING_EXPORT int lkf_scoringdetails_getAbt (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *buf, unsigned int buflen)
{ /* V2023.0 */
    char localbuf[1024];
    localbuf[0] = 0;

    if (pAufenthalt->pScoringDetails && index < pAufenthalt->abt_anz) {
        LKF_SCORINGDETAILS_ABT *pScoringDetailsAbt = pAufenthalt->pScoringDetails->pAbt + index;
        sprintf (localbuf, "%ld|%s|%ld|%ld|%ld", pScoringDetailsAbt->abtVD, pScoringDetailsAbt->spezBereich, pScoringDetailsAbt->spezPunkte, pScoringDetailsAbt->lp100, pScoringDetailsAbt->tp100);
        if (buflen > 0) {
            strncpy (buf, localbuf, buflen);
        }
        return 1;
    }
    if (buflen) buf[0] = 0;
    return 0;
}

static int lkf_scoringdetails_getGroupInfo (LKF_AUFENTHALT *pAufenthalt, LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup, char *buf, unsigned int buflen) {
    char localbuf[1024];
    localbuf[0] = 0;

    if (!pAufenthalt->subgruppe) {
        strcpy (localbuf, "9");
    }
    else if (pScoringDetailsGroup->inactive) {
        sprintf (localbuf, "%d|||%d", pScoringDetailsGroup->inactive, pScoringDetailsGroup->subgruppeIndex);
    }
    else {
        LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe = pAufenthalt->subgruppe + pScoringDetailsGroup->subgruppeIndex;
        sprintf (localbuf, "%d|%8.8s|%c|%d|%d", pScoringDetailsGroup->inactive, pSubgruppe->gruppe, pSubgruppe->knoten_char, pScoringDetailsGroup->subgruppeIndex, pScoringDetailsGroup->originalMelIndex);
    }
    
    if (buflen > 0) {
        strncpy (buf, localbuf, buflen);
    }
    return 1;
}

_SCORING_EXPORT int lkf_scoringdetails_getMELInfo (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *buf, unsigned int buflen) {

    if (pAufenthalt->pScoringDetails && index < pAufenthalt->mel_anz) {
        LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pAufenthalt->pScoringDetails->pGroup + index;
        return lkf_scoringdetails_getGroupInfo (pAufenthalt, pScoringDetailsGroup, buf, buflen);
    }
    if (buflen) buf[0] = 0;
    return 0;
}

_SCORING_EXPORT int lkf_scoringdetails_getDIAGInfo (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *buf, unsigned int buflen) {
    if (pAufenthalt->pScoringDetails && index < pAufenthalt->diag_anz) {
        LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup = pAufenthalt->pScoringDetails->pDiagGroup + index;
        return lkf_scoringdetails_getGroupInfo (pAufenthalt, pScoringDetailsGroup, buf, buflen);
    }
    if (buflen) buf[0] = 0;
    return 0;

}

_SCORING_EXPORT int lkf_scoringdetails_getSubgruppeMEL (LKF_AUFENTHALT *pAufenthalt, int subgruppeIndex, unsigned int melIndex, char *buf, unsigned int buflen)
{
    char localBuf[2048];
    int pos;
    MEL_ARRAY_STRUC *pMelDef;
    MELZU_DATA *pMelZuData;
    LKF_AUFENTHALT_MEL *pMel;
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
    
    pMel = pAufenthalt->mel + melIndex;
    if (pMel->nMelIndex >= 0) {
        pMelDef = GetMELArrayFromIndex (pAufenthalt->pScoringContext, pMel->nMelIndex);
        if (IsEmpty (pMelDef->sGruppe, 8)) {
            return 0;
        }
    }
    else {
        return 0;
    }
    
    pSubgruppe = pAufenthalt->subgruppe + subgruppeIndex;
    if (pSubgruppe->pMelZu) {
        pMelZuData = pSubgruppe->pMelZu + melIndex;
        pos = sprintf (localBuf, "%ld|%ld|%d|%ld|%d|", pMelZuData->lMelZu, pMel->melzu, pMelZuData->nDynMelId, pMelZuData->lDynMelDiff, pMel->nMelMelIndex);
    }
    else {
        pos = sprintf (localBuf, "0|%ld|-1|0|%d|", pMel->melzu, pMel->nMelMelIndex);
    }
    if (pMel->nMelMelIndex > 0) {
        unsigned int i;
        for (i = 0; i < pAufenthalt->mel_anz; i++) {
            LKF_AUFENTHALT_MEL *pOther = pAufenthalt->mel + i;
            if (pOther->nMelMelIndex == pMel->nMelMelIndex) {
                switch (pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX (pAufenthalt,melIndex,i)]) {
                    case MELMELGROUP_DYN:
                        localBuf[pos++] = 'D';
                        break;
                    case MELMELGROUP_WIN:
                        localBuf[pos++] = 'W';
                        break;
                    case MELMELGROUP_LOSE:
                        localBuf[pos++] = 'L';
                        break;
                    default:
                        localBuf[pos++] = '?';
                        break;
                }
            }
        }
        localBuf[pos++] = '|';
    }
    else {
        localBuf[pos++] = '|';
    }
    localBuf[pos] = 0;
    
    if (buflen > 0) {
        strncpy (buf, localBuf, buflen);
    }
    return 1;
}

_SCORING_EXPORT int lkf_scoringdetails_getSubgruppe (LKF_AUFENTHALT *pAufenthalt, int index, char *buf, unsigned int buflen) {
    
    int pos;
    char localbuf[2048];
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
    
    if (!pAufenthalt->subgruppe && index >= 0) {
        if (buflen > 0) {
            buf[0] = 0;
        }
        return 0;
    }
    
    if (index >= 0) {
        
        const char *diagmel;
        
        pSubgruppe = pAufenthalt->subgruppe + index;
        
        if (pSubgruppe->mel_id >= 0) {
            diagmel = pAufenthalt->mel[pSubgruppe->mel_id].MEL;
        }
        else {
            diagmel = pSubgruppe->diag;
        }
        
        pos = sprintf(localbuf, "%8.8s|%c|%ld|%ld|%ld|%d|%ld|%ld|%ld|%ld|%ld|%d|%6.2f|%d|%d|%.2f|%s", pSubgruppe->gruppe, pSubgruppe->knoten_char, pSubgruppe->SCGES, pSubgruppe->LDFPLK, pSubgruppe->LDFPTK,pSubgruppe->anz, pSubgruppe->MELZU, pSubgruppe->MELZU_DIRECT, pSubgruppe->SCULK, pSubgruppe->SCUTK, pSubgruppe->VDZU, pSubgruppe->melzu_voll, pSubgruppe->melzu_reduziert,
                      pSubgruppe->vd_u, pSubgruppe->vd_o, pSubgruppe->vd_mw, diagmel);
        
        if (pSubgruppe->pMelZu) {
            unsigned int i;
            MELZU_DATA *pMelZu = pSubgruppe->pMelZu;
            for (i = 0; i < pAufenthalt->mel_anz; i++, pMelZu++) {
                pos += sprintf(localbuf + pos, "%d|%ld|%ld", pMelZu->nDynMelId, pMelZu->lMelZu, pMelZu->lDynMelDiff);
                if (pos > 2000)
                    break;
            }
        }
    }
    else {
        pos = sprintf(localbuf, "%8.8s|%s|%ld|%ld|%ld|0|%ld|%ld|%ld|%ld|%ld|%ld|%6.2ld|%d|%d|%.2f", pAufenthalt->GRP, pAufenthalt->KNT, pAufenthalt->SCGES, pAufenthalt->LDFPLK, pAufenthalt->LDFPTK, pAufenthalt->MELZU, pAufenthalt->MELZU, pAufenthalt->SCULK, pAufenthalt->SCUTK, pAufenthalt->VDZU, pAufenthalt->MELZU, pAufenthalt->MELZU,
                      0, 0, 0.0);
    }

    
    if (buflen > 0) {
        strncpy (buf, localbuf, buflen);
    }
    return 1;
}

_SCORING_EXPORT int lkf_auf_getLineWithIdent (LKF_AUFENTHALT *pAufenthalt, const char *ident, char *line) {
    
    unsigned int lineIndex;
    
    if (memcmp (ident, "AUF:X0", 6)) {
        if (!memcmp (ident, "INX:", 4)) {
            return lkf_auf_getIntLineWithIdent(pAufenthalt, ident, line);
        }
        return LKFCERROR_INVALIDID;
    }

    switch (ident[6]) {
        case '1':
            return lkf_auf_line_root (pAufenthalt, line);
        case '2':
            lineIndex = (unsigned int) atoi (ident + 8);
            return lkf_auf_line_abt(pAufenthalt, lineIndex, line);
        case '3':
            lineIndex = (unsigned int) atoi (ident + 8);
            return lkf_auf_line_diag(pAufenthalt, lineIndex, line);
        case '4':
            lineIndex = (unsigned int) atoi (ident + 8);
            return lkf_auf_line_mel(pAufenthalt, lineIndex, line);
        case '5':
            return lkf_auf_line_scoring(pAufenthalt, line);
        case '6':
            lineIndex = (unsigned int) atoi (ident + 8);
            return lkf_auf_line_akwarn(pAufenthalt, lineIndex, line);
        case '7':
            lineIndex = (unsigned int) atoi (ident + 8);
            return lkf_auf_line_kommentar(pAufenthalt, lineIndex, line);
        default:
            return LKFCERROR_INVALIDID;
    }
}

_SCORING_EXPORT int lkf_auf_deleteLine (LKF_AUFENTHALT *pAufenthalt, const char *ident) {
    if (memcmp (ident, "AUF:X0", 6)) {
        if (!memcmp (ident, "INX:", 4)) {
            return lkf_auf_deleteIntLine(pAufenthalt, ident);
        }
        return -1;
    }

    return -1;
}

_SCORING_EXPORT unsigned int lkf_recompute_aufenthalt (LKF_AUFENTHALT *pAufenthalt) {
    LKF_CONTEXT *pContext;
    
    pContext = pAufenthalt->pScoringContext;
    
    if (pContext == 0) {
        return 1000;
    }
    
    lkf_sort_auf_abt (pAufenthalt);
    lkf_plaus (pContext, pAufenthalt);
    lkf_scoring(pContext, pAufenthalt);
    return 0;
}

void lkf_auf_add_category (LKF_AUFENTHALT *pAufenthalt, char *code, char *comment, unsigned int maxLength)
{ /* V2025.0 */
    
    LKF_AUFENTHALT_CATEGORY *pCategory;
    LKF_CONTEXT *pContext;
    
    pContext = pAufenthalt->pScoringContext;
    
    if (pAufenthalt->pCategory == 0) {
        pAufenthalt->category_alloc = 1;
        pAufenthalt->pCategory = LKF_CALLOC(pContext, "lkf_auf_add_category", pAufenthalt->category_alloc, sizeof(LKF_AUFENTHALT_CATEGORY));
        if (!pAufenthalt->pCategory) return;
        
        pCategory = pAufenthalt->pCategory;
        pAufenthalt->category_count = 1;
    }
    else {
        unsigned int i;
        pCategory = 0;
        for (i = 0; i < pAufenthalt->category_count; i++) {
            if (!strcmp (pAufenthalt->pCategory[i].code, code)) {
                pCategory = pAufenthalt->pCategory + i;
                if (comment) {
                    strncpy (pCategory->comment, comment, maxLength);
                    pCategory->comment[maxLength] = 0;
                }
                return;
            }
        }
        
        if (!pCategory) {
            if (pAufenthalt->category_alloc == pAufenthalt->category_count) {
                LKF_AUFENTHALT_CATEGORY *pOld = pAufenthalt->pCategory;
                pAufenthalt->category_alloc += 2;
                pAufenthalt->pCategory = LKF_CALLOC(pContext, "lkf_auf_add_category.pCategory", sizeof(LKF_AUFENTHALT_CATEGORY), pAufenthalt->category_alloc);
                if (!pAufenthalt->pCategory) {
                    LKF_FREE (pContext, "lkf_auf_add_category", pOld);
                    return;
                }
                memcpy (pAufenthalt->pCategory, pOld, sizeof(LKF_AUFENTHALT_CATEGORY) * pAufenthalt->category_count);
                LKF_FREE (pContext, "lkf_auf_add_category", pOld);
                
            }
            pCategory = pAufenthalt->pCategory + pAufenthalt->category_count++;
        }        
    }
    strcpy (pCategory->code, code);
    if (comment) {
        strcpy (pCategory->comment, comment);
        pCategory->comment[maxLength] = 0;
    }
    else {
        pCategory->comment[0] = 0;
    }
}
    
_SCORING_EXPORT unsigned int lkf_auf_getCategoryCount (LKF_AUFENTHALT *pAufenthalt) {
    return pAufenthalt->category_count;
}
    
_SCORING_EXPORT int lkf_auf_getCategory (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *pBuf, unsigned int buflen) {
    
    LKF_AUFENTHALT_CATEGORY *pCategory;
    char buf[512];
    unsigned int curbuflen;
    if (!pAufenthalt->pCategory || i >= pAufenthalt->category_count) {
        return -1;
    }
    pCategory = pAufenthalt->pCategory + i;
    
    if (pCategory->comment[0]) {
        sprintf (buf, "%s;%s", pCategory->code, pCategory->comment);
    }
    else {
        strcpy (buf, pCategory->code);
    }
    curbuflen = (unsigned int) strlen(buf);
    if (pBuf && buflen > 0) {
        strncpy (pBuf, buf, buflen);
        if (curbuflen >= buflen) {
            pBuf[buflen-1] = 0;
        }
    }
    return curbuflen;
}

