<?php
define('idDiGIR_LOP','$Id: DiGIR_fltLOP.php,v 1.4 2003/05/06 20:33:22 vieglais Exp $');
if (defined('idDIGIR_VERSION_REQUEST'))
    return;
/*
* $Id: DiGIR_fltLOP.php,v 1.4 2003/05/06 20:33:22 vieglais Exp $
*/
class filterLOP
{
    var $m_LOPop;
    var $m_left;
    var $m_right;
    var $m_parent;
    function filterLOP($op)
    {
        $this->m_LOPop = $op;
        $this->m_left = NULL;
        $this->m_right = NULL;
        $this->m_parent = NULL;
    }

    //sets left or right to the specified child.  This
    //creates a copy of child.
    function setChild($child)
    {
        if (is_null($this->m_left))
        {
            $this->m_left = $child;
            $this->m_left->setParent($this);
            return 0;
        }
        $this->m_right = $child;
        $this->m_right->setParent($this);
        return 1;
    }

    //returns a reference to the left (0) or right (1) child
    function &getChild($id)
    {
        if ($id === 0)
        {
            return $this->m_left;
        }
        return $this->m_right;
    }

    function setParent(&$parent)
    {
        $this->m_parent = &$parent;
    }

    function &getParent()
    {
        return $this->m_parent;
    }

    //attempts to create a filter structure from the provided RPN query string
    //@and @attr 1=1 "a" @or @attr 1=2 "b" @attr 1=3 "c"
    function parseRPN($aElements)
    {
        $idx = 0;
        $nadded = 0;
        while ($nadded < 2)
        {
            DebugMsg("LOP.parseRPN: aElements = ".dumpArray($aElements));
            $s = trim($aElements[0]);
            $atmp = split(" ",$s);
            $opt = opType($atmp[0]);
            switch ($opt)
            {
                case op_AND:
                case op_OR:
                case op_ANDNOT:
                case op_ORNOT:
                    if ($this->m_left == NULL)
                    {
                        DebugMsg("add filter LOP to LEFT");
                        $this->m_left = new filterLOP($opt,&$this);
                        $aElements = array_slice($aElements,1);
                        $this->m_left->parseRPN($aElements);
                        $nadded ++;
                    }
                    else
                    {
                        DebugMsg("add filter LOP to RIGHT");
                        $this->m_right = new filterLOP($opt,&$this);
                        $aElements = array_slice($aElements,1);
                        $this->m_right->parseRPN($aElements);
                        $nadded ++;
                    }
                    break;
                case op_ATTR:
                    $nt = 0;
                    $bFound = FALSE;
                    while (($nt < count($aElements)) && (!$bFound))
                    {
                        if (strpos($aElements[$nt],"\"") === FALSE)
                            $nt++;
                        else
                            $bFound = TRUE;
                    }
                    if ($this->m_left == NULL)
                    {
                        DebugMsg("add filter COP to LEFT");
                        $this->m_left = new filterCOP(cp_undefined);
                        $this->m_left->setParent(&$this);
                        $this->m_left->parseRPN(array_slice($aElements,0,$nt+1));
                        $nadded ++;
                    }
                    else
                    {
                        DebugMsg("add filter COP to RIGHT");
                        $this->m_right = new filterCOP(cp_undefined);
                        $this->m_right->setParent(&$this);
                        $this->m_right->parseRPN(array_slice($aElements,0,$nt+1));
                        $nadded ++;
                    }
                    $aElements = array_slice($aElements,$nt+1);
                    break;
            }
        }
    }

    function Dump($n)
    {
        $this->m_left->Dump($n+1);
        $stab = ".";
        for ($i=0; $i<$n; $i++)
                $stab = $stab.".";
        switch ($this->m_LOPop)
        {
        case op_AND:
            echo $stab."AND\n";
            break;
        case op_ANDNOT:
            echo $stab."AND NOT\n";
            break;
        case op_OR:
            echo $stab."OR\n";
            break;
        case op_ORNOT:
            echo $stab."OR NOT\n";
            break;
        }
        $this->m_right->Dump($n+1);
    }

    function toSQL(&$Cfg)
    {
        $sql = "";
        if (($this->m_left != NULL) && ($this->m_right != NULL))
        {
            $sql = '('.$this->m_left->toSQL($Cfg);
            switch ($this->m_LOPop)
            {
                case op_AND:
                    $sql = $sql." AND ";
                    break;
                case op_ANDNOT:
                    $sql = $sql." AND NOT ";
                    break;
                case op_OR:
                    $sql = $sql." OR ";
                    break;
                case op_ORNOT:
                    $sql = $sql." OR NOT ";
                    break;
            }
        $sql = $sql.$this->m_right->toSQL($Cfg).')';
        }
        return $sql;
    }

    function toRPN(&$Cfg)
    {
        $rpn = "";
        if (($this->m_left != NULL) && ($this->m_right != NULL))
        {
            switch ($this->m_LOPop)
            {
            case op_AND:
                $rpn = " @and ";
                break;
            case op_ANDNOT:
                $rpn = " @and @not ";
                break;
            case op_OR:
                $rpn = " @or ";
                break;
            case op_ORNOT:
                $rpn = " @or @not ";
                break;
            }
            $rpn = $rpn.$this->m_left->toRPN($Cfg);
            $rpn = $rpn.$this->m_right->toRPN($Cfg);
        }
        return $rpn;
    }

    function andDupe()
    {
        if (($this->m_LOPop == op_AND) ||
            ($this->m_LOPop == op_ANDNOT))
        {

        }
    }

}

?>
