package de.stefanocke.japkit.roo.japkit;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import de.stefanocke.japkit.metaannotations.Case;
import de.stefanocke.japkit.metaannotations.Constructor;
import de.stefanocke.japkit.metaannotations.InnerClass;
import de.stefanocke.japkit.metaannotations.Matcher;
import de.stefanocke.japkit.metaannotations.TypeCategory;
import de.stefanocke.japkit.metaannotations.Var;
import de.stefanocke.japkit.metaannotations.Method;
import de.stefanocke.japkit.metaannotations.Properties;
import de.stefanocke.japkit.metaannotations.Template;
import de.stefanocke.japkit.metaannotations.classselectors.GeneratedClass;

@Template(vars = @Var(name = "toStringProperties", propertyFilter = @Properties(sourceClass = GeneratedClass.class)))
public abstract class ToString {
	@Method(imports = { ToStringBuilder.class, ToStringStyle.class },
			
			bodyIterator="#{toStringProperties}",
			//bodyIteratorVar="p"
			bodyBeforeExpr = "return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).\n",
			
			bodySwitch={
				//Only summary for collections
				@Case(matcher=@Matcher(srcTypeCategory=TypeCategory.COLLECTION), 
						expr = "append(\"#{element.simpleName}\", #{element.getter.simpleName}(), false).\n"),
			},
			bodyExpr = "append(\"#{element.simpleName}\", #{element.getter.simpleName}()).\n",
			bodyAfterExpr = "toString();\n",
			bodyEmptyExpr = "return super.toString();" 
			)
	public abstract String toString();
	
//	@Constructor(bodyExpr="//Some ctor code")
//	public ToString (){};
	
	//TODO: Take name from class if no nameExpr is given...  
	//TODO: Consider the inner class as a template for them members of the inner class to be generated.
	//TODO: rule src element for name expression should not always be the annotated class.
//	@InnerClass(iterator="#{toStringProperties}", nameExpr="#{parent.element.simpleName.toFirstUpper}InnerClassTest")
//	static class InnerClassTest{
//		@Method
//		void foo(){}
//	}
}

@@ -246,234 +246,14 @@
 ons.
-Constructor;%0Aimport de.stefanocke.japkit.metaannotations.InnerClass;%0Aimport de.stefanocke.japkit.metaannotations.Matcher;%0Aimport de.stefanocke.japkit.metaannotations.TypeCategory;%0Aimport de.stefanocke.japkit.metaannotations.Va
+Matche
 r;%0Ai
@@ -413,16 +413,123 @@
 mplate;%0A
+import de.stefanocke.japkit.metaannotations.TypeCategory;%0Aimport de.stefanocke.japkit.metaannotations.Var;%0A
 import d
@@ -992,14 +992,13 @@
 body
-Switch
+Cases
 =%7B%0A%09
@@ -1414,511 +1414,8 @@
 ();%0A
+
 %09%0A
-//%09@Constructor(bodyExpr=%22//Some ctor code%22)%0A//%09public ToString ()%7B%7D;%0A%09%0A%09//TODO: Take name from class if no nameExpr is given...  %0A%09//TODO: Consider the inner class as a template for them members of the inner class to be generated.%0A%09//TODO: rule src element for name expression should not always be the annotated class.%0A//%09@InnerClass(iterator=%22#%7BtoStringProperties%7D%22, nameExpr=%22#%7Bparent.element.simpleName.toFirstUpper%7DInnerClassTest%22)%0A//%09static class InnerClassTest%7B%0A//%09%09@Method%0A//%09%09void foo()%7B%7D%0A//%09%7D%0A
 %7D%0A

Fix for: renamed bodySwitch to bodyCases to avoid conflict with keyword