/**
 * 
 */
package semantica;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;

import databases.DatabaseRelazioni;
import databases.DatabaseRicerche;
import parser.Parser;
import types.*;
import knowledge_member.*;

/**
 * @author   Giorgio Ravera
 */
public class AnalizzatoreSemantico extends Thread
{
	private Parser parser = new Parser();
	private LinkedHashMap<String, KnowledgeElement> bidone = new LinkedHashMap<String,KnowledgeElement>();
	
	private DatabaseRelazioni db = DatabaseRelazioni.getInstance();
	
	private DatabaseRicerche ricerca = DatabaseRicerche.getInstance();

	public AnalizzatoreSemantico()
	{
		
		db.addRelation(Alimenti.class, Alimentari.class);
		//db.addRelation(Alimentari.class, Tradizionali.class);
		
		KnowledgeElement k = new Condizioni("fame");
		k.addRelazion(Alimenti.class);
		bidone.put(k.getValue(), k);
		
		k = new Alimenti("budino");
		bidone.put(k.getValue(), k);
		
	}
	
	public void run()
	{
		while(true)
		{
			Frase f = parser.nextFrase();
			if(f==null)
			{
				synchronized(ricerca)
				{
					Iterator<String> i =ricerca.iterator();
					while(i.hasNext())
					{
						System.out.println(i.next());
					}
				}
				return;
			}
			else
			{
				System.out.println(f);
				System.out.println("Negativa? " +f.isNegative());
				elaboraFrase(f);
			}

		}
	}

	private void elaboraFrase(Frase f) 
	{
		List<Symbol> ric=null;
		System.out.println("Elaborazione Semantica...");
		
		
		System.out.println(((VerboConiugato)f.getVerbo()).getVerbo().getValore());
		// Se non  una necessit escludere
		
		
		
		if(f.getOggetto().size()==0)
		{
			System.out.println("Non capisco, sorry");
			return;
		}
		
		
		if(f.getOggetto().get(0).getType()==Type.pronome)
		{
			Pronome p = (Pronome)f.getOggetto().get(0);
			if(p.isPassive())
			{
				ric = f.getSoggetto();
			}
			else
				ric=f.getOggetto();			
		}
		else
			ric=f.getOggetto();
		
		Iterator<Symbol> iter = ric.iterator();
		while(iter.hasNext())
		{
			System.out.print("nuovo evento: ");
			String s = iter.next().getValore();
			KnowledgeElement ke = bidone.get(s);
			if(ke==null)
				continue;
			
			Iterator<Class> rel = ke.getRelations();
			find(rel);
		}
	}

	public void find(Iterator<Class> rel)
	{
		
		while(rel.hasNext())
		{
			try
			{
				Class<?> c = rel.next();
				if(!c.getPackage().equals(KnowledgeElement.class.getPackage()))
					continue;
				Method m = c.getMethod(new String("findable"), null);
				if((Boolean)m.invoke(null, null))
				{
					String nomeClasse = c.getName();
					String keyword = nomeClasse.substring(new String("knowledge_member.").length());
					synchronized(ricerca)
					{
						ricerca.add(keyword);
					}
					System.out.print("cerca su google " + keyword);
				}
				//else
				//{
					// Se A implica B e A  findable, B non viene trovata...
					Iterator<Class> rel2 = db.getRelations(c);
					find(rel2);
				//}
			}
			catch (Exception e) 
			{
				e.printStackTrace();
			} 
		}
	}
}