/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 Copyright (C) Picosoft s.r.l. 1995-2002

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
# ifndef where_h
# define where_h "$Id: where.h 5.0 1999/10/08 10:17:43 picoSoft Exp $"
# include "conditn.h"
# include "cfield.h"
# include "stmtattr.h"
# include "pstack.h"

class SqlParser;
class TokenIterator;
PTSTACK(Condition);

class Where : public PObject 
{
private:
   PCLASS(Where, PObject)
   ConditionList ValidCond;
   ConditionList Stack;
   SqlParser *Parent;
   Expression::Method findAttr;
   void Complement ();
   const PBool parseAggregate;
   Error FirstTerm (Lex &l, PStack(Condition) & localStack);
   Error CfrtOp (Lex &l, PStack(Condition) & localStack, Expression *ex, PBool isNot);
   Error SecondTerm (Lex &l, PStack(Condition) & localStack,
                     Expression *ex1, toknum op, PBool isNot);
   Error BoolOp (Lex &l, PStack(Condition) & localStack);
   void reduce (Token *lookAhead, PStack(Condition) &localStack);
public:
   Where (SqlParser *sp, Expression::Method m, PBool aggr);
   ~Where() { Clear (); }
   void Clear ();
   void SetValidCond (ConditionList *cl) {
      Condition *c;
      if (cl)
         for (c = cl->GetFirst (); c; c = cl->GetNext())
            ValidCond.AddItem (c);
   }
   ConditionList & GetValidCond () { return ValidCond; }
   Error verifyExpression();
   Error Eval (StmtRel *sr, PBool &result);
   Error Parse (Lex &l, const Token *startToken);
   Condition * GetFirst () { return Stack.GetFirst (); }
   Condition * GetLast ()  { return Stack.GetLast (); }
   Condition * GetCurrent ()  { return Stack.GetCurrent (); }
   Condition * GetNext ()  { return Stack.GetNext ();} 
   Condition * GetPrevious ()  { return Stack.GetPrevious ();}
   Condition * GetAt (int i)  { return Stack.GetAt (i);}
   Condition * DelCurrent ()  { Condition *c = Stack.GetCurrent();
                                if (c)
                                   delete c;
                                return Stack.DeleteCurrent ();
                              } 
   long GetItemNum () { return Stack.GetItemNum(); }
   void toString (PString &result);
};
# endif
