/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package transformacie;

import data.*;

/**
 *
 * @author chislim
 */
public class PosunNegaciiNadol 
{

      public PosunNegaciiNadol()
    {
        Uzol.f.vypis3("\n\nPOSUN NEGACII NADOL \n"); 
    }
      
    public void runPosunNegaciiNadol(Uzol u)
    {
        while (u instanceof UzolUnarny)
        {
            u = u.lavy;
        }
        negacieNadol(u.otec);
    }

    public boolean lavySyn(Uzol u)
    {
        Uzol w = u;

        while ((!(w.otec instanceof UzolOperacia)) && (w.otec != null)) 
        {
            w = w.otec;
        }

        if (w.otec != null)
        {
            if (w.equals(w.otec.lavy))
            {
                return true;
            }
            else 
            {
                return false;
            }
        }
        return true;
    }

    public void negacieNadol(Uzol u) 
    {

        if (u instanceof UzolUnarny)
        {
           
            if (((UzolUnarny) u).getUnarna() == Utils.negacia) 
            {
               
                if (!((u.lavy) instanceof UzolOperand)) 
                {
                    Uzol w;
                    w = u;
                    //idem zrusit samotnu negaciu ktoru posuvam dole 
                   
                    if (u.lavy instanceof UzolOperacia) 
                    {
                        //zmenenie operacie po znegovani
                    
                        if (((UzolOperacia) u.lavy).getSign() == Utils.and)
                        {
                            ((UzolOperacia) u.lavy).setSign(Utils.or);
                        } 
                        else if ((((UzolOperacia) u.lavy).getSign() == Utils.or) || (((UzolOperacia) u.lavy).getSign() == Utils.or2)) {
                            ((UzolOperacia) u.lavy).setSign(Utils.and);
                        }
                    }

                    if (u.otec instanceof UzolOperacia)
                    {
                        if (lavySyn(u)) 
                        {
                            u.lavy.otec = u.otec;
                            u.otec.lavy = u.lavy;
                        } 
                        else
                        {
                            u.lavy.otec = u.otec;
                            u.otec.pravy = u.lavy;
                        }
                    } 
                    else
                    {
                        //ak je otec unarna 
                        u.lavy.otec = u.otec;
                        u.otec.lavy = u.lavy;
                    }

                    // idem spracovat lavu stranu
                    w = w.lavy;

                    if (w.lavy instanceof UzolUnarny)
                    {
                        if (((UzolUnarny) w.lavy).getUnarna() == Utils.negacia) 
                        {
                            //idem zrusit existujucu negaciu, prelinkovanim
                            w.lavy.lavy.otec = w;
                            w.lavy = w.lavy.lavy;
                        }
                    } 
                    else 
                    {
                        Uzol neg = new UzolUnarny(w, "" + Utils.negacia);
                        neg.lavy = w.lavy;
                        w.lavy.otec = neg;
                        w.lavy = neg;
                    // ak to nie je negacia tak to moze byt operand alebo operacia a tam sa to 
                    // bude chovat rovnako, iba sa vlozi negacia pred dany Uzol
                    }
                    //prava cast
                  
                    if (w.pravy instanceof UzolUnarny) 
                    {
                   
                        if (((UzolUnarny) w.pravy).getUnarna() == Utils.negacia) 
                        {
                            //idem zrusit existujucu negaciu
                            w.pravy.lavy.otec = w;
                            w.pravy = w.pravy.lavy;
                        }
                    } 
                    else
                    {
                        Uzol neg = new UzolUnarny(w, "" + Utils.negacia);
                        neg.lavy = w.pravy;
                        w.pravy.otec = neg;
                        w.pravy = neg;
                    // ak to nie je negacia tak to moze byt operand alebo operacia a tam sa to 
                    // bude chovat rovnako, iba sa vlozi negacia pred dany Uzol
                    }
                } 
                else 
                {
                //ak to pod negaciou je uz operand tak nic sa nerobi, negacia je uz uplne dole
                }
            }
        }

        if (u.lavy != null) 
        {
            negacieNadol(u.lavy);
        }
      
        if (u.pravy != null) 
        {
            negacieNadol(u.pravy);
        }
    }
}
