/**
 * 
 */
package org.commcare.android.models;

import java.util.Enumeration;
import java.util.Hashtable;

import org.commcare.android.database.user.models.User;
import org.commcare.android.util.SessionUnavailableException;
import org.commcare.suite.model.Detail;
import org.commcare.suite.model.DetailField;
import org.commcare.suite.model.Text;
import org.javarosa.core.model.condition.EvaluationContext;
import org.javarosa.core.model.instance.FormInstance;
import org.javarosa.core.model.instance.TreeReference;
import org.javarosa.xpath.XPathException;
import org.javarosa.xpath.XPathParseTool;
import org.javarosa.xpath.expr.XPathExpression;
import org.javarosa.xpath.expr.XPathFuncExpr;
import org.javarosa.xpath.parser.XPathSyntaxException;

/**
 * @author ctsims
 *
 */
public class NodeEntityFactory {

	private EvaluationContext ec;
	
	Detail detail;
	FormInstance instance;
	User current; 
	
	public Detail getDetail() {
		return detail;
	}

	
	public NodeEntityFactory(Detail d, EvaluationContext ec) {
		this.detail = d;
		this.ec = ec;
	}

	public Entity<TreeReference> getEntity(TreeReference data) throws SessionUnavailableException {
		EvaluationContext nodeContext = new EvaluationContext(ec, data);
		Hashtable<String, XPathExpression> variables = getDetail().getVariableDeclarations();
		//These are actually in an ordered hashtable, so we can't just get the keyset, since it's
		//in a 1.3 hashtable equivilant
		for(Enumeration<String> en = variables.keys(); en.hasMoreElements();) {
			String key = en.nextElement();
			nodeContext.setVariable(key, XPathFuncExpr.unpack(variables.get(key).eval(nodeContext)));
		}
		
		//return new AsyncEntity<TreeReference>(detail.getFields(), nodeContext, data);
		
		int length = detail.getHeaderForms().length;
		String[] details = new String[length];
		String[] sortDetails = new String[length];
		boolean[] relevancyDetails = new boolean[length];
		int count = 0;
		for(DetailField f : this.getDetail().getFields()) {
			try {
				details[count] = f.getTemplate().evaluate(nodeContext);
				Text sortText = f.getSort();
				if(sortText == null) {
					sortDetails[count] = details[count];
				} else {
					sortDetails[count] = sortText.evaluate(nodeContext);
				}
				String relevancy = f.getRelevancy();
				boolean isRelevant = true;
				if (relevancy != null) {
					try {
						XPathExpression parsed = XPathParseTool.parseXPath(relevancy);
						isRelevant = XPathFuncExpr.toBoolean(parsed.eval(nodeContext)).booleanValue();
					} catch (XPathSyntaxException e) {
						e.printStackTrace();
					}
				}
				relevancyDetails[count] = isRelevant;
			} catch(XPathException xpe) {
				xpe.printStackTrace();
				details[count] = "<invalid xpath: " + xpe.getMessage() + ">";
			}
			count++;
		}
		
		return new Entity<TreeReference>(details, sortDetails, relevancyDetails, data);
	}
}

@@ -574,51 +574,8 @@
 n;%0D%0A
-import org.javarosa.xpath.XPathParseTool;%0D%0A
 impo
@@ -2256,23 +2256,16 @@
 %09%7D%0D%0A%09%09%09%09
-String 
 relevanc
@@ -2269,262 +2269,53 @@
 ancy
- = f.getRelevancy();%0D%0A%09%09%09%09boolean isRelevant = true;%0D%0A%09%09%09%09if (relevancy != null) %7B%0D%0A%09%09%09%09%09try %7B%0D%0A%09%09%09%09%09%09XPathExpression parsed = XPathParseTool.parseXPath(relevancy);%0D%0A%09%09%09%09%09%09isRelevant = XPathFuncExpr.toBoolean(parsed.eval(nodeContext)).booleanValue(
+Details%5Bcount%5D = f.isRelevant(nodeContext
 );%0D%0A
-%09%09
 %09%09%09%7D
@@ -2324,21 +2324,14 @@
 atch
- 
 (XPath
-Syntax
 Exce
@@ -2336,16 +2336,18 @@
 ception 
+xp
 e) %7B%0D%0A%09%09
@@ -2348,18 +2348,18 @@
  %7B%0D%0A%09%09%09%09
-%09%09
+xp
 e.printS
@@ -2380,59 +2380,68 @@
 %09%09%09%09
-%09%7D%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%09relevancyDetails%5Bcount%5D = isRelevant
+details%5Bcount%5D = %22%3Cinvalid xpath: %22 + xpe.getMessage() + %22%3E%22
 ;%0D%0A%09
@@ -2441,38 +2441,45 @@
 %22%3E%22;%0D%0A%09%09%09%7D catch
+ 
 (XPath
+Syntax
 Exception xpe) %7B
@@ -2464,34 +2464,32 @@
 SyntaxException 
-xp
 e) %7B%0D%0A%09%09%09%09xpe.pr
@@ -2474,34 +2474,32 @@
 ption e) %7B%0D%0A%09%09%09%09
-xp
 e.printStackTrac
@@ -2508,75 +2508,8 @@
 );%0D%0A
-%09%09%09%09details%5Bcount%5D = %22%3Cinvalid xpath: %22 + xpe.getMessage() + %22%3E%22;%0D%0A
 %09%09%09%7D

Move parsing into DetailField