package br.eti.rslemos.ad;

import java.util.Arrays;
import java.util.Iterator;

public abstract class Node {

	private final ADCorpus corpus;

	private final String function;
	private final String form;
	private final Info info;
	protected final int depth;

	Node(ADCorpus corpus) {
		this.corpus = corpus;
		
		String line = corpus.line;
		
		int i = 0;
		while(line.charAt(i++) == '=');
		depth = i-1;
		
		line = line.substring(depth);
		
		String[] parts;

		if (line.contains(":")) {
			// X:n("consolação" <act> F S)	Consolação
			parts = line.split(":");
			
			assert parts[0].length() > 0;
			function = parts[0];
			
			line = line.substring((function + ":").length());
			parts = line.split("[(\t]");
			
			assert parts[0].length() > 0;
			form = parts[0];
			
			line = line.substring(form.length());
			if (line.length() > 0 && line.charAt(0) == '(') {
				String info_chunk = line.substring(1, line.indexOf(')'));
				if ("n".equals(form))
					info = new Info_n(info_chunk);
				else if("pron-indef".equals(form))
					info = new Info_pron_indef(info_chunk);
				else if("prp".equals(form))
					info = new Info_prp(info_chunk);
				else if("prop".equals(form))
					info = new Info_prop(info_chunk);
				else
					throw new RuntimeException();
			} else
				info = null;
		} else {
			function = null;
			form = null;
			info = null;
		}
	}

	public String getFunction() {
		return function;
	}

	public String getForm() {
		return form;
	}

	public Info getInfo() {
		return info;
	}

	public int getDepth() {
		return depth;
	}

	public Iterator<Node> getChildren() {
		return new Iterator<Node>() {

			public boolean hasNext() {
				String prefix = buildDepthPrefix(depth + 1);
				return corpus.line.startsWith(prefix);
			}

			public Node next() {
				Node subNode;
				if (corpus.line.contains("\t") || !corpus.line.contains(":"))
					subNode = new TerminalNode(corpus);
				else
					subNode = new NonTerminalNode(corpus);

				return subNode;
			}

			public void remove() {
			}
		};
	}

	private static String buildDepthPrefix(int length) {
		char[] prefixChars = new char[length];
		Arrays.fill(prefixChars, '=');
		
		return new String(prefixChars).intern();
	}

}

@@ -108,41 +108,8 @@
  %7B%0A%0A
-%09private final ADCorpus corpus;%0A%0A
 %09pri
@@ -224,58 +224,72 @@
 ;%0A%0A%09
-Node(ADCorpus corpus) %7B%0A%09%09this.corpus = corpus;%0A%09%09
+private Iterator%3CNode%3E children;%0A%0A%09Node(final ADCorpus corpus) %7B
 %0A%09%09S
@@ -1334,302 +1334,165 @@
 %09%09%7D%0A
-%09%7D%0A%0A%09public String getFunction() %7B%0A%09%09return function;%0A%09%7D%0A%0A%09public String getForm() %7B%0A%09%09return form;%0A%09%7D%0A%0A%09public Info getInfo() %7B%0A%09%09return info;%0A%09%7D%0A%0A%09public int getDepth() %7B%0A%09%09return depth;%0A%09%7D%0A%0A%09public Iterator%3CNode%3E getChildren() %7B%0A%09%09return new Iterator%3CNode%3E() %7B%0A%0A%09%09%09public boolean hasNext() %7B
+%0A%09%09children = new Iterator%3CNode%3E() %7B%0A%09%09%09private ADCorpus corpus0 = corpus;%0A%09%09%09%0A%09%09%09public boolean hasNext() %7B%0A%09%09%09%09if (corpus0 == null)%0A%09%09%09%09%09return false;%0A%09%09%09%09
 %0A%09%09%09
@@ -1545,21 +1545,19 @@
 %09%09%09%09
-return 
+if (
 corpus
+0
 .lin
@@ -1576,17 +1576,102 @@
 (prefix)
-;
+) %7B%0A%09%09%09%09%09return true;%0A%09%09%09%09%7D else %7B%0A%09%09%09%09%09corpus0 = null;%0A%09%09%09%09%09%0A%09%09%09%09%09return false;%0A%09%09%09%09%7D
 %0A%09%09%09%7D%0A%0A%09
@@ -1721,24 +1721,25 @@
 %09%09if (corpus
+0
 .line.contai
@@ -1753,24 +1753,25 @@
 ) %7C%7C !corpus
+0
 .line.contai
@@ -1817,16 +1817,17 @@
 e(corpus
+0
 );%0A%09%09%09%09e
@@ -1871,16 +1871,17 @@
 e(corpus
+0
 );%0A%0A%09%09%09%09
@@ -1942,16 +1942,267 @@
 %09%7D;%0A%09%7D%0A%0A
+%09public String getFunction() %7B%0A%09%09return function;%0A%09%7D%0A%0A%09public String getForm() %7B%0A%09%09return form;%0A%09%7D%0A%0A%09public Info getInfo() %7B%0A%09%09return info;%0A%09%7D%0A%0A%09public int getDepth() %7B%0A%09%09return depth;%0A%09%7D%0A%0A%09public Iterator%3CNode%3E getChildren() %7B%0A%09%09return children;%0A%09%7D%0A%0A
 %09private

parser de árvores deitadas: nós filhos