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

import data.*;

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

    public Distributivita()
    {
        Uzol.f.vypis3("\n\nDISTRIBUTIVITA \n"); 
    }
            
    
    public void zduplikuj(Uzol u, Uzol w) 
    {

        // w.otec=u.otec;
        if (u.lavy != null) 
        {

            if (u.lavy instanceof UzolUnarny)
            {
                Uzol n = new UzolUnarny(w, ((UzolUnarny) u.lavy).getUnarna() + ((UzolUnarny) u.lavy).getOperand());
                w.lavy = n;
            }
            
            if (u.lavy instanceof UzolOperand)
            {
                Uzol n = new UzolOperand(w, ((UzolOperand) u.lavy).getOperand());
                w.lavy = n;
            }
            
            if (u.lavy instanceof UzolOperacia)
            {
                Uzol n = new UzolOperacia(w, ((UzolOperacia) u.lavy).getSign());
                w.lavy = n;
            }
        }
        
        if (u.pravy != null) 
        {

            if (u.pravy instanceof UzolUnarny)
            {
                Uzol n = new UzolUnarny(w, ((UzolUnarny) u.pravy).getUnarna() + ((UzolUnarny) u.pravy).getOperand());
                w.pravy = n;
            }
            
            if (u.pravy instanceof UzolOperand)
            {
                Uzol n = new UzolOperand(w, ((UzolOperand) u.pravy).getOperand());
                w.pravy = n;
            }
           
            if (u.pravy instanceof UzolOperacia)
            {
                Uzol n = new UzolOperacia(w, ((UzolOperacia) u.pravy).getSign());
                w.pravy = n;
            }
        }

        if (u.lavy != null) 
        {
            zduplikuj(u.lavy, w.lavy);
        }

        if (u.pravy != null) 
        {
            zduplikuj(u.pravy, w.pravy);
        }
  }

    public Uzol getZduplikovanyUzol(Uzol u)
    {
        Uzol n = u;
        
        if (u instanceof UzolOperand)
        {
            n = new UzolOperand(((UzolOperand) u).getOtec(), ((UzolOperand) u).getOperand());
        }

        if (u instanceof UzolOperacia)
        {
            n = new UzolOperacia(((UzolOperacia) u).getOtec(), ((UzolOperacia) u).getSign());
            ((UzolOperacia) n).setLavySyn(u.lavy);
            ((UzolOperacia) n).setPravySyn(u.pravy);
        }
       
        if (u instanceof UzolUnarny) 
        {
            n = new UzolUnarny(((UzolUnarny) u).getOtec(), ((UzolUnarny) u).getUnarna() + ((UzolUnarny) u).getOperand());
            ((UzolUnarny) n).setLavySyn(u.lavy);
        }
        return n;
    }

    public void runDistributivita(Uzol u)
    {

        if (u instanceof UzolOperacia)
        {


            if (((UzolOperacia) u).getSign() == Utils.and)
            {

                if (u.lavy instanceof UzolOperacia)
                {

                    if ((((UzolOperacia) u.lavy).getSign() == Utils.or) || (((UzolOperacia) u.lavy).getSign() == Utils.or2)) 
                    {

                        if ((u.pravy instanceof UzolOperand) || (u.pravy instanceof UzolUnarny)) 
                        {
                            //hore konjukcia, vlavo disjunkcia, vpravo operand
                            Uzol n = new UzolOperacia(u, Utils.and);
                            Uzol z;

                            ((UzolOperacia) u).setSign(Utils.or);
                            ((UzolOperacia) u.lavy).setSign(Utils.and);
                            //((UzolOperacia)u.lavy).setPravySyn(u.pravy);                           

                            ((UzolOperacia) n).setPravySyn(u.pravy);
                            ((UzolOperacia) n).setLavySyn(u.lavy.pravy);
                            n.lavy.setOtec(n);

                            ((UzolOperacia) u).setPravySyn(n);

                            n.pravy.setOtec(n);

                            // 

                            //  ((UzolOperacia)u.lavy).setPravySyn(n.pravy); 
                            ((UzolOperacia) u.lavy).setPravySyn(getZduplikovanyUzol(n.pravy));
                            zduplikuj(n.pravy, u.lavy.pravy);

                            u.lavy.pravy.setOtec(u.lavy);

                        //((UzolOperacia)n).setLavySyn(u.lavy.pravy); 
                        }
                        else 
                        {
                           
                            if (u.pravy instanceof UzolOperacia)
                            {
                                // je to operacia, este zistit ze ci disjunkcia alebo konjukcia
                               
                                if ((((UzolOperacia) u.pravy).getSign() == Utils.or) || (((UzolOperacia) u.pravy).getSign() == Utils.or2))
                                {
                                    ((UzolOperacia) u).setSign(Utils.or);
                                    ((UzolOperacia) u.lavy).setSign(Utils.or);
                                    ((UzolOperacia) u.pravy).setSign(Utils.or);

                                    Uzol u1 = new UzolOperacia(u.lavy, Utils.and);
                                    Uzol u2 = new UzolOperacia(u.lavy, Utils.and);
                                    Uzol u3 = new UzolOperacia(u.pravy, Utils.and);
                                    Uzol u4 = new UzolOperacia(u.pravy, Utils.and);

                                    ((UzolOperacia) u1).setLavySyn(getZduplikovanyUzol(u.lavy.lavy));
                                    zduplikuj(u.lavy.lavy, u1.lavy);
                                    u1.lavy.otec = u1;
                                    ((UzolOperacia) u1).setPravySyn(getZduplikovanyUzol(u.pravy.lavy));
                                    zduplikuj(u.pravy.lavy, u1.pravy);
                                    u1.pravy.otec = u1;

                                    ((UzolOperacia) u2).setLavySyn(getZduplikovanyUzol(u.lavy.lavy));
                                    zduplikuj(u.lavy.lavy, u2.lavy);
                                    u2.lavy.otec = u2;
                                    ((UzolOperacia) u2).setPravySyn(getZduplikovanyUzol(u.pravy.pravy));
                                    zduplikuj(u.pravy.pravy, u2.pravy);
                                    u2.pravy.otec = u2;

                                    ((UzolOperacia) u3).setLavySyn(getZduplikovanyUzol(u.lavy.pravy));
                                    zduplikuj(u.lavy.pravy, u3.lavy);
                                    u3.lavy.otec = u3;
                                    ((UzolOperacia) u3).setPravySyn(getZduplikovanyUzol(u.pravy.lavy));
                                    zduplikuj(u.pravy.lavy, u3.pravy);
                                    u3.pravy.otec = u3;

                                    ((UzolOperacia) u4).setLavySyn(getZduplikovanyUzol(u.lavy.pravy));
                                    zduplikuj(u.lavy.pravy, u4.lavy);
                                    u4.lavy.otec = u4;
                                    ((UzolOperacia) u4).setPravySyn(getZduplikovanyUzol(u.pravy.pravy));
                                    zduplikuj(u.pravy.pravy, u4.pravy);
                                    u4.pravy.otec = u4;

                                    u.lavy.lavy = u1;
                                    u.lavy.pravy = u2;
                                    u.pravy.lavy = u3;
                                    u.pravy.pravy = u4;

                                } 
                                else 
                                {
                                    
                                    if (((UzolOperacia) u.pravy).getSign() == Utils.and)
                                    {
                                        ((UzolOperacia) u).setSign(Utils.or);
                                        //   ((UzolOperacia)u.lavy).setSign(and);
                                        // ((UzolOperacia)u.pravy).setSign(and);                               

                                        Uzol u1 = new UzolOperacia(u, Utils.and);
                                        Uzol u2 = new UzolOperacia(u1, Utils.and);
                                        Uzol u3 = new UzolOperacia(u, Utils.and);
                                        Uzol u4 = new UzolOperacia(u3, Utils.and);

                                        ((UzolOperacia) u1).setLavySyn(getZduplikovanyUzol(u.lavy.lavy));
                                        zduplikuj(u.lavy.lavy, u1.lavy);
                                        u1.lavy.otec = u1;
                                        ((UzolOperacia) u1).setPravySyn(u2);
                                        //zduplikuj(u.pravy.lavy, u1.pravy);

                                        ((UzolOperacia) u2).setLavySyn(getZduplikovanyUzol(u.pravy.lavy));
                                        zduplikuj(u.pravy.lavy, u2.lavy);
                                        u2.lavy.otec = u2;
                                        ((UzolOperacia) u2).setPravySyn(getZduplikovanyUzol(u.pravy.pravy));
                                        zduplikuj(u.pravy.pravy, u2.pravy);
                                        u2.pravy.otec = u2;

                                        ((UzolOperacia) u3).setLavySyn(getZduplikovanyUzol(u.lavy.pravy));
                                        zduplikuj(u.lavy.pravy, u3.lavy);
                                        u3.lavy.otec = u3;
                                        ((UzolOperacia) u3).setPravySyn(u4);
                                        //zduplikuj(u.pravy.lavy, u3.pravy);

                                        ((UzolOperacia) u4).setLavySyn(getZduplikovanyUzol(u.pravy.lavy));
                                        zduplikuj(u.pravy.lavy, u4.lavy);
                                        u4.lavy.otec = u4;
                                        ((UzolOperacia) u4).setPravySyn(getZduplikovanyUzol(u.pravy.pravy));
                                        zduplikuj(u.pravy.pravy, u4.pravy);
                                        u4.pravy.otec = u4;

                                        u.lavy = u1;
                                        u.pravy = u3;
                                    }
                                }
                            }
                        }
                    } 
                    else 
                    {
                        //ak pravy je disjunkcia
//                  
                        //                     {   

                        if (u.lavy instanceof UzolOperacia) 
                        {
                          
                            if (((UzolOperacia) u.lavy).getSign() == Utils.and) 
                            {

                                if (u.pravy instanceof UzolOperacia)
                                {
                                
                                    if ((((UzolOperacia) u.pravy).getSign() == Utils.or) || (((UzolOperacia) u.pravy).getSign() == Utils.or2)) 
                                    {
                                        ((UzolOperacia) u).setSign(Utils.or);
                                        //((UzolOperacia)u.lavy).setSign(and);
                                        //((UzolOperacia)u.pravy).setSign(and);                               

                                        Uzol u1 = new UzolOperacia(u, Utils.and);
                                        Uzol u2 = new UzolOperacia(u1, Utils.and);
                                        Uzol u3 = new UzolOperacia(u, Utils.and);
                                        Uzol u4 = new UzolOperacia(u3, Utils.and);


                                        ((UzolOperacia) u1).setLavySyn(u2);
                                        ((UzolOperacia) u1).setPravySyn(getZduplikovanyUzol(u.pravy.lavy));
                                        zduplikuj(u.pravy.lavy, u1.pravy);
                                        u1.pravy.otec = u1;

                                        ///zduplikuj(u.pravy.lavy, u1.pravy);

                                        ((UzolOperacia) u2).setLavySyn(getZduplikovanyUzol(u.lavy.lavy));
                                        zduplikuj(u.lavy.lavy, u2.lavy);
                                        u2.lavy.otec = u2;

                                        ((UzolOperacia) u2).setPravySyn(getZduplikovanyUzol(u.lavy.pravy));
                                        zduplikuj(u.lavy.pravy, u2.pravy);
                                        u2.pravy.otec = u2;

                                        ((UzolOperacia) u3).setLavySyn(u4);
                                        ((UzolOperacia) u3).setPravySyn(getZduplikovanyUzol(u.pravy.pravy));
                                        zduplikuj(u.pravy.pravy, u3.pravy);
                                        u3.pravy.otec = u3;

                                        //zduplikuj(u.pravy.lavy, u3.pravy);

                                        ((UzolOperacia) u4).setLavySyn(getZduplikovanyUzol(u.lavy.lavy));
                                        zduplikuj(u.lavy.lavy, u4.lavy);
                                        u4.lavy.otec = u4;

                                        ((UzolOperacia) u4).setPravySyn(getZduplikovanyUzol(u.lavy.pravy));
                                        zduplikuj(u.lavy.pravy, u4.pravy);
                                        u4.pravy.otec = u4;

                                        u.lavy = u1;
                                        u.pravy = u3;
                                    }
                                }
                            }
                        }

                    //}
                    }
                }
                else 
                {
                    //tu dat ak lavy syn je operand
                   
                    if (((u.lavy instanceof UzolOperand) || (u.lavy instanceof UzolUnarny)) && (u.pravy instanceof UzolOperacia)) {
                       
                        if ((((UzolOperacia) u.pravy).getSign() == Utils.or) || (((UzolOperacia) u.pravy).getSign() == Utils.or2)) {
                            //hore konjukcia, vlavo operand, vpravo disjunkcia
                            Uzol n = new UzolOperacia(u, Utils.and);
                            Uzol z;

                            ((UzolOperacia) u).setSign(Utils.or);

                            ((UzolOperacia) u.pravy).setSign(Utils.and);
                            //((UzolOperacia)u.lavy).setPravySyn(u.pravy);                           

                            ((UzolOperacia) n).setLavySyn(u.lavy);
                            ((UzolOperacia) n).setPravySyn(u.pravy.lavy);
                            n.lavy.setOtec(n);

                            ((UzolOperacia) u).setLavySyn(n);
                            n.pravy.setOtec(n);

                            // 

                            // ((UzolOperacia)u.pravy).setLavySyn(n.lavy); 
                            ((UzolOperacia) u.pravy).setLavySyn(getZduplikovanyUzol(n.lavy));
                            zduplikuj(n.lavy, u.pravy.lavy);
                            //
                            u.pravy.lavy.setOtec(u.pravy);
                        }
                    }

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