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

import data.*;
import javax.swing.*;

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

    String s;
    public Uzol a;
    Uzol b;
    Formular f;
    public int zdola = 0;
    public int lavy = 1;
    String finalPredikat = "";
    String answer = "";
    int bezOperacie = 1;

    public Parser(String s, Formular f) 
    {
        String n = "";
       
        f.vypis("POVODNY " + s + "\n");
        
        int i = 0;
        int j = 0;
        int z, e;

        while (s.charAt(i) != '(')
        {
            
            if ((s.charAt(i) == Utils.maly) || (s.charAt(i) == Utils.velky))
            {
                j = i + 1;
                if ( ! finalPredikat.equals("")) 
                {
                    finalPredikat += ",";
                }
                
                while ((s.charAt(j) != Utils.maly) && (s.charAt(j) != Utils.velky) && (s.charAt(j) != '(') && (s.charAt(j) != Utils.negacia)) 
                {
                    finalPredikat += s.charAt(j);
                    j++;
                }
            }
            i++;
        }

        i++;
        z = i;

        i = s.length() - 1;
        
        while (s.charAt(i) != Utils.implikacia)
        {
            i--;
        }

        e = i - 1;
        j = e;
        j++;
       
        while (s.charAt(j) != ')')
        {
            j++;
            answer += s.charAt(j);
        }

        for (int k = z; k <= e; k++)
        {
            n += s.charAt(k);
        }

        this.s = n;
        this.f = f;
        Utils.setFinalPredikat(finalPredikat);
        Utils.setAnswer(answer);
        Utils.setBezOperacie(bezOperacie);
    }

    public int najdiZaciatok(int p, int z)
    {
        int i = 0;
        int k = 0;

        while (k <= 1) 
        {

            if (s.charAt(p) == ')') 
            {
                i++;
            }
            
            if (s.charAt(p) == '(') 
            {
                i--;
            }

            if (i == 0) 
            {
                p--;
                //            while ((s.charAt(p)!='(') && (s.charAt(p)!='∃') && (s.charAt(p)!='∀') && (s.charAt(p)!='¬')) p--;
                
                while ((s.charAt(p) != '('))
                {
                    p--;
                }
//povodne tam bola iba zatvorka
                //if (s.charAt(p+1)=='¬') return p+1;
                return p + 1;

            }

            p--;
        }
        return 0;
    }

    public int nemaSpojku(int z, int p) 
    {
        for (int i = z; i <= p; i++) 
        {
            if ((s.charAt(i) == Utils.implikacia) || (s.charAt(i) == Utils.and) || (s.charAt(i) == Utils.or) || (s.charAt(i) == Utils.or2)) 
            {
                return 0;
            }
        }
        return 1;
    }

    public int najdiKoniec(int p) 
    {

        int i = 0;
        int k = 0;

        while ((s.charAt(p) != '(') && (s.charAt(p) != ')')) 
        {
            p++;
        }

        if (s.charAt(p) == ')')
        {
            return p - 1;
        }

        while (k <= 1)
        {


            if (s.charAt(p) == ')') 
            {
                i++;
            }
            
            if (s.charAt(p) == '(') 
            {
                i--;
            }

            if (i == 0)
            {
                return p;
            }

            p++;
        }
        return 0;
    }

 
   

    public boolean kvantifikator(int zac, int kon, int i) {
      
        int zat;
        boolean kvanti = false;

        for (int j = zac; j <= kon; j++)
        {
            
            if ((s.charAt(j) == Utils.and) || (s.charAt(j) == Utils.or2) || (s.charAt(j) == Utils.or) || (s.charAt(j) == Utils.implikacia)) 
            {
                kvanti = true;
            }
        }
        if (!kvanti)
        {
            return true;
        }

        kvanti = false;

        while (s.charAt(i) != '(')
        {
            i++;
        }
        zat = 1;
        i++;
        
        while ((zat != 0) && (i <= kon)) 
        {
           
            if ((s.charAt(i) == Utils.and) || (s.charAt(i) == Utils.or2) || (s.charAt(i) == Utils.or) || (s.charAt(i) == Utils.implikacia)) 
            {
                kvanti = true;
            }
            i++;
        }
        return kvanti;
    }

    public int runParser(int zac, int kon, Uzol u) 
    {
        int otv = 0;
        int min = 999;
        int pos = -1, kvant = 0;
        //    f.vypis("1");
        if (kon > s.length()) {
            kon = s.length() - 1;
        }
        //f.vypis("2"+s);
        //    f.vypis("pracujem s "+substr(s,zac,kon));
        //     f.vypis("3");
       
        if ((s.charAt(zac) == '(') && (s.charAt(kon) == ')'))
        {
            zac++;
            kon--;
        }
        f.vypis("pracujem s " + Utils.substr(s, zac, kon));

        //   "∀F((∃V∃C∃L(objednavky(jozo, V)∧dodava(F, V, C, L)))⇒dodava_nieco_jozovi(F))"

        for (int i = zac; i <= kon; i++)
        {
            
            if (s.charAt(i) == '(')
            {
                otv++;
            }
            
            if (s.charAt(i) == ')') 
            {
                otv--;
            }
           
            if ((s.charAt(i) == Utils.implikacia) || (s.charAt(i) == Utils.and) || (s.charAt(i) == Utils.or) || (s.charAt(i) == Utils.or2))
            {
                if (min > otv) {
                    min = otv;
                    pos = i;
                }
            }
        }
        otv = 0;
        kvant = 1;
        //     f.vypis("min je "+min);
        
        for (int i = zac; i <= kon; i++) 
        {
            
            if (s.charAt(i) == '(')
            {
                otv++;
            }
            
            if (s.charAt(i) == ')')
            {
                otv--;
            }
            
            if (((((s.charAt(i) == Utils.velky) || (s.charAt(i) == Utils.maly)) && (min - 1 == otv)) ||
                    (((s.charAt(i) == Utils.velky) || (s.charAt(i) == Utils.maly)) && (otv == 0))) && (kvantifikator(zac, kon, i))) 
            {
                System.out.println("vkladam unarny" + "" + s.charAt(i) + Utils.getWord(s, i + 1));
                f.vypis("vkladam " + kvant + " unarny " + "" + s.charAt(i) + Utils.getWord(s, i + 1));
                u = u.add(new UzolUnarny(u, "" + s.charAt(i) + Utils.getWord(s, i + 1)));
                kvant = kvant + 1 + Utils.getWord(s, i + 1).length();
            }

            if (((s.charAt(i) == Utils.negacia) && (min - 1 >= otv)) || ((s.charAt(i) == Utils.negacia) && (otv == 0) && (nemaSpojku(zac, kon) == 1)) ||
                    ((s.charAt(i) == Utils.negacia) && ((s.charAt(i + 1) == Utils.velky) || (s.charAt(i + 1) == Utils.maly)))) 
            {
                System.out.println("vkladam unarny" + "" + s.charAt(i));
                f.vypis("vkladam unarny " + "" + s.charAt(i));
                u = u.add(new UzolUnarny(u, "" + s.charAt(i)));
                //     f.vypis("index je " +i);
                int g;
                g = i - zac + 1;
                //      f.vypis("tamto nove by mohlo byt "+g+ " pismeno "+s.charAt(g));


                kvant = kvant + 1;
                kvant = g;
            }
        }
        
        if (kvant == 1) 
        {
            kvant = 0;
        }


        if (pos == -1) 
        {
            int p = zac;
            int dalej = 0;
            int zat = 0;
            /*            
            while (dalej==0)
            {
            if  ((s.charAt(p)=='∀') || (s.charAt(p)=='¬') || (s.charAt(p)=='∃') || (s.charAt(p)=='('))  
            {
            if (s.charAt(p)=='(') zat++;
            p++;
            while ((s.charAt(p)!='∀') && (s.charAt(p)!='¬') && (s.charAt(p)=='∃')  && (s.charAt(p)=='(') )  p++;
            }
            if ((s.charAt(p)!='∀') && (s.charAt(p)!='¬') && (s.charAt(p)!='∃') && (s.charAt(p)!='('))  dalej=1;
            }
             */

            while (dalej == 0) 
            {
               
                if (s.charAt(p) == '(') 
                {
                    p++;
                    zat++;
                }
               
                if (s.charAt(p) == Utils.negacia)
                {
                    p++;
                }

                if ((s.charAt(p) == Utils.velky) || (s.charAt(p) == Utils.maly)) 
                {
                    p++;
                    
                    while ((s.charAt(p) != Utils.velky) && (s.charAt(p) != Utils.maly) && (s.charAt(p) != '(') && (s.charAt(p) != Utils.negacia)) 
                    {
                        p++;
                    }
                }

                if ((s.charAt(p) != Utils.velky) && (s.charAt(p) != Utils.maly) && (s.charAt(p) != '(') && (s.charAt(p) != Utils.negacia)) 
                {
                    dalej = 1;
                }

            }

            //     System.out.println("vkladam operand"+substr(s,zac,kon));
            //   System.out.println("vkladam operand"+substr(s,p,kon-zat));            
            f.vypis("vkladam operand " + Utils.substr(s, p, kon - zat));
            //if (s.charAt(zac)=='¬') u.add(new UzolOperand(u,substr(s,zac+1,kon)));   else 
            u.add(new UzolOperand(u, Utils.substr(s, p, kon - zat)));
        //  f.vypis("som tu 1");
        } 
        else 
        {
            System.out.println("vkladam operaciu" + s.charAt(pos));
            f.vypis("vkladam operaciu " + s.charAt(pos));
            bezOperacie = 0;
            Uzol uu = u.add(new UzolOperacia(u, s.charAt(pos)));
            //    f.vypis("na mieste pos-1 "+s.charAt(pos-1));
            //  f.vypis("najdi zaciatok je na indexe "+najdiZaciatok(pos-1,zac)+" na pismene"+s.charAt(najdiZaciatok(pos-1,zac)) );              
            runParser(Math.max(kvant, najdiZaciatok(pos - 1, zac)), pos - 1, uu);

            //   f.vypis("druha cast ");
            runParser(pos + 1, najdiKoniec(pos + 1), uu);
        }
        return 0;
    }
}
