package org.kvj.lima1.android.ui.manager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
import org.kvj.lima1.android.ui.page.Renderer;
import org.kvj.lima1.sync.PJSONObject;
import android.util.Log;
import android.view.ViewGroup;
public class UIManager {
public static interface UIManagerDataProvider {
public JSONObject findTemplate(long id);
public PJSONObject[] getTemplates();
public PJSONObject[] getNotes(String sheetID);
}
private static final String TAG = "UIManager";
private static final String VALUE_PATTERN = "([a-zA-Z0-9\\s\\(\\)\\+\\-\\_/\\:\\.]*)";
Map<String, PageProtocol> protocols = new HashMap<String, PageProtocol>();
// Map<String, JSONObject> templates = new LinkedHashMap<String,
// JSONObject>();
ViewGroup root = null;
UIManagerDataProvider provider = null;
PJSONObject[] notes = null;
boolean showArchived = false;
EditorInfo editorInfo = null;
Pattern injectPattern = Pattern.compile("\\$\\{([a-z\\@]+)\\:"
+ VALUE_PATTERN + "\\}");
Pattern replacePattern = Pattern.compile("^([a-z\\@]+)\\:" + VALUE_PATTERN
+ "$");
Pattern linkPattern = Pattern.compile("^([a-z\\@]+)\\:" + VALUE_PATTERN
+ "$");
private Renderer renderer = null;
public UIManager(ViewGroup root, UIManagerDataProvider provider) {
this.root = root;
this.provider = provider;
protocols.put("@", new ItemProtocol());
protocols.put("dt", new DateProtocol());
}
public String inject(String text, JSONObject item) {
Matcher matcher = injectPattern.matcher(text);
StringBuffer result = new StringBuffer();
// Log.i(TAG, "Injecting "+text+", "+item);
while (matcher.find()) {
PageProtocol p = protocols.get(matcher.group(1));
// Log.i(TAG,
// "Found protocol: "+matcher.group(1)+", "+matcher.group(2)+", "+p);
if (null != p) {
String value = p.convert(matcher.group(2), item);
matcher.appendReplacement(result, value);
}
}
matcher.appendTail(result);
return result.toString();
}
public String replace(String text, JSONObject item) {
Matcher matcher = replacePattern.matcher(text);
StringBuffer result = new StringBuffer();
// Log.i(TAG, "Replacing "+text+" to "+item);
while (matcher.find()) {
// Log.i(TAG,
// "Found protocol: "+matcher.group(1)+", "+matcher.group(2));
PageProtocol p = protocols.get(matcher.group(1));
if (null != p) {
String value = p.convert(matcher.group(2), item);
matcher.appendReplacement(result, value);
}
}
matcher.appendTail(result);
return result.toString();
}
protected void render(JSONObject template, JSONObject sheet, int place)
throws JSONException {
notes = null;
renderer = new Renderer(null, this, root, template, sheet);
renderer.render();
}
public boolean showPage(JSONObject sheet) {
return showPage(sheet.optLong("template_id"), sheet);
}
public boolean showPage(long templateID, JSONObject sheet) {
JSONObject template = provider.findTemplate(templateID);
if (null == template) {
showError("No template found");
return false;
}
try {
sheet.put("template_id", template);
JSONObject config = new JSONObject();
JSONObject protocol = template.optJSONObject("protocol");
if (null != protocol && sheet.has("code")) {
Iterator<String> it = protocol.keys();
while (it.hasNext()) {
PageProtocol p = protocols.get(it.next());
if (null != p) {
p.prepare(sheet, sheet.optString("code"));
}
}
}
render(template, sheet, 0);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public boolean openSheetByCode(JSONObject object) {
JSONObject empty = new JSONObject();
try {
empty.put("code", object.optString("code"));
return showPage(object.optLong("template_id"), empty);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void showError(String message) {
Log.e(TAG, "UI error: " + message);
}
public boolean openLink(String link, String place) throws JSONException {
Log.i(TAG, "Open link: " + link);
Matcher matcher = linkPattern.matcher(link);
List<JSONObject> templatesFound = new ArrayList<JSONObject>();
if (matcher.find()) {
String name = matcher.group(1);
PageProtocol p = protocols.get(name);
if (null == p) {
Log.w(TAG, "Unsupported tag: " + name);
return false;
}
for (JSONObject tmpl : provider.getTemplates()) {
JSONObject protocols = tmpl.optJSONObject("protocol");
// Log.i(TAG, "Template have protocol: "+protocols);
if (null != protocols && protocols.has(name)
&& tmpl.has("code")) {
JSONObject config = p.accept(protocols.optJSONObject(name),
matcher.group(2));
// Log.i(TAG, "Got config: "+config);
if (null == config) {
continue;
}
String code = inject(tmpl.optString("code"), config);
// Log.i(TAG, "Code: "+code);
if (null != code) {
JSONObject obj = new JSONObject();
obj.put("code", code);
obj.put("template_id", tmpl.optLong("id"));
templatesFound.add(obj);
}
}
}
}
Log.i(TAG, "Templates found: " + templatesFound.size());
if (1 == templatesFound.size()) {
return openSheetByCode(templatesFound.get(0));
}
return false;
}
public List<JSONObject> getNotes(String sheetID, String area) {
if (null == notes) {
notes = provider.getNotes(sheetID);
}
List<JSONObject> result = new ArrayList<JSONObject>();
for (int i = 0; i < notes.length; i++) {
JSONObject note = notes[i];
if (null != area && area.equals(note.optString("area"))) {
if (!showArchived && 1 == note.optInt("done")) {
continue;
}
result.add(note);
}
}
return result;
}
public void toggleArchived() {
showArchived = !showArchived;
redraw();
}
public void textEditorFocus(boolean hasFocus, EditorInfo info) {
if (hasFocus) {
editorInfo = info;
} else {
editorInfo = null;
}
}
public EditorInfo getEditorInfo() {
return editorInfo;
}
public void redraw() {
if (null != renderer) {
try {
renderer.render();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}