<?php
// --------------------------------------------------------------------------- //
// Formulaire de requete Sphinx
// --------------------------------------------------------------------------- //
// Fichiers lus en entree : crit2seq.prn et comb2crit.txt
// --------------------------------------------------------------------------- //
if (defined('DEBUG') == false) {
    define( 'DEBUG', 0);
}
if (defined('LOCAL') == false) {
    define( 'LOCAL', 0);
}

if (LOCAL) {
    include_once('../sphinx/api/sphinxapi.php');
    include_once('criteresFonc.php');
    define('SPHINX_HOST', 'localhost');
    define('SPHINX_PORT', 9312);
    $pass = '';
    $conf = file("../etc/conf/sphinx.conf");
    foreach ($conf as $ligne) {
        $param = explode('=', $ligne);
        if (trim($param[0]) == 'sql_pass') {
            $pass = trim($param[1]);
        }
    }
    define('MYSQL_HOST', 'localhost');
    define('MYSQL_USER', 'root');
    define('MYSQL_PASS', $pass);
} else {
    require_once realpath(dirname(__FILE__)).'/sphinxapi.php';
    require_once realpath(dirname(__FILE__)).'/criteresFonc.php';
}

$gDatabaseJO = databaseJO();

// --------------------------------------------------------------------------- //
// databaseJO
// --------------------------------------------------------------------------- //
function databaseJO()
{
    @$db = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, 'jo');
    if (mysqli_connect_error()) {
        println('Ne peut pas se connecter a la base.');
        return;
    }
    $db->query("SET NAMES 'utf8';");
    return $db;
}

// --------------------------------------------------------------------------- //
// println
// --------------------------------------------------------------------------- //
function println($ln = '')
{
    print $ln.'<br/>';
}

// --------------------------------------------------------------------------- //
// debugln
// --------------------------------------------------------------------------- //
if (DEBUG) {
    function debugln($ln = '')
    {
        print $ln.'<br/>';
    }
} else if (LOCAL) {
    function debugln($ln = '')
    {
    }
} else {
    function debugln($ln = '')
    {
        /*
        $fp = fopen(LOG_PATH.'/recherchesDebug.log', 'a');
        fwrite($fp, $ln.'\n');
        fclose($fp);
        */
    }
}

// --------------------------------------------------------------------------- //
// Filtre les caracteres speciaux
// --------------------------------------------------------------------------- //
function filtreCaracteresSpeciaux(&$formR)
{
    foreach ($formR as $label => $valeur) {
        if (empty($valeur) == true) {
            continue;
        }
        $formR[$label] = str_replace('@',  'a', $valeur);
        $formR[$label] = str_replace('\'', ' ', $formR[$label]);
    }
}

// --------------------------------------------------------------------------- //
// Filtre pour le siren
// --------------------------------------------------------------------------- //
function filtreSiret(&$formR, &$criteres, &$sphinx)
{
    if (empty($formR['siret']) == true) {
        return;
    }

    if (strstr($criteres, 'I') != false) {
        if (preg_match('/[0-9]{9}/', $formR['siret'], $arraySiren) > 0) {
            debugln("filtre siren='$arraySiren[0]'");
            $sphinx->SetFilter('siren', $arraySiren);
        } else if (preg_match('/[0-9]{5}/', $formR['siret'], $arrayNic) > 0) {
            debugln("filtre nic='$arrayNic[0]'");
            $sphinx->SetFilter('nic', $arrayNic);
        }
    }
}

// --------------------------------------------------------------------------- //
// Filtre pour les elements de l'adresse
// --------------------------------------------------------------------------- //
function filtreAdresse(&$formR, &$criteres, &$sphinx)
{
	$gDatabaseJO = databaseJO();

    if (empty($formR['cpVille']) == true) {
        return;
    }

    $adressePostale = $formR['cpVille'];
    if (preg_match('/[0-9]{5}/',
                   $adressePostale, $codePostaux) > 0) {
        if (strstr($criteres, 'L') != false) {
            debugln("filtre adr_cp='$codePostaux[0]'");
            $sphinx->SetFilter('adr_cp', $codePostaux);
        } else if (strstr($criteres, 'D') != false) {
            $departement = substr($codePostaux[0], 0, 2);
            if ($departement == 97 ||
                $departement == 98) {
                $departement = substr($codePostaux[0], 0, 3);
            }
            debugln("filtre adr_dep='$departement'");
            $sphinx->SetFilter('adr_dep', array($departement));
        }
        $formR['ville'] = str_replace($codePostaux[0], '',
                                      $adressePostale);
        $dep = intval(substr($codePostaux[0], 0, 2));
        if ($codePostaux[0] == '98000') {
            $formR['departement'] = 99;
            $formR['localite']    = 0;
        } else if ($dep == 97 ||
                   $dep == 98) {
            $formR['departement'] = substr($codePostaux[0], 0, 3);
            $formR['localite']    = substr($codePostaux[0], 3, 2);
        } else {
            $formR['departement'] = substr($codePostaux[0], 0, 2);
            $formR['localite']    = substr($codePostaux[0], 2, 3);
        }
    } else if (preg_match('/[0-9]{3}/',
                          $adressePostale, $departements) > 0 ||
               preg_match('/[0-9]{2}/',
                          $adressePostale, $departements) > 0) {
        if (strstr($criteres, 'D') != false) {
            debugln("filtre adr_dep='$departements[0]'");
            $sphinx->SetFilter('adr_dep', $departements);
        }
        $formR['ville'] = str_replace($departements[0], '',
                                      $adressePostale);
        $formR['departement'] = $departements[0];
    } else {
        $formR['ville'] = $adressePostale;
    }

    // Completion
    if (isset($formR['ville']) == true &&
        isset($formR['localite']) == false) {
        $ville  = strtoupper(trim($formR['ville']));
        if ($ville == 'PARIS') {
            $formR['departement'] = 75;
            return;
        }
        if ($ville == 'LYON') {
            $formR['departement'] = 69;
            return;
        }
        if ($ville == 'MARSEILLE') {
            $formR['departement'] = 13;
            return;
        }
        $requeteDB = "select * from communes where LibCom like '$ville'";
        debugln($requeteDB);
        $resDB = $gDatabaseJO->query($requeteDB);
        if ($resDB->num_rows == 1) {
            $cp = $resDB->fetch_assoc();
            $cp = $cp['Code Postal'];
            $formR['departement'] = substr($cp, 0, 2);
            if ($formR['departement'] == '97' ||
                $formR['departement'] == '98') {
                $formR['departement'] = substr($cp, 0, 3);
                $formR['localite']    = substr($cp, 3, 2);
            } else {
                $formR['localite']    = substr($cp, 2, 3);
            }
            if (DEBUG) {
                print 'Completion: '.$formR['ville'].' '.
                    $formR['departement'].$formR['localite'].'<br/>';
            }
        }
        // TODO:
        // On peut ameliorer avec le departement si plusieurs resultats
        // ou tronquer la ville si aucun resultat
    }
}

// --------------------------------------------------------------------------- //
// Filtre pour le numero de la voie
// --------------------------------------------------------------------------- //
function filtreNumero(&$formR, &$criteres, &$sphinx)
{
    if (empty($formR['numVoie']) == false) {
        if (strstr($criteres, 'N') != false) {
            debugln("filtre adr_num='$formR[numVoie]'");
            $sphinx->SetFilter('adr_num', array($formR['numVoie']));
        }
    }
}

// --------------------------------------------------------------------------- //
// Filtre pour la date de naissance
// --------------------------------------------------------------------------- //
function filtreDateNaiss(&$formR, &$criteres, &$sphinx)
{
    $jj = preg_replace('/[^0-9]/', '', $formR['dirDateNaissJJ']);
    if ($jj < 0 ||
        $jj > 31) {
        echo ('Jour de naissance incorrect !');
    }
    $mm = preg_replace('/[^0-9]/', '', $formR['dirDateNaissMM']);
    if ($mm < 0 ||
        $mm > 12) {
        echo ('Mois de naissance incorrect !');
    }
    $aa = preg_replace('/[^0-9]/', '', $formR['dirDateNaissAAAA']);
    $annee = date('Y') - 18;
    if ($aa < 0 ||
        $aa > $annee) {
        echo ('Année de naissance incorrecte !');
    }

    if (empty($jj) == false && strstr($criteres, 'J') != false) {
        debugln("filtre naiss_jour='$jj'");
        $sphinx->SetFilter('naiss_jour', array($jj));
    }
    if (empty($mm) == false && strstr($criteres, 'M') != false) {
        debugln("filtre naiss_jour='$mm'");
        $sphinx->SetFilter('naiss_mois', array($mm));
    }
    if (empty($aa) == false) {
        if (strstr($criteres, 'A') != false) {
            debugln("filtre naiss_jour='$aa'");
            $sphinx->SetFilter('naiss_annee', array($aa));
        } else if (strstr($criteres, 'R') != false) {
            debugln("filtre naiss_jour='".($aa-5).'-'.($aa+5)."'");
            $sphinx->SetFilterRange('naiss_annee', $aa - 5, $aa + 5);
        }
    }
}

// --------------------------------------------------------------------------- //
// Premiere requete Sphinx
// --------------------------------------------------------------------------- //
// Premiere requete sans la gestion des mots non significatifs
// et avec concatenation de tous les mots de la raison sociale
// --------------------------------------------------------------------------- //
function premiereRequeteSphinx(&$sphinx, &$index, &$formR, &$criteres,
                               &$criteresSphinx, &$form2crit, $sirenValide)
{
    filtreSiret  ($formR, $criteres, $sphinx);
    filtreAdresse($formR, $criteres, $sphinx);
    filtreNumero ($formR, $criteres, $sphinx);
    if ($sirenValide == true) {
        $sphinx->SetFilter('sirenValide', array(1));
    }

    $requete_sphinx = '';
    foreach ($formR as $label => $valeur) {
        if ($label == 'naf' && empty($valeur) == false) {
            $requete_sphinx .= '@ape_etab '.$valeur.' ';
        } else if (empty($valeur) == false &&
            isset($criteresSphinx[$label]) == true &&
            strstr($criteres, $form2crit[$label]) != false) {
            if ($label == 'raisonSociale') {
                $sans_espace = str_replace(' ', '', $valeur);
                if ($sans_espace != $valeur) {
                    if (strstr($valeur, '"') == false) {
                        $valeur = '"'.$valeur.'"';
                    }
                    $valeur = '('.$sans_espace.' | '.$valeur.'~2)';
                } else if (strstr($valeur, '"') == false) {
                    $valeur = '"'.$valeur.'"';
                }
            }
            $requete_sphinx .= $criteresSphinx[$label].' '.$valeur.' ';
        }
    }
    debugln("requete='$requete_sphinx'");
    if (substr($index, 0, 3) == 'ent') {
        $sphinx->
            SetSortMode(SPH_SORT_EXTENDED,
                        'sirenValide DESC, rang DESC, actif DESC, siege DESC');
    } else if (substr($index, 0, 3) == 'dir') {
        $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'actif DESC');
    }

    return $sphinx->Query($requete_sphinx, $index);
}

// --------------------------------------------------------------------------- //
// Requete Sphinx
// --------------------------------------------------------------------------- //
function requeteSphinx(&$sphinx, &$index, &$formR, &$criteres,
                       &$criteresSphinx, &$form2crit, $quorum_actif, $quorum,
                       $sirenValide)
{
    filtreSiret  ($formR, $criteres, $sphinx);
    filtreAdresse($formR, $criteres, $sphinx);
    filtreNumero ($formR, $criteres, $sphinx);
    if ($sirenValide == true) {
        $sphinx->SetFilter('sirenValide', array(1));
    }
    if ($quorum_actif == true) {
        foreach ($quorum as $label => $valeur) {
            if ($valeur > 1 && strstr($formR[$label], '"') == false) {
                $formR[$label] = '"'.$formR[$label].'"/'.($valeur-1);
            }
        }
    }

    $requete_sphinx = '';
    foreach ($formR as $label => $valeur) {
        if ($label == 'naf' && empty($valeur) == false) {
            $requete_sphinx .= '@ape_etab '.$valeur.' ';
        } else if (empty($valeur) == false &&
            isset($criteresSphinx[$label]) == true &&
            strstr($criteres, $form2crit[$label]) != false) {
            $requete_sphinx .= $criteresSphinx[$label].' '.$valeur.' ';
        }
    }
    debugln("requete='$requete_sphinx'");
    if (substr($index, 0, 3) == 'ent') {
        $sphinx->
            SetSortMode(SPH_SORT_EXTENDED,
                        'sirenValide DESC, rang DESC, actif DESC, siege DESC');
    } else if (substr($index, 0, 3) == 'dir') {
        $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'actif DESC');
    }

    return $sphinx->Query($requete_sphinx, $index);
}

// --------------------------------------------------------------------------- //
// Criteres de depart
// --------------------------------------------------------------------------- //
function criteresDeDepart(&$formR, &$form2crit)
{
    $criteres = '';
    foreach ($form2crit as $label => $valeur) {
        if (empty($formR[$label]) == false) {
            if ($valeur == 'I') {  // Dans ce cas on ne garde que le siren
                return 'I         ';
            }
            $criteres .= $valeur;
        } else {
            $criteres .= ' ';
        }
    }
    return $criteres;
}

// --------------------------------------------------------------------------- //
// Affichage du status de Sphinx
// --------------------------------------------------------------------------- //
function afficheStatusSphinx(&$sphinx, &$resSphinx)
{
    if (DEBUG) {
        if ($resSphinx == false) {
            println('Query failed: '.$sphinx->GetLastError().'.');
            return;
        }
        if ($sphinx->GetLastWarning()) {
            println('WARNING: '.$sphinx->GetLastWarning());
        }

        println("Query retrieved $resSphinx[total]".
                " of $resSphinx[total_found] matches in $resSphinx[time] sec.");
        println('Query stats:');
        if (isset   ($resSphinx['words']) &&
            is_array($resSphinx['words'])) {
            foreach ($resSphinx['words'] as $word => $info) {
                println("    '$word' found $info[hits] times".
                        " in $info[docs] documents");
            }
            println('');
        }
    }
}

// --------------------------------------------------------------------------- //
// Affichage des donnees en base
// --------------------------------------------------------------------------- //
function afficheDB(&$resSphinx, &$formR, &$form2crit, $table, &$base2form,
                   $deb, $nbRep)
{
     $gDatabaseJO = databaseJO();

    if (isset($resSphinx['matches']) == false) {
        println('Aucun r&eacute;sultat');
        return;
    }
    if ($formR['type'] == 'ent') {
        $requeteDB = "select *, (siren>200) AS sirenValide";
    } else {
        $requeteDB = "select *";
    }
    $requeteDB .= " from $table where id=".$resSphinx['matches'][0]['id'];
    for ($i = 1; $i + $deb < $resSphinx['total'] && $i < $nbRep; ++$i) {
        $requeteDB .= ' or id='.$resSphinx['matches'][$i]['id'];
    }
    if ($formR['type'] == 'ent') {
        $requeteDB .=
            ' ORDER BY sirenValide DESC, rang DESC, actif DESC, siege DESC';
    } else {
        $requeteDB .= ' ORDER BY actif DESC';
    }
    $requeteDB .= ' limit 0, '.$nbRep;
    debugln("requeteDB='$requeteDB'");
    $resDB = $gDatabaseJO->query($requeteDB);
    $nb_res = $resDB->num_rows;
    for ($i = 0; $i < $nb_res; ++$i) {
        $ligne = $resDB->fetch_assoc();
        println();
        foreach ($base2form as $label => $valeur) {
            if (empty($formR[$valeur]) == false) {
                print "$form2crit[$valeur]=<b>'$ligne[$label]'</b> ";
            } else {
                print "$form2crit[$valeur]='$ligne[$label]' ";
            }
        }
    }
    println();
}

// --------------------------------------------------------------------------- //
// Nombre de mots trouves dans un champ
// --------------------------------------------------------------------------- //
function nombreDeMots(&$res, $champ)
{
    if (isset($res['words']) == false) {
        return 0;
    }

    $champ = preg_replace('/[^A-Za-z]/', ' ', $champ);
    $mot = explode(' ', strtolower($champ));
    $n   = 0;
    $nul = 0;

    foreach ($mot as $m) {
        if (isset($res['words'][$m]) == true) {
            debugln('nombre de mots: '.
                    $m.' => '.$res['words'][$m]['hits']);
            if ($res['words'][$m]['hits'] == 0) {
                ++$nul;
            }
            ++$n;
        }
    }

    if ($nul > 2) {
        return $n - $nul + 1;
    } else {
        return $n;
    }
}

// --------------------------------------------------------------------------- //
// changePass
// --------------------------------------------------------------------------- //
// mode et index doivent etre positionnes a chaque fois
// --------------------------------------------------------------------------- //
function changePass(&$pass, &$mode, &$index, &$quorumActif, &$formR)
{
    switch ($pass) {
    case 1:  // Pass 2 : Phonex
        $pass  = 2;
        $mode  = SPH_MATCH_EXTENDED2;
        $index = 'ent_phx';
        return true;
    case 2:  // Pass 3 : Ispell
        $pass  = 3;
        $mode  = SPH_MATCH_ISPELL;
        $index = 'ent_mns';
        return true;
    case 3:  // Pass 4 : Quorum n-1
        $pass  = 4;
        $mode  = SPH_MATCH_EXTENDED2;
        $index = 'ent_mns';
        $quorumActif = true;
        return true;
    case 4:  // Pass 5 : Quorum n-2
        $pass  = 5;
        foreach ($formR as $label => $valeur) {
            if (preg_match('@.*"/[1-9]+@', $valeur) != false) {
                $n = preg_replace('@.*"/([1-9]+).*@', '$1', $valeur);
                if ($n > 1) {
                    $formR[$label] = str_replace($n, $n - 1, $valeur);
                }
            }
        }
        return true;
    default:
        return false;
    }
}

// --------------------------------------------------------------------------- //
// initSphinx
// --------------------------------------------------------------------------- //
function initSphinx(&$sphinx, $mode, $pass, $deb, $nbRep, $max)
{
    debugln();
    debugln('pass '.$pass);
    debugln();
    $sphinx->SetMatchMode($mode);
    $sphinx->resetFilters();
    $sphinx->SetLimits(intval($deb), intval($nbRep), intval($max));
}

// --------------------------------------------------------------------------- //
// Criteres recherche par dirigeant
// --------------------------------------------------------------------------- //
function criteresDir($c, &$index)
{
    if (substr($c, strlen($c) - 1, 1) == 'p') {
        $c = substr($c, 0, strlen($c) - 1);
        $index = 'dir';
    } else {
        $index = 'dir_phx';
        return $c.'p';
    }
    $tab =
        array('NPAMJDV' => 'NPAM DV',
              'NPAM DV' => 'NPA  DV',
              'NPA  DV' => 'NPR  DV',
              'NPR  DV' => 'NP   DV',
              'NP   DV' => 'NPAMJD ',
              'NPAMJD ' => 'NPAMJ  ',
              'NPAMJ  ' => 'N AMJDV',
              'N AMJDV' => 'N AM DV',
              'N AM DV' => 'N A  DV',
              'N A  DV' => 'N R  DV',
              'N R  DV' => 'N    DV',
              'N    DV' => 'N AMJD ',
              'N AMJD ' => 'N AMJ  ',
              'N AMJ  ' => ' PAMJDV',
              ' PAMJDV' => ' PAM DV',
              ' PAM DV' => ' PA  DV',
              ' PA  DV' => ' PR  DV',
              ' PR  DV' => ' P   DV',
              ' P   DV' => ' PAMJD ',
              ' PAMJD ' => ' PAMJ  ',
              ' PAMJ  ' => ' PAM   ');

    if (isset($tab[$c]) == true) {
        $ret = $tab[$c];
    } else {
        $ret = '';
    }

    return $ret;
}

// --------------------------------------------------------------------------- //
// clientSphinx
// --------------------------------------------------------------------------- //
function clientSphinx(&$formR)
{
    // Formulaire
    $formulaire_vide = true;
    foreach ($formR as $label => $valeur) {
        if ($label != 'type' &&  // Ce champs ne devrait pas etre dans formR
            empty($valeur) == false) {
            $formulaire_vide = false;
            $formR[$label] = trim($valeur);
        }
    }
    if ($formulaire_vide == true) {
        return false;
    }
    if (DEBUG) {
        foreach ($formR as $label => $valeur) {
            println("$label = '$valeur'");
        }
    }

    // Client Sphinx
    $sphinx = new SphinxClient();
    switch($formR['type'])
    {
    	case 'ent':
    		$host = SPHINX_ENT_HOST;
    		$port = SPHINX_ENT_PORT;
    		break;
    	case 'dir':
    		$host = SPHINX_DIR_HOST;
    		$port = SPHINX_DIR_PORT;
    		break;
    	case 'histo':
    		$host = SPHINX_HISTO_HOST;
    		$port = SPHINX_HISTO_PORT;
    		break;
    	case 'act':   	
    		$host = SPHINX_ACT_HOST;
    		$port = SPHINX_ACT_PORT;
    		break;
    }
    $sphinx->SetServer($host, $port);
    $sphinx->SetConnectTimeout(1);
    $sphinx->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
    $sphinx->SetArrayResult(true);

    return $sphinx;
}

// --------------------------------------------------------------------------- //
// compare
// --------------------------------------------------------------------------- //
function compare($a1, $a2)
{
    $a1 = strtoupper($a1);
    $a2 = strtoupper($a2);
    $a1 = str_replace('&', 'ET', $a1);
    $a2 = str_replace('&', 'ET', $a2);
    if (DEBUG) {
        print 'Compare: '.$a1.' avec: '.$a2;
    }
    $l1 = levenshtein($a1, $a2);
    $t1 = explode(' ', $a1);
    $t2 = explode(' ', $a2);
    sort($t1);
    sort($t2);
    $a1 = implode(' ', $t1);
    $a2 = implode(' ', $t2);
    $l2 = levenshtein($a1, $a2);
    $l  = min($l1, $l2);
    $ret = 1 - $l / max(strlen($a1), strlen($a2));
    debugln(' levenshtein: '.$l.' pertinence: '.$ret);

    return $ret;
}

// --------------------------------------------------------------------------- //
// reponse
// --------------------------------------------------------------------------- //
function reponse(&$resSphinx, &$resDB, $criteres, $time, $formR, $form2crit,
                 $deb, $ligneDir = array())
{
    $criteresRet = array();

    foreach ($form2crit as $field => $letter) {
        if (preg_match("/$letter/", $criteres)) {
            if (empty($formR[$field]) == false) {
                $criteresRet[] = strtoupper($formR[$field]);
            }
        }
    }

    $ret['criteres']        = $criteresRet;
    //$ret['nbReponses']      = $resDB->num_rows;
    $ret['nbReponsesTotal'] = $resSphinx['total'];
    $ret['duree']           = $time;

    $pertinence_generale = 100;
    if ($formR['type'] == 'ent') {
        //$pertinence_generale = 100 - 5 * $resSphinx['pass'];;
        $tot = 0;
        $num = 0;
        $poids = array('I' => 10,
                       'T' => 1,
                       'S' => 9,
                       'E' => 8,
                       'P' => 7,
                       'D' => 6,
                       'L' => 4,
                       'V' => 5,
                       'N' => 2,
                       'R' => 3);
        foreach ($form2crit as $field => $letter) {
            if (empty($formR[$field]) == false) {
                $tot += $poids[$letter];
                if (preg_match("/$letter/", $criteres)) {
                    $num += $poids[$letter];
                }
            }
        }
        $pertinence_generale *= $num / $tot;
        $pertinence_generale  = intval($pertinence_generale);
        print 'Pertinence generale: '.$pertinence_generale.'<br/>';
    }
    $decalage = false;
    for ($i = 0, $k = 0; $k < $resDB->num_rows || $decalage == true; ++$i) {
        if ($decalage == false) {
            $ligne = $resDB->fetch_assoc();
            ++$k;
        } else {
            $decalage = false;
        }
        if ($formR['type']=='dir') {
            debugln($ligneDir[$i]['id'].' '.$ligne['id']);
        }
        if ($formR['type']=='dir' && $ligneDir[$i]['id']!=$ligne['id']) {
            for ($j = $i - 1; $j >= 0; --$j) {
                if ($ret['reponses'][$j]['id'] == $ligneDir[$i]['id']) {
                    $ret['reponses'][$i] = $ret['reponses'][$j];
                    $decalage = true;
                    break;
                }
            }
            if ($decalage != true) {
                debugln('erreur '.$ligneDir[$i]['id'].' != '.$ligne['id']);
            }
        } else {
            $ret['reponses'][$i]['id']         = $ligne['id'];
            //if ($formR['type'] == 'dir') {
            //    debugln("$i:$ligne[id]");
            //}
            $pertinence = $pertinence_generale;
            if ($formR['type'] == 'ent') {
                if (empty($formR['raisonSociale']) == false) {
                    $pertinence *= compare($formR['raisonSociale'],
                                           $ligne['raisonSociale']);
                }
                if (empty($formR['voie']) == false) {
                    $pertinence *= compare($formR['voie'],
                                           $ligne['adr_typeVoie'].' '.
                                           $ligne['adr_libVoie']);
                }
                if (empty($formR['ville']) == false) {
                    $pertinence *= compare($formR['ville'],
                                           $ligne['adr_ville']);
                }
            }
            $ret['reponses'][$i]['Pertinence'] = $pertinence;
            $ret['reponses'][$i]['Siret']      = $ligne['siret'];
            $ret['reponses'][$i]['Siren']      = $ligne['siren'];
            $ret['reponses'][$i]['Nic']        = $ligne['nic'];
            $ret['reponses'][$i]['Siege']      = $ligne['siege'];
            $ret['reponses'][$i]['Nom']        = $ligne['raisonSociale'];
            $ret['reponses'][$i]['Nom2']       = '';
            $ret['reponses'][$i]['Sigle']      = $ligne['sigle'];
            $ret['reponses'][$i]['Enseigne']   = $ligne['enseigne'];
            $ret['reponses'][$i]['Adresse']    =
                $ligne['adr_num'].' '.
                $ligne['adr_typeVoie'].' '.
                $ligne['adr_libVoie'];
            $ret['reponses'][$i]['Adresse2']   = $ligne['adr_comp'];
            $ret['reponses'][$i]['CP']         = $ligne['adr_cp'];
            $ret['reponses'][$i]['Ville']      = $ligne['adr_ville'];
            $ret['reponses'][$i]['Tel']        = $ligne['tel'];
            $ret['reponses'][$i]['Fax']        = $ligne['fax'];
            $ret['reponses'][$i]['FJ']         = $ligne['cj'];
          //$ret['reponses'][$i]['FJLib']      = ;
            $ret['reponses'][$i]['Actif']      = $ligne['actif'];
            $ret['reponses'][$i]['NafEtab']    = $ligne['ape_etab'];
          //$ret['reponses'][$i]['NafEtabLib'] = ;
            $ret['reponses'][$i]['NafEnt']     = $ligne['ape_entrep'];
          //$ret['reponses'][$i]['NafEntLib']  = ;
        }
        if ($formR['type']=='dir') {
            // Dirigeant
            $ret['reponses'][$i]['DirRs']        = '';
            $ret['reponses'][$i]['DirNom']       = $ligneDir[$i]['nom'];
            $ret['reponses'][$i]['DirPrenom']    = $ligneDir[$i]['prenom'];
            $ret['reponses'][$i]['DirNomUsage']  = '';
            $ret['reponses'][$i]['DirDateEffet'] = '';
            $ret['reponses'][$i]['DirFonction']  = $ligneDir[$i]['fonction_lib'];
            $ret['reponses'][$i]['DirDepart']    = '';
        } elseif ($formR['type']=='act') {
        	// Actionnaire
        	$ret['reponses'][$i]['ActNomRs'] = $ligneDir[$i]['ActNomRs'];
        	$ret['reponses'][$i]['ActPays'] = $ligneDir[$i]['ActPays'];
        	$ret['reponses'][$i]['ActDateLien'] = $ligneDir[$i]['ActDateLien'];
        	$ret['reponses'][$i]['ActActif']  = $ligneDir[$i]['ActActif'];
        	$ret['reponses'][$i]['ActPmin']  = $ligneDir[$i]['ActPmin'];
        }
    }
    if ($formR['type']=='dir') {
        for (; $i < count($ligneDir); ++$i) {
            debugln($ligneDir[$i]['id'].' ==> '.$i);
            for ($j = $i - 1; $j >= 0; --$j) {
                if ($ret['reponses'][$j]['id'] == $ligneDir[$i]['id']) {
                    $ret['reponses'][$i] = $ret['reponses'][$j];
                    $ret['reponses'][$i]['DirRs']        = '';
                    $ret['reponses'][$i]['DirNom']       = $ligneDir[$i]['nom'];
                    $ret['reponses'][$i]['DirPrenom']    = $ligneDir[$i]['prenom'];
                    $ret['reponses'][$i]['DirNomUsage']  = '';
                    $ret['reponses'][$i]['DirDateEffet'] = '';
                    $ret['reponses'][$i]['DirFonction']  = $ligneDir[$i]['fonction_lib'];
                    $ret['reponses'][$i]['DirDepart']    = '';
                    break;
                }
            }
            if ($j < 0) debugln('erreur '.$ligneDir[$i]['id'].' non trouve');
        }
    } elseif ($formR['type']=='act') {
    	for (; $i < count($ligneDir); ++$i) {
            debugln($ligneDir[$i]['id'].' ==> '.$i);
            for ($j = $i - 1; $j >= 0; --$j) {
                if ($ret['reponses'][$j]['id'] == $ligneDir[$i]['id']) {
                    $ret['reponses'][$i] = $ret['reponses'][$j];
                    $ret['reponses'][$i]['ActNomRs'] = $ligneDir[$i]['ActNomRs'];
                    $ret['reponses'][$i]['ActPays'] = $ligneDir[$i]['ActPays'];
                    $ret['reponses'][$i]['ActDateLien'] = $ligneDir[$i]['ActDateLien'];
                    $ret['reponses'][$i]['ActActif']  = $ligneDir[$i]['ActActif'];
                    $ret['reponses'][$i]['ActPmin']  = $ligneDir[$i]['ActPmin'];
                    break;
                }
            }
            if ($j < 0) debugln('erreur '.$ligneDir[$i]['id'].' non trouve');
        }
    }
    if ($formR['type'] == 'ent') {
        $ret['pass'] = $resSphinx['pass'];
    }
    $ret['nbReponses'] = count($ret['reponses']);
    if (DEBUG) {
        print '<pre>';
        print_r($ret);
        print '</pre>';
    }
    return $ret;
}

// --------------------------------------------------------------------------- //
// Recherche par dirigeant
// --------------------------------------------------------------------------- //
function rechercheDir(&$formR, $deb, $nbRep, $max)
{
    $gDatabaseJO = databaseJO();

    // Duree totale
    $total_time = 0;

    $sphinx = clientSphinx($formR);
    if ($sphinx == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'erreur'          => 'Formulaire vide');
    }

    $criteresSphinx = array('nom'    => '@nom',
                            'prenom' => '@prenom',
                            'ville'  => '@naissance_lieu');

    $form2crit = array('nom'              => 'N',
                       'prenom'           => 'P',
                       'dirDateNaissAAAA' => 'A',
                       'dirDateNaissMM'   => 'M',
                       'dirDateNaissJJ'   => 'J',
                       'departement'      => 'D',
                       'ville'            => 'V');

    $index = 'dir';
    $mode  = SPH_MATCH_EXTENDED2;
    $pass  = 0;
    $criteres = 'NPAMJDV';
    initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);

    while (empty($criteres) == false) {
        debugln("criteres: $criteres");
        filtreDateNaiss($formR, $criteres, $sphinx);
        filtreAdresse($formR, $criteres, $sphinx);
        $requete_sphinx = '';
        foreach ($formR as $label => $valeur) {
            if (empty($valeur) == false &&
                isset($criteresSphinx[$label]) == true &&
                strstr($criteres, $form2crit[$label]) != false) {
                if ($label == 'prenom') {
                    $requete_sphinx .= $criteresSphinx[$label].
                        ' "'.$valeur.'"/1 ';
                } else {
                    $requete_sphinx .= $criteresSphinx[$label].' '.$valeur.' ';
                }
            }
        }
        debugln("requete='$requete_sphinx'");
        $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'actif DESC');
        $resSphinx = $sphinx->Query($requete_sphinx, $index);
        if ($resSphinx != false) {
            $total_time += $resSphinx['time'];
        }
        if ($resSphinx != false && $resSphinx['total'] > 0) {
            break;
        }

        $criteres = criteresDir($criteres, $index);
        $sphinx->resetFilters();
    }

    afficheStatusSphinx($sphinx, $resSphinx);
    if ($resSphinx == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'erreur'          => $sphinx->GetLastError(),
                     'criteres'        => $criteres);
    }
    if ($resSphinx['total'] == 0) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'criteres'        => $criteres);
    }

    if (DEBUG) {
        $base2form = array('adr_dep'        => 'departement',
                           'nom'            => 'nom',
                           'prenom'         => 'prenom',
                           'naissance_nom'  => 'nom',
                           'naissance_date' => 'dirDateNaissAAAA',
                           'naissance_lieu' => 'ville');
        afficheDB($resSphinx, $formR, $form2crit, 'dirigeants', $base2form,
                  $deb, $nbRep);
    }

    // Recherche des sieges
    if ($gDatabaseJO == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => $resSphinx['total'],
                     'duree'           => $total_time,
                     'erreur'          => 'Base inaccessible');
    }

    if (isset($resSphinx['matches']) == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => $resSphinx['total'],
                     'duree'           => $total_time,
                     'erreur'          => 'Aucun r&eacute;sultat');
    }

    $requeteDB = 'SELECT d.id as iddirigeant, e.id, e.raisonSociale, CONCAT(e.siren, e.nic) AS siret, e.siren, e.nic, e.siege, e.raisonSociale,
     	e.sigle, e.enseigne,  e.adr_num, e.adr_typeVoie, e.adr_libVoie, e.adr_comp, e.adr_cp, e.adr_ville, e.tel, 
        e.fax, e.cj, e.actif, e.ape_etab, ape_entrep, d.nom, d.prenom, l.libelle AS fonction_lib  from dirigeants d, etablissements e, bodacc_fonctions l WHERE d.id IN (';
    foreach($resSphinx['matches'] as $elements)  {
    	$requeteDB .= $elements['id'];
    	if($i+1 < count($resSphinx['matches']))
    	$requeteDB .= ', ';
    	$i++;
    }
    $requeteDB.= ' ) AND d.siren=e.siren and d.fonction_code=l.codeFct AND e.siege=1 GROUP BY d.siren, d.id ORDER BY e.rang DESC, e.actif DESC, e.siege DESC, e.id ASC';
    $resDB = $gDatabaseJO->query($requeteDB);

    return reponse($resSphinx, $resDB, $criteres, $total_time, $formR,
                   $form2crit, $deb, $ligneDir);
}

// --------------------------------------------------------------------------- //
// Recherche Histo
// --------------------------------------------------------------------------- //
function rechercheHisto($formR, $deb, $nbRep, $max)
{
	$gDatabaseJO = databaseJO();
	
	$sphinx = clientSphinx($formR);
	
	$index = 'histo';
	$mode  = 'SPH_MATCH_EXTENDED';
	$pass  = 0;
	initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
	if (!empty($formR['annee1']))
		$sphinx->SetFilter('annee1', array(0=>$formR['annee1']));	
	
	$sphinx->SetRankingMode ( SPH_RANK_PROXIMITY_BM25 );
	
	$sphinxreturn = $sphinx->Query($formR['recherche'], $index);
	
	$gDatabaseJO->select_db('histobodacc');
	
	foreach ( $sphinxreturn['matches'] as $doc => $docinfo ) 
	{
		$requette = "SELECT Histo as Loc, id, nomFichier, annee1, bod, texte FROM bodacc_cor WHERE id=$doc";
		$req = $gDatabaseJO->query($requette);		
		$ligne = $req->fetch_assoc();
		$etab = $ligne[0];
		$tabRet[] = array(	
			'Localisation'	=> $etab['Loc'],
			'id'			=> $doc,
			'Pertinence'	=> $docinfo['weight'],
			'Fichier'		=> $etab['nomFichier'],
			'Annee'			=> $etab['annee1'],
			'Code'			=> $etab['bod'],
			'Texte'			=> $etab['texte'],
		);
	}
	
	return array(	
		'results'	=> $tabRet,
		'nbRet'		=> $sphinxreturn['total'],
		'nbTot'		=> $sphinxreturn['total_found'],
		'duration'	=> $sphinxreturn['time'],
		'words'		=> $sphinxreturn['words'],
	);
}

// --------------------------------------------------------------------------- //
// Recherche par actionnaire
// --------------------------------------------------------------------------- //

function constructRequete($formR, $sphinxCriteres)
{
	foreach($sphinxCriteres as $name => $critere) {
		if ($name == 'Req') {
			$requete .= $formR[$critere];
		}
		if ($name[0] == '@') {
			if(!empty($formR[$critere]))
			$parametres .= ' '.$name.' '.$formR[$critere];
		}
	}
	echo $sphinxRequete = '"'.$requete.'" '.$parametres;
	return ($sphinxRequete);
}

function rechercheAct($formR, $deb, $nbRep, $max)
{
    $gDatabaseJO = databaseJO();
    
    $sphinx = clientSphinx($formR);
    $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'actif DESC');
    
    $index = 'act';
    $mode  = 'SPH_MATCH_EXTENDED2';
    $pass  = 0;
    initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
    
    $Criteres = array('Siren2'  => 'siren',
                      'Req'     => 'actNomRS',
                      '@Pays'   => 'pays',
                      'PminNum' => 'pctMax'
    );
    $form2crit = array('actNomRS' => 'N',
                       'pays'     => 'P',
                       'pctMax'   => 'M'
    );
    
    $Requete = constructRequete($formR, $Criteres);
    if(!empty($formR['pctMin']))
        $sphinx->SetFilterRange('PminNum', $formR['pctMin'], 99);
    if(!empty($formR['pctMax']))
        $sphinx->SetFilterRange('PminNum', $formR['pctMin'], 99);
    if(!empty($formR['pctMin']) and !empty($formR['pctMax']))
        $sphinx->SetFilterRange('PminNum', $formR['pctMix'], $formR['pctMax']);
        

    $sphinxreturn = $sphinx->Query($Requete, $index);
    $criteres     = 'NPM';
    $requette     = 'SELECT l.id AS lienId, l.actif AS lienActif, l.source, l.Pmin, l.PpPm, l.id2, '.
    				'l.Siren2, l.RaisonSociale, l.Pays, '.
					'IF(l.dateUpdate>IF(l.dateInsert>l.dateLien,l.dateInsert,l.dateLien),l.dateUpdate,IF(l.dateInsert>l.dateLien,l.dateInsert,l.dateLien)) AS dateLien, '.
    				'e.id, CONCAT(siren,nic) AS siret, siren, nic, siege, e.raisonSociale, sigle, '.
    				'enseigne, adr_num, adr_typeVoie, adr_libVoie, adr_comp, adr_cp, adr_ville, '.
    				'tel, fax, cj, e.actif, ape_etab, ape_entrep '.
					'FROM liens l, etablissements e '.
					'WHERE l.Siren1=e.siren AND e.siege=1 AND (';
	$i = 0;
	foreach($sphinxreturn['matches'] as $id => $element) {
            if($i == 0)
                $requette.= ' l.id='.$element['id'];
            else
                $requette.= ' OR l.id='.$element['id'];
        $i++;
	}
	$requette.= ') GROUP BY l.Siren1, l.id ORDER BY e.rang DESC, e.actif DESC, e.siege DESC, e.id ASC';
	$req       = $gDatabaseJO->query($requette);
	
	$requette2 ='SELECT id, CONCAT(siren,nic) AS siret, siren, nic, siege, '.
				'raisonSociale, sigle, enseigne, adr_num, adr_typeVoie, adr_libVoie, '.
				'adr_comp, adr_cp, adr_ville, tel, fax, cj, actif, ape_etab, '.
				'ape_entrep FROM etablissements WHERE ';
	
	$ligneAct = array();
	for($i = 0; $i < $req->num_rows; $i++) {
		$ligne = $req->fetch_assoc();
		$ligneAct[$i] = array(	'id'		=> $ligne['id'],
								'ActNomRs'	=> $ligne['RaisonSociale'],
								'ActPays'	=> $ligne['Pays'],
								'ActDateLien'=>$ligne['dateLien'],
								'ActActif'	=> $ligne['actif'],
								'ActPmin'	=> $ligne['Pmin'],
							 );
		if($i == 0)	$requette2.= ' id='.$ligne['id'];
		else		$requette2.= ' OR id='.$ligne['id'];
	}
	$requette2.= ' ORDER BY rang DESC, actif DESC, siege DESC, id ASC';
	
	$req        = $gDatabaseJO->query($requette2);
   
	return reponse($sphinxreturn, $req, $criteres, $sphinxreturn['time'], $formR, $form2crit, $deb, $ligneAct);
}

// --------------------------------------------------------------------------- //
// Recherche entreprise
// --------------------------------------------------------------------------- //
function rechercheEnt(&$formR, $deb, $nbRep, $max, $sirenValide = false)
{
    $gDatabaseJO = databaseJO();

    // Duree totale
    $total_time = 0;

    $sphinx = clientSphinx($formR);
    if ($sphinx == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'erreur'          => 'Formulaire vide');
    }

    $criteresSphinx = array(
                          //'siret'         => '@siren',
                            'raisonSociale' => '@nom',
                          //'numVoie'       => '@adr_num',
                          //'voie'          => '@(adr_typeVoie,adresse)',
                            'voie'          => '@adresse',
                          //'cpVille'       => '@(adr_dep,adr_cp,ville)',
                            'ville'         => '@ville',
                            'telFax'        => '@(tel,fax)',
                            'naf'           => '@ape_etab');

    $form2crit = array('siret'         => 'I',
                       'telFax'        => 'T',
                       'raisonSociale' => 'S',
                       'enseigne'      => 'E',
                       'prenom'        => 'P',
                       'departement'   => 'D',
                       'localite'      => 'L',
                       'ville'         => 'V',
                       'numVoie'       => 'N',
                       'voie'          => 'R');

    filtreCaracteresSpeciaux($formR);

    // Quorum
    $quorum_actif = false;
    $quorum = array();

    // Premiere requete sans la gestion des mots non significatifs
    // et avec concatenation de tous les mots de la raison sociale
    $index = 'ent';
    $mode  = SPH_MATCH_EXTENDED2;
    $pass  = 0;
    $criteres = 'ITSEPDLVNR';
    initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
    $resSphinx = premiereRequeteSphinx($sphinx, $index, $formR, $criteres,
                                       $criteresSphinx, $form2crit,
                                       $sirenValide);
    afficheStatusSphinx($sphinx, $resSphinx);
    if ($resSphinx == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'erreur'          => $sphinx->GetLastError(),
                     'pass'            => $pass,
                     'criteres'        => $criteres);
    }
    $total_time += $resSphinx['time'];
    if ($resSphinx['total'] == 0) {
        debugln('Sans la gestion des mots non significatifs');
        debugln();
        $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                   $criteresSphinx, $form2crit,
                                   false, $quorum, $sirenValide);
        afficheStatusSphinx($sphinx, $resSphinx);
        if ($resSphinx == false) {
            return array('nbReponses'      => 0,
                         'nbReponsesTotal' => 0,
                         'duree'           => $total_time,
                         'erreur'          => $sphinx->GetLastError(),
                         'pass'            => $pass,
                         'criteres'        => $criteres);
        }
        $total_time += $resSphinx['time'];
    }
    if ($resSphinx['total'] == 0 && isset($formR['departement']) == true) {
        debugln('Sans la gestion des mots non significatifs'.
                ' et sans la localité');
        debugln();
        $criteres = 'ITSEPD VNR';
        $sphinx->resetFilters();
        $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                   $criteresSphinx, $form2crit,
                                   false, $quorum, $sirenValide);
        afficheStatusSphinx($sphinx, $resSphinx);
        if ($resSphinx == false) {
            return array('nbReponses'      => 0,
                         'nbReponsesTotal' => 0,
                         'duree'           => $total_time,
                         'erreur'          => $sphinx->GetLastError(),
                         'pass'            => $pass,
                         'criteres'        => $criteres);
        }
        $total_time += $resSphinx['time'];
        $criteres = 'ITSEPDLVNR';
    }
    $total_premiere_requete = $resSphinx['total'];
    if ($total_premiere_requete == 0 ||
        $total_premiere_requete > 500) {  // "huit a huit" donne 414
        $index = 'ent_mns';

        // Requete sans les mots non significatifs
        // pour connaitre le nombre de mots trouves pour chaque champ alpha
        debugln('Avec la gestion des mots non significatifs'.
                ' et avec quorum si l\'adresse est complete');
        $raisonSociale = $formR['raisonSociale'];
        if ((empty($formR['ville']) == false ||
             empty($formR['departement']) == false) &&
            empty($formR['numVoie']) == false &&
            empty($formR['voie']) == false) {
            $quorum = array('raisonSociale' => 2);
            $quorum_actif = true;
        }
        $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                   $criteresSphinx, $form2crit,
                                   $quorum_actif, $quorum, $sirenValide);
        afficheStatusSphinx($sphinx, $resSphinx);
        if ($resSphinx == false) {
            return array('nbReponses'      => 0,
                         'nbReponsesTotal' => 0,
                         'duree'           => $total_time,
                         'erreur'          => $sphinx->GetLastError(),
                         'pass'            => $pass,
                         'criteres'        => $criteres);
        }
        $total_time += $resSphinx['time'];
        $quorum_actif = false;
        $quorum = array();
        $formR['raisonSociale'] = $raisonSociale;
        if ($resSphinx['total'] == 0) {
            $pass = 1;
            $criteres = 'ITSEPDLVNR';
            initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
            // Nombre de mots pour le quorum
            if (isset($formR['raisonSociale']) == true) {
                $quorum['raisonSociale'] = nombreDeMots($resSphinx,
                                                        $formR['raisonSociale']);
            }
            if (isset($formR['voie']) == true) {
                $quorum['voie']          = nombreDeMots($resSphinx,
                                                        $formR['voie']);
            }
            if (isset($formR['ville']) == true) {
                $quorum['ville']         = nombreDeMots($resSphinx,
                                                        $formR['ville']);
            }
        }
    }

    while ($pass > 0) {
        // Requete Sphinx
        $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                   $criteresSphinx, $form2crit,
                                   $quorum_actif, $quorum, $sirenValide);
        afficheStatusSphinx($sphinx, $resSphinx);
        if ($resSphinx == false) {
            return array('nbReponses'      => 0,
                         'nbReponsesTotal' => 0,
                         'duree'           => $total_time,
                         'erreur'          => $sphinx->GetLastError(),
                         'pass'            => $pass,
                         'criteres'        => $criteres);
        }
        $total_time += $resSphinx['time'];
        if ($resSphinx['total'] > 0 &&
            ($total_premiere_requete == 0 ||
             $total_premiere_requete >= $resSphinx['total'])) {
            break;
        }

        if (isset($sequence) == false) {
            // Criteres de depart
            $criteres = criteresDeDepart($formR, $form2crit);
            debugln("criteres de depart='$criteres'");

            // Sequence
            $sequence = nouvelleSequence($criteres);
            if ($sequence == array()) {
                debugln('fin des sequences');
                if (changePass($pass, $mode, $index,
                               $quorum_actif, $formR) == true) {
                    $criteres = 'ITSEPDLVNR';
                    initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
                    $sequencePos = 0;
                    continue;
                } else {
                    break;
                }
            }
            $sequencePos = 0;
            if (DEBUG) {
                print "sequence='";
                foreach ($sequence as $valeur) {
                    print $valeur.' ';
                }
                println("'");
            }

            // Pour les nouveaux criteres
            if (LOCAL) {
                $comb2crit = file('comb2crit.txt');
            } else {
                $comb2crit = file(realpath(dirname(__FILE__)).'/comb2crit.txt');
            }
        }

        // Combinaison
        $combinaison = nouvelleCombinaison($sequence, $sequencePos,
                                           $pass, $index, $mode);
        if ($combinaison == '') {
            debugln('fin des combinaisons');
            if (changePass($pass, $mode, $index,
                           $quorum_actif, $formR) == true) {
                $criteres = 'ITSEPDLVNR';
                initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
                $sequencePos = 0;
                continue;
            } else {
                break;
            }
        }
        debugln("combinaison='$combinaison'");
        if (strlen($combinaison) == 3) {
            $combinaison = substr($combinaison, 0, 2);
        }

        // Nouveaux criteres
        $criteres = nouveauxCriteres($comb2crit, $combinaison);
        if ($criteres == '') {
            debugln("combinaison inconnue: '$combinaison'");
            break;
        }
        debugln("nouveau criteres='$criteres'");

        $sphinx->SetMatchMode($mode);
        $sphinx->resetFilters();
    }
    $resSphinx['pass'] = $pass;

    // Reprise de la premiere requete si elle etait meilleure
    if ($pass > 0 &&
        $total_premiere_requete > 0 &&
        $total_premiere_requete < $resSphinx['total']) {
        $index = 'ent';
        $mode  = SPH_MATCH_EXTENDED2;
        $pass  = 0;
        $criteres = 'ITSEPDLVNR';
        initSphinx($sphinx, $mode, $pass, $deb, $nbRep, $max);
        $resSphinx = premiereRequeteSphinx($sphinx, $index, $formR, $criteres,
                                           $criteresSphinx, $form2crit,
                                           $sirenValide);
        $total_time += $resSphinx['time'];
        // Sans la gestion des mots non significatifs
        if ($resSphinx['total'] == 0) {
            $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                       $criteresSphinx, $form2crit,
                                       false, $quorum, $sirenValide);
            $total_time += $resSphinx['time'];
        }
        // Sans la gestion des mots non significatifs et sans la localité
        if ($resSphinx['total'] == 0 && isset($formR['departement']) == true) {
            $criteres = 'ITSEPD VNR';
            $sphinx->resetFilters();
            $resSphinx = requeteSphinx($sphinx, $index, $formR, $criteres,
                                       $criteresSphinx, $form2crit,
                                       false, $quorum, $sirenValide);
            $total_time += $resSphinx['time'];
        }
        $resSphinx['pass'] = $pass;
    }

    if ($resSphinx['total'] == 0) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => $total_time,
                     'pass'            => $pass,
                     'criteres'        => $criteres);
    }

    if (DEBUG) {
        $base2form = array('adr_dep'       => 'departement',
                           'adr_cp'        => 'localite',
                           'adr_num'       => 'numVoie',
                           'adr_libVoie'   => 'voie',
                           'adr_comp'      => 'voie',
                           'adr_ville'     => 'ville',
                           'raisonSociale' => 'raisonSociale',
                           'enseigne'      => 'raisonSociale',
                           'sigle'         => 'raisonSociale',
                           'identite_pre'  => 'raisonSociale');
        afficheDB($resSphinx, $formR, $form2crit, 'etablissements', $base2form,
                  $deb, $nbRep);
    }

    // Reponse
    if ($gDatabaseJO == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => $resSphinx['total'],
                     'duree'           => $total_time,
                     'erreur'          => 'Base inaccessible');
    }
    if (isset($resSphinx['matches']) == false) {
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => $resSphinx['total'],
                     'duree'           => $total_time,
                     'erreur'          => 'Aucun r&eacute;sultat');
    }
    $requeteDB = 'select id, CONCAT(siren,nic) AS siret, siren, nic, siege, '.
        'raisonSociale, sigle, enseigne, adr_num, adr_typeVoie, adr_libVoie, '.
        'adr_comp, adr_cp, adr_ville, tel, fax, cj, actif, ape_etab, '.
        'ape_entrep, (siren>200) AS sirenValide'.
        ' from etablissements where id='.$resSphinx['matches'][0]['id'];
    for ($i = 1; $i + $deb < $resSphinx['total'] && $i < $nbRep; ++$i) {
        $requeteDB .= ' or id='.$resSphinx['matches'][$i]['id'];
    }
    $requeteDB .=
        ' ORDER BY sirenValide DESC, rang DESC, actif DESC, siege DESC';

    debugln();
    debugln("requeteDB='$requeteDB'");
    $resDB = $gDatabaseJO->query($requeteDB);

    return reponse($resSphinx, $resDB, $criteres, $total_time, $formR,
                   $form2crit, $deb);
}

// --------------------------------------------------------------------------- //
// sommeDeControle
// --------------------------------------------------------------------------- //
function sommeDeControle($sn)
{
    $s = 0;
    $n = strlen($sn);
    for ($i = 0; $i < $n; ++$i) {
        if ($i & 1) {
            $t = substr($sn, $n - $i - 1, 1) << 1;
            $s += ($t > 9)? $t - 9 : $t;
        } else {
            $s += substr($sn, $n - $i - 1, 1);
        }
    }

    return $s % 10;
}

// --------------------------------------------------------------------------- //
// Verification du siret
// --------------------------------------------------------------------------- //
function verificationDuSiret($siret)
{
    if (strlen($siret) == 14) {
        $sn = substr($siret, 0, 9);
        $st = $siret;
    } else if (strlen($siret) == 9) {
        $sn = $siret;
        $st = 0;
    } else {
        // TODO: message d'erreur et/ou correction
        return false;
    }
    // Verification du siren
    $s = sommeDeControle($sn);
    if ($s != 0) {
        // Correction du chiffre de controle
        $sr = (substr($sn, 8, 1) - $s + 10) % 10;
        $liste = array(substr($sn, 0, 8).$sr);
        // Transpositions
        for ($i = 0; $i < 8; ++$i) {
            $n1 = substr($sn, $i, 1);
            $n2 = substr($sn, $i + 1, 1);
            if ($n1 == $n2) {
                continue;
            }
            $p = '';
            if ($i > 0) {
                $p .= substr($sn, 0, $i);
            }
            $p .= $n2;
            if ($i < 7) {
                $p .= $n1;
            }
            if ($i < 6) {
                $p .= substr($sn, $i + 2, 6 - $i);
            }
            if ($i & 1) {
                if ($i < 7) {
                    if ($n1 >= 5) { $n1 -= 9; }
                    if ($n2 >= 5) { $n2 -= 9; }
                } else {
                    $n1 = ($n1 >= 5) ? ($n1 << 1) - 9 : ($n1 << 1);
                    $n2 = ($n2 >= 5) ? ($n2 << 1) - 9 : ($n2 << 1);
                }
                $p .= ($sr + $n1 - $n2 + 10) % 10;
            } else {
                if ($n2 >= 5) { $n2 -= 9; }
                if ($n1 >= 5) { $n1 -= 9; }
                $p .= ($sr + $n2 - $n1 + 10) % 10;
            }
            $liste[] = $p;
        }
        // Substitutions
        for ($i = 0; $i < 8; ++$i) {
            $n = substr($sn, $i, 1);
            for ($j = 0; $j < 10; ++$j) {
                if ($j == $n) {
                    continue;
                }
                $p = '';
                if ($i > 0) {
                    $p .= substr($sn, 0, $i);
                }
                $p .= $j;
                if ($i < 7) {
                    $p .= substr($sn, $i + 1, 7 - $i);
                }
                if ($i & 1) {
                    $n1 = ($n << 1); if ($n1 > 9) { $n1 -= 9; }
                    $n2 = ($j << 1); if ($n2 > 9) { $n2 -= 9; }
                    $p .= ($sr + $n1 - $n2 + 10) % 10;
                } else {
                    $p .= ($sr + $n - $j + 10) % 10;
                }
                $liste[] = $p;
            }
        }
        return $liste;
    }
    if ($st == 0) {
        return false;
    }
    // Verification du siret
    if (sommeDeControle($st) != 0) {
        return array($sn);
    }
    return false;
}

// --------------------------------------------------------------------------- //
// Recherche
// --------------------------------------------------------------------------- //
function recherche(&$formR, $deb = 0, $nbRep = 20, $max = 1000)
{
    if        ($formR['type'] == 'ent') {
        return rechercheEnt($formR, $deb, $nbRep, $max);
    } else if ($formR['type'] == 'dir') {
        return rechercheDir($formR, $deb, $nbRep, $max);
     } else if ($formR['type'] == 'act') {
        return rechercheAct($formR, $deb, $nbRep, $max);
    } else {
        debugln('Type de recherche inconnu');
        return array('nbReponses'      => 0,
                     'nbReponsesTotal' => 0,
                     'duree'           => 0,
                     'erreur'          => 'Type de recherche inconnu');
    }
}
 ?>