/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: negot.c,v $
 * Revision 2.7  1993/07/06  15:13:47  lotos
 * fix control by konfig.negotiation
 *
 * Revision 2.6  1993/02/22  16:14:23  lotos
 * buf fixing
 *
 * Revision 2.5  1993/01/18  18:25:53  lotos
 * distribution issues
 *
 * Revision 2.4  1993/01/12  14:27:53  lotos
 * fix minor bug in value negotiation with eval
 *
 * Revision 2.3  1992/11/25  15:00:25  lotos
 * adapt type of EVAL functions to match the new data formats
 *
 * Revision 2.2  1992/11/17  17:27:06  lotos
 * var -> rav
 * success -> xto
 * distinguish kdatum / udatum
 *
 * Revision 2.1  1992/10/20  17:49:56  lotos
 * new KT evaluation algorithm
 * new Lbeta interface
 * cleaning, code optimization, space saving, bugs, ...
 *
 * Revision 1.6  1992/09/02  17:38:31  lotos
 * full remake to revise defauls & evals
 *
 * Revision 1.5  1992/03/05  17:36:54  lotos
 * just a few more bugs went to the hell
 *
 * Revision 1.4  92/02/29  13:25:59  lotos
 * miscellaneous bug fixing
 *
 * Revision 1.3  92/02/12  18:47:41  lotos
 * ni idea, era una version que andaba por ahi ...
 *
 * Revision 1.2  92/01/15  12:40:59  lotos
 * a bug in frames
 * change success and values
 *
 * Revision 1.1  92/01/14  19:24:59  lotos
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: negot.c,v 2.7 1993/07/06 15:13:47 lotos Exp $";
#endif

#include "swbus.h"
/* LINTLIBRARY */

   /*************************************************/

PRIVATE boolean def_negot   ();
PRIVATE boolean eval_negot  ();
PRIVATE boolean predok ();

PRIVATE offert o_neg = NULL;

   /*************************************************/

PUBLIC  boolean
  ad_ok (o)
offert o;

{
  boolean flag_neg = FALSE;
  boolean def_flag = FALSE;
  register  int i;
  int expcnt;

  expcnt   = TSsizes[o->sort_id];
  if (expcnt == 0)
    return TRUE;

  o_neg    = o;
  for (i=0; i< expcnt; i++) {
    if (o->exp[i]->class == '!') {
      xto[i] = o->exp[i]->val;
    } else
      if (o->exp[i]->class == 'd') {
	def_flag = TRUE;
	xto[i] = o->exp[i]->val;
      } else {
	flag_neg = TRUE;
	xto[i] = NULL;
      }
  }

  if (flag_neg)
    if(o->f_eval)
      return eval_negot (0);
    else  {
      if (konfig.negotiation) {
	printf ("-> negotiation fail \n ");
	draw_off (o_neg);
      }
      return FALSE;
    }
  else {
    if (! def_flag)
      return predok ();
    else {
      if (predok ())
	return TRUE;
      else {
	if (konfig.negotiation) {
	  printf ("-> negotiation fail \n ");
	  draw_off (o_neg);
	}
	return FALSE;
      }
    }
  }
}

PUBLIC  boolean
  exit_ok (o)
offert o;
{
  register  int i;
  int expcnt;

  expcnt   = TSsizes[o->sort_id];
  if (expcnt == 0)
    return TRUE;

  for (i=0; i< expcnt; i++) {
    if (o->exp[i]->class == '!')
      xto[i] = o->exp[i]->val;
    else {
      if (konfig.negotiation == 0)
	return FALSE;
      else if (konfig.negotiation == 1) {
	 /* 	avisa (); */
	printf ("-> negotiation fail 1\n ");
	draw_off (o_neg);
	return FALSE;
      }else  {
	printf ("-> negotiation fail 2\n ");
	draw_off (o_neg);
	/* pide_valor (); */
	return FALSE;
      }

    }
  }

  return TRUE;
}

PUBLIC  void
  valvar (o)
offert o;
{
  register  int i;
  register  int j;

  suc_n = TSsizes[o->sort_id];
  for (j=0; j < suc_n; j++) {
    for (i=0; i < o_neg->actn ; i++){
      o = o_neg->act[i]->offer;
      if (o->exp[j]->rav != NO_VAR)
	o_neg->act[i]->frm->rav[o->exp[j]->rav]=
	  ud_copy(TSsbes[o->sort_id][j],xto[j]);

    }
    xto[j]= ud_copy(TSsbes[o->sort_id][j],xto[j]);
  }
}


 /*************************************************/

PRIVATE boolean
predok ()

{
  offert o;
  register int  i;

  if (o_neg->f_prd) {
    if(o_neg->f_prd_ok)
      return TRUE;
    for (i=0; i < o_neg->actn; i++) {
      o = o_neg->act[i]->offer;
      if  (o->prd != NO_PRD && (! (ftbl[o->prd](o_neg->act[i]->frm) == TRUE)))
	return FALSE;
    }
  }
  return TRUE;
}


PRIVATE  boolean
eval_negot (n)
int n;
{
  value def_val;
  boolean def_res;
  register int    i;

  if (n == TSsizes[o_neg->sort_id])
    return predok ();
  if (o_neg->exp[n]->class == '!' || o_neg->exp[n]->class == 'd')
    return eval_negot (n+1);

  for (i=0; i < o_neg->actn; i++){
    if (o_neg->act[i]->offer->exp[n]->eval != NO_EVAL) {
      def_res = TSevals[o_neg->act[i]->offer->exp[n]->eval] (& def_val);
      switch (def_res){
      case EVAL_END:
	/* KJT 20/01/23: set to 0 instead of NULL */
	o_neg->act[i]->offer->exp[n]->eval = 0;
	return FALSE;
      case EVAL_OK:
	xto[n] = def_val;
	if (eval_negot(n+1))
	  return TRUE;
      default:
	assert(FALSE);
      }
    }
  }
  return FALSE;
}

