package gueei.binding.converters;
import gueei.binding.AttributeInjector;
import gueei.binding.AttributeInjector.InjectParams;
import gueei.binding.Binder.InflateResult;
import gueei.binding.Converter;
import gueei.binding.DynamicObject;
import gueei.binding.IObservable;
import gueei.binding.viewAttributes.templates.Layout;
import java.util.ArrayList;
/**
* INJECT binding statements into layout templates. <br/>
* Most probably those templates came from external libraries (e.g. android) that you cannot change <br/>
* This is much more convenient than everytime you need to copy those standard templates. <br/>
* <br/>
*
* The most common usage is on those templates for spinners, listviews (e.g. @android:layout/simple_list_item1). <br/>
* Suppose We need to inject the statement to the textview (@android:id/textview1), then: <br/>
* binding:itemTemplate="INJECT(@android:layout/simple_list_item1, { id=@android:id/textview1, attr='text', statement='Name' })" <br/>
* Note it is possible to inject more than one attribute, for example you can change the color of the above mentioned text view too: <br/>
* binding:itemTemplate="INJECT(@android:layout/simple_list_item1, { id=@android:id/textview1, attr='text', statement='Name' }, { id=@android:id/textview1, attr='backgroundColor', statement='ARGB(255,0,0)' })" <br/>
* @usage layout params ...
*
* @arg layout gueei.binding.viewAttributes.templates.Layout Layout of the template-to-inject
* @arg params DynamicObject
*
* @item id integer Android Id value of the widget
* @item attr Attribute name of that widget
* @item statement Binding Statement to be injected
*
* @return gueei.binding.viewAttributes.templates.Layout
*/
public class INJECT extends Converter<Layout> {
public INJECT(IObservable<?>[] dependents) {
super(Layout.class, dependents);
}
@Override
public Layout calculateValue(Object... args) throws Exception {
if (args.length<1 || !(args[0] instanceof Layout)) return null;
if (args.length<2) return (Layout)args[0];
return new InjectLayout((Layout)args[0], process(args));
}
private static InjectParams[] process(Object[] args){
ArrayList<InjectParams> injectParams = new ArrayList<InjectParams>();
int len = args.length;
if (args.length<2) return new InjectParams[0];
for(int i=1; i<len; i++){
if (!(args[i] instanceof DynamicObject)) continue;
try{
DynamicObject p = (DynamicObject)args[i];
InjectParams param = new InjectParams();
param.Id = (Integer)p.getObservableByName("id").get();
param.AttrName = p.getObservableByName("attr").get().toString();
param.Statement = p.getObservableByName("statement").get().toString();
injectParams.add(param);
}catch(Exception e){ continue; }
}
return injectParams.toArray(new InjectParams[0]);
}
public static class InjectLayout extends Layout{
private final Layout mLayout;
private final InjectParams[] mParams;
@Override
public void onAfterInflate(InflateResult result, int position) {
super.onAfterInflate(result, position);
AttributeInjector.inject(mParams, result);
}
public InjectLayout(Layout layout, InjectParams[] params) {
super(layout.getDefaultLayoutId());
mLayout = layout;
mParams = params;
}
@Override
public int getLayoutTypeId(int pos) {
return mLayout.getLayoutTypeId(pos);
}
@Override
public int getLayoutId(int pos) {
return mLayout.getLayoutId(pos);
}
@Override
public int getTemplateCount() {
return mLayout.getTemplateCount();
}
}
}