package org.maltparser.parser.algorithm.moreTransition;



	import org.maltparser.core.exception.MaltChainedException;
	import org.maltparser.core.syntaxgraph.DependencyStructure;
	import org.maltparser.core.syntaxgraph.node.DependencyNode;
	import org.maltparser.parser.DependencyParserConfig;
	import org.maltparser.parser.Oracle;
	import org.maltparser.parser.ParserConfiguration;
	import org.maltparser.parser.history.GuideUserHistory;
	import org.maltparser.parser.history.action.GuideUserAction;
	import org.maltparser.core.syntaxgraph.LabelSet;
	import org.maltparser.core.symbol.trie.TrieSymbolTable;
import org.maltparser.core.symbol.trie.Trie;
	/**
	 * @author Carlos Gomez Rodriguez
	 *
	 */
	public class MoreTransitionOracle extends Oracle {

		public MoreTransitionOracle(DependencyParserConfig manager, GuideUserHistory history) throws MaltChainedException {
			super(manager, history);
			setGuideName("MT");
		}
		
		public GuideUserAction predict(DependencyStructure gold, ParserConfiguration config) throws MaltChainedException {
            MoreTransitionConfig planarConfig = (MoreTransitionConfig)config;
			DependencyStructure dg = planarConfig.getDependencyGraph();
			DependencyNode stackPeek = planarConfig.getStack().peek();
			int stackPeekIndex = stackPeek.getIndex();
			int inputPeekIndex = planarConfig.getInput().peek().getIndex();
			
			DependencyNode inputPeek = planarConfig.getInput().peek();
			int inputPeek2Index=0;
			if(planarConfig.getInput().size()>=2){
			   DependencyNode inputPeek2 = planarConfig.getInput().get(planarConfig.getInput().size()-2);
			   inputPeek2Index = inputPeek2.getIndex();
			}
			
			int inputPeek3Index=0;
			if(planarConfig.getInput().size()>=3){
				   DependencyNode inputPeek3 = planarConfig.getInput().get(planarConfig.getInput().size()-3);
				   inputPeek3Index = inputPeek3.getIndex();
			}
//			System.out.println("STACK[0]: "+stackPeekIndex);
//			System.out.println("INPUT[0]: "+inputPeekIndex);
//			System.out.println("INPUT[1]: "+inputPeek2Index);
//			System.out.println("INPUT[2]: "+inputPeek3Index);
			
//			int i=0;
//			while(i<planarConfig.getInput().size())
//			{
//				System.out.println("********* "+planarConfig.getInput().get(i).getIndex()); 
//				i++;
//			}
			
			
			if (planarConfig.getInput().size()>=2  && gold.getTokenNode(inputPeekIndex).getHead().getIndex() == inputPeek2Index
					&& !checkIfArcExists ( dg , inputPeek2Index , inputPeekIndex ))  {
			
				return updateActionContainers(MoreTransition.LEFTSHORTARC, gold.getTokenNode(inputPeekIndex).getHeadEdge().getLabelSet());	
			}
			
//			else if (planarConfig.getInput().size()>=3  && gold.getTokenNode(inputPeekIndex).getHead().getIndex() == inputPeek3Index
//					&& !checkIfArcExists ( dg , inputPeek3Index , inputPeekIndex ) )  {
	
//				return updateActionContainers(MoreTransition.LEFTARCPOP2, gold.getTokenNode(inputPeekIndex).getHeadEdge().getLabelSet());	
//			} 
			//else
//				if (planarConfig.getInput().size()>=2  && gold.getTokenNode(inputPeek2Index).getHead().getIndex() == inputPeekIndex
//					&& !checkIfArcExists ( dg , inputPeekIndex , inputPeek2Index ) 
//					&& !gold.getTokenNode(inputPeek2Index).hasRightDependent()) {
//			
//				return updateActionContainers(MoreTransition.RIGHTSHORTARC, gold.getTokenNode(inputPeek2Index).getHeadEdge().getLabelSet());
//			}
//			else if (gold.getTokenNode(inputPeekIndex).getHead().getIndex() == stackPeekIndex
//					&& !checkIfArcExists ( dg , stackPeekIndex , inputPeekIndex ) && !stackPeek.isRoot() 
//					&& stackPeek.hasHead() && gold.getTokenNode(stackPeekIndex).getRightmostDependent().getIndex()==inputPeekIndex ) {
//				//System.out.println("Stack[0]= "+stackPeekIndex+" Input[0]= "+inputPeekIndex);
//			//	System.out.println("Tiene dependientes el Input[0]" +gold.getTokenNode(stackPeekIndex).getRightmostDependent().getIndex());
//				//System.out.println(gold.getEdges().toString());
//				return updateActionContainers(MoreTransition.RIGHTARCRED, gold.getTokenNode(inputPeekIndex).getHeadEdge().getLabelSet());
//			}
			else if (!stackPeek.isRoot() && gold.getTokenNode(stackPeekIndex).getHead().getIndex() == inputPeekIndex
					&& !checkIfArcExists ( dg , inputPeekIndex , stackPeekIndex ) )  {
			
				return updateActionContainers(MoreTransition.LEFTARC, gold.getTokenNode(stackPeekIndex).getHeadEdge().getLabelSet());	
			
			}
				
//			else if (planarConfig.getInput().size()>=2  && !stackPeek.isRoot() && gold.getTokenNode(stackPeekIndex).getHead().getIndex() == inputPeek2Index
//						&& !checkIfArcExists ( dg , inputPeek2Index , stackPeekIndex ) )  {
//				
//					return updateActionContainers(MoreTransition.LEFTNONPROJARC, gold.getTokenNode(stackPeekIndex).getHeadEdge().getLabelSet());	
//				
//				}
			
			else if (gold.getTokenNode(inputPeekIndex).getHead().getIndex() == stackPeekIndex
					&& !checkIfArcExists ( dg , stackPeekIndex , inputPeekIndex ) ) {
				
				return updateActionContainers(MoreTransition.RIGHTARC, gold.getTokenNode(inputPeekIndex).getHeadEdge().getLabelSet());
			} 
//			else if (planarConfig.getInput().size()>=2  && gold.getTokenNode(inputPeek2Index).getHead().getIndex() == stackPeekIndex
//					&& !checkIfArcExists ( dg , stackPeekIndex , inputPeek2Index ) )  {
//			
//				return updateActionContainers(MoreTransition.RIGHTNONPROJARC, gold.getTokenNode(inputPeek2Index).getHeadEdge().getLabelSet());	
//			
//			}
			
//			else if (!gold.getTokenNode(inputPeekIndex).hasRightDependent() && dg.getTokenNode(inputPeekIndex).hasHead()) {
//				System.out.println("---------SHIFTDUCEEEEEEEEE");
//				return updateActionContainers(MoreTransition.SHIFTDUCE, null);
//			}
			
			else if (gold.getTokenNode(inputPeekIndex).hasLeftDependent() &&
					gold.getTokenNode(inputPeekIndex).getLeftmostDependent().getIndex() < stackPeekIndex) {
				return updateActionContainers(MoreTransition.REDUCE, null);
			} 
			else if (gold.getTokenNode(inputPeekIndex).getHead().getIndex() < stackPeekIndex) {
				return updateActionContainers(MoreTransition.REDUCE, null);
			}
			else {
				return updateActionContainers(MoreTransition.SHIFT, null);
			}
				
		}
		
		private boolean checkIfArcExists ( DependencyStructure dg , int index1 , int index2 ) throws MaltChainedException
		{
			return dg.getTokenNode(index2).hasHead() && dg.getTokenNode(index2).getHead().getIndex() == index1;
		}
		
		public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {}
		
		public void terminate() throws MaltChainedException {}
	}

