static char *SccsId = "@(#)recog.c 4.3 (TU-Delft) 11/24/92";
/**********************************************************

Name/Version      : space/4.3

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : A.J. van Genderen
		  : N.P. van der Meijs
Creation date     : 15-Mar-1988
Modified by       :
Modification date :


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1988. All rights reserved.
**********************************************************/
#include <stdio.h>
#include "include/config.h"
#include "include/type.h"
#include "aux/aux.h"
#include "extract/define.h"
#include "extract/extern.h"

/* local operations */
private void    printColor ();
private void    printElems ();

elemDef_t ** recognizeElements (sColor, eColor, oeColor)
mask_t sColor;
mask_t eColor;
mask_t oeColor;
{
    register mask_t key;
    register int recog_cnt = 0;

    static   elemDef_t  * elemList[100];
    register elemDef_t ** el;

    int last_id;

    key = sColor & sBitmask;

    if (eColor > 0)
        key += (eColor * (sBitmask + 1)) & eBitmask;

    if (oeColor > 0)
        key += (oeColor * (sBitmask + eBitmask + 1)) & oeBitmask;

    /* if there are no extra conditions to test,
     * either because layCTab == NULL or there are no
     * potential elements for this key, return immediately.
     */

    if (layCTab == NULL || *keyTab[key] == NULL) {

	if (optPrintRecog) {
	    printColor (sColor, eColor, oeColor);
	    printElems (keyTab[key]);
	}

	return (keyTab[key]);
    }

    if (optPrintRecog) {
	printColor (sColor, eColor, oeColor);
    }

    /* If we come here,
     * we know some potential elements for this key,
     * and filter the actual elements out with elemPresent.
     *
     * Idea: we can maintain two keyTabs, in such a way
     * that they individually only use a SUBSET of the
     * keys, but together they use ALL keys.
     * Identifying wich elements are actually present
     * can then be done by taking a crossection of both
     * lists of candidate elements.
     * This crossection can easily be taken since the
     * element lists are sorted.
     */

    last_id = -1;

    recog_cnt = 0;
    for (el = keyTab[key]; *el; el++) {

	if ((*el) -> cond_cnt == 0 ||
	    ((*el) -> id != last_id
	     && elemPresent (*el, sColor, eColor, oeColor))) {

	     /* do not duplicate elements with same id,
	      * this is easy since they are succeeding 
	      * members in el.
	      */

	    elemList[recog_cnt++] = *el;
	    last_id = (*el) -> id;
	    ASSERT (recog_cnt < 100);
	}
    }

    /* Terminate the list of recognized elements with a zero */

    elemList[recog_cnt] = NULL;

    if (optPrintRecog) {
	printElems (elemList);
    }

    return (elemList);
}


int elemPresent (el, sColor, eColor, oeColor)
elemDef_t * el;
mask_t sColor;
mask_t eColor;
mask_t oeColor;
{
    register int cond;
    register int cond_cnt;
    register mask_t color;
    register mask_t testColor;

    cond = el -> cond;
    cond_cnt = el -> cond_cnt;

    for ( ; cond_cnt-- > 0; cond++) {

	switch (layCTab[cond].occurrence) {
	    case SURFACE:
		if (sColor < 0) {
		    return (0);
		}
		color = sColor;
		break;
	    case EDGE:
		if (eColor < 0) {
		    return (0);
		}
		color = eColor;
		break;
	    case OTHEREDGE:
		if (oeColor < 0) {
		    return (0);
		}
		color = oeColor;
		break;
	}

	testColor = masktable[ layCTab[cond].mask ].color;

        if (color & testColor) {
	    if (! layCTab[cond].present)
		return (0);
	}
	else {
	    if (layCTab[cond].present)
		return (0);
	}
    }

    return (1);  /* element is present */
}

private void printColor (sColor, eColor, oeColor)
mask_t sColor;
mask_t eColor;
mask_t oeColor;
{
    int i;

    message ("\n");

    message ("sColor: ");
    if (sColor < 0) message ("%d", sColor);
    else message ("%o", sColor);
    message (" eColor: ");
    if (eColor < 0) message ("%d", eColor);
    else message ("%o", eColor);
    message (" oeColor: ");
    if (oeColor < 0) message ("%d", oeColor);
    else message ("%o", oeColor);
    message ("\n");

    if (sColor > 0) {
	for (i = 0; i < nrOfMasks; i++) {
	     if (masktable[i].color & sColor) {
		 message ("%s ", masktable[i].name);
	     }
	}
    }

    if (eColor > 0) {
	for (i = 0; i < nrOfMasks; i++) {
	     if (masktable[i].color & eColor) {
		 message ("-%s ", masktable[i].name);
	     }
	}
    }

    if (oeColor > 0) {
	for (i = 0; i < nrOfMasks; i++) {
	     if (masktable[i].color & oeColor) {
		 message ("=%s ", masktable[i].name);
	     }
	}
    }

    message ("\n");
}

private void printElems (el)
elemDef_t ** el;
{
    message ("Elements:");
    while (*el)
	message (" %s", (*el++) -> name);
    message ("\n");
}
