// $Id: xxl_lookup.cc,v 1.3 1997/01/07 01:07:35 aml Exp $

#include "xxl_funcs.hh"
#include "sheet.hh"



Stack_elem *Vlookup::eval(Stack_elem *p,Sheet *sheet, short col, short row) {
    double value;
    int column;
    Range rg1;
    int flag;
    short r,c,rf,cf;
    double f1;

    sheet->propagate_error(p-2,se);
    value = sheet->stack_value(p-2);
    rg1 = (p-1)->contents.rg_val;
    column = (int) sheet->stack_value(p);
    sheet->propagate_error(p,se);
    flag = 1;

    r = cell_address(rg1.start.row,row);
    c = cell_address(rg1.start.col,col);
    rf = cell_address(rg1.end.row,row);
    cf = cell_address(rg1.end.col,col);

    se->type = FORM_STRING;
    sprintf(se->contents.string_val,"# VALUE");

    if (c > cf) return(se);
    
    short i;
    Stack_elem *s1;
    for(i=r ; i<=rf ; i++) {
      s1 = sheet->cellRef(c,i);
      sheet->propagate_error(s1,se);
      f1 = sheet->stack_value(s1);

      if (f1 == value) {
        break;
      } else if (f1 > value) {
        i--;
        if (!flag) i = r-1;
        break;
      }
    }
    if (i > rf || i < r ) return(se);

    s1 = sheet->cellRef(c+column,i);
    sheet->propagate_error(s1,se);
    *se = *s1;
    se->type = FORM_REF;
    return(se);
}

Vlookup::Vlookup() {
    se = new Stack_elem;
}

Vlookup::~Vlookup() {
    delete se;
}


Stack_elem *Hlookup::eval(Stack_elem *p,Sheet *sheet, short col, short row) {
    double value;
    int rrow;
    Range rg1;
    int flag;
    short r,c,rf,cf;
    double f1;

    sheet->propagate_error(p-2,se);
    value = sheet->stack_value(p-2);
    rg1 = (p-1)->contents.rg_val;
    rrow = (int) sheet->stack_value(p);
    sheet->propagate_error(p,se);
    flag = 1;

    r = cell_address(rg1.start.row,row);
    c = cell_address(rg1.start.col,col);
    rf = cell_address(rg1.end.row,row);
    cf = cell_address(rg1.end.col,col);

    se->type = FORM_STRING;
    sprintf(se->contents.string_val,"# VALUE");

    if (c > cf) return(se);
    
    short i;
    Stack_elem *s1;
    for(i=c ; i<=cf ; i++) {
      s1 = sheet->cellRef(i,r);
      sheet->propagate_error(s1,se);
      f1 = sheet->stack_value(s1);

      if (f1 == value) {
        break;
      } else if (f1 > value) {
        i--;
        if (!flag) i = r-1;
        break;
      }
    }
    if (i > cf || i < c ) return(se);

    s1 = sheet->cellRef(i,r+rrow);
    sheet->propagate_error(s1,se);
    *se = *s1;
    se->type = FORM_REF;
    return(se);
}

Hlookup::Hlookup() {
    se = new Stack_elem;
}

Hlookup::~Hlookup() {
    delete se;
}



// $Log: xxl_lookup.cc,v $
// Revision 1.3  1997/01/07  01:07:35  aml
// Error propagation for formulas fixed.
// Edit operations in place.
//
// Revision 1.2  1997/01/02 16:15:31  aml
// Fixed unsufficient range of colunm width.
// First cut of vlookup and hlookup functions.
// Fixed bug in display routines.
//
// Revision 1.1  1997/01/02 13:53:54  aml
// Initial revision
//
