package dk.silverbullet.telemed.questionnaire.node;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.*;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import com.google.gson.annotations.Expose;
import dk.silverbullet.telemed.questionnaire.MainQuestionnaire;
import dk.silverbullet.telemed.questionnaire.Questionnaire;
import dk.silverbullet.telemed.questionnaire.R;
import dk.silverbullet.telemed.questionnaire.element.*;
import dk.silverbullet.telemed.questionnaire.expression.Variable;
import dk.silverbullet.telemed.questionnaire.expression.VariableLinkFailedException;
import dk.silverbullet.telemed.utils.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class IONode extends Node {
private boolean enterCalled = false;
private boolean hideTopPanel;
private boolean hideBackButton;
private boolean hideMenuButton;
private static final String TAG = Util.getTag(IONode.class);
@Expose
private List<Element> elements = new ArrayList<Element>();
private Activity activity;
private View topPanel;
private LinearLayout outerLayout;
private LinearLayout innerLayout;
private LinearLayout headerLayout;
private FrameLayout menuFrame;
public IONode(Questionnaire questionnaire, String nodeName) {
super(questionnaire, nodeName);
}
public void addElement(Element element) {
if (null == elements) {
elements = new ArrayList<Element>();
}
elements.add(element);
}
public void clearElements() {
if (null != elements) {
elements.clear();
}
}
protected void hideMenuButton() {
hideMenuButton = true;
}
protected void hideBackButton() {
hideBackButton = true;
}
protected void showKeyboard(EditText editTextView) {
InputMethodManager imm = (InputMethodManager)questionnaire.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editTextView, InputMethodManager.SHOW_IMPLICIT);
}
protected void hideKeyboard(EditText editTextView) {
InputMethodManager imm = (InputMethodManager)questionnaire.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editTextView.getWindowToken(), 0);
}
@Override
public void enter() {
Log.d(TAG, "enter...");
if (enterCalled) {
Log.e(TAG, "Enter already called once!");
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
Log.e(TAG, stackTraceElement.toString());
}
}
createView();
if (!hideTopPanel) {
questionnaire.push(this);
}
if (questionnaire.isBackPressed()) {
questionnaire.goBack();
}
enterCalled = true;
}
protected void createView() {
if (elements == null || elements.isEmpty()) {
return;
}
activity = questionnaire.getActivity();
// Figure out how to do the layout...
// text, any*, list, any2*, [buttons] -> { _text_ } {any*} list {any2} {buttons}
// text1, text2, any*, [buttons] -> { _text_ } {tex2, any} {buttons}
boolean hasEditText = false;
EditTextElement lastEditTextElement = null;
StringBuffer sb = new StringBuffer();
for (Element e : elements) {
char ch;
if (e instanceof ButtonElement || e instanceof TwoButtonElement) {
ch = 'B';
} else if (e instanceof TextViewElement) {
ch = 'T';
} else if (e instanceof PatientMessageBubbleElement || e instanceof ClinicMessageBubbleElement) {
ch = 'M';
} else if (e instanceof ListViewElement) {
ch = 'L';
} else if (e instanceof HelpTextElement) {
ch = 'H';
} else {
if (e instanceof EditTextElement) {
hasEditText = true;
lastEditTextElement = (EditTextElement)e;
}
ch = 'Z';
}
sb.append(ch);
}
if (lastEditTextElement != null)
lastEditTextElement.setLastElement(true);
String types = sb.toString();
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (types.contains("L")) { // List/Menu
outerLayout = (LinearLayout) inflater.inflate(R.layout.menunode, null);
headerLayout = (LinearLayout) outerLayout.findViewById(R.id.header);
innerLayout = null;
menuFrame = (FrameLayout) outerLayout.findViewById(R.id.menu);
int first = 0;
int last = elements.size() - 1;
if (types.matches("T(T|L).*")) {
TextViewElement tve = (TextViewElement) elements.get(first++);
tve.setHeader(true);
headerLayout.addView(tve.getView());
}
for (int e = first; e <= last; e++) {
Element element = elements.get(e);
if (element instanceof ListViewElement) {
menuFrame.addView(element.getView());
} else {
outerLayout.addView(element.getView());
}
}
} else { // General form with text, fields, buttons, ...
outerLayout = (LinearLayout) inflater.inflate(R.layout.ionode, null);
LinearLayout headerLayout = (LinearLayout) outerLayout.findViewById(R.id.header);
innerLayout = (LinearLayout) outerLayout.findViewById(R.id.inner_ionode);
menuFrame = null;
int first = 0;
int last = elements.size() - 1;
if (types.matches("T(T|L).*")) {
TextViewElement tve = (TextViewElement) elements.get(first++);
tve.setHeader(true);
headerLayout.addView(tve.getView());
}
if (types.matches("[^B]+B")) {
last--;
}
for (int e = first; e <= last; e++) {
Element element = elements.get(e);
innerLayout.addView(element.getView());
}
if (types.matches("[^B]+B")) {
if (hasEditText) //to make buttons scroll with input fields when soft keyboard is visible:
innerLayout.addView(elements.get(++last).getView());
else
outerLayout.addView(elements.get(++last).getView());
}
}
linkTopPanel(outerLayout);
if (types.matches(".*M.*")) {
ViewTreeObserver vto = innerLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
innerLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
ScrollView scrollView = (ScrollView) outerLayout.findViewById(R.id.inner_ionode_scroll);
int target = innerLayout.getBottom();
if (target > 1500) {
scrollView.scrollTo(0, target);
} else {
ObjectAnimator animScrollToBottom = ObjectAnimator.ofInt(scrollView, "scrollY", target);
animScrollToBottom.setInterpolator(new AccelerateDecelerateInterpolator());
animScrollToBottom.setDuration(2000);
animScrollToBottom.start();
}
}
});
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
questionnaire.getRootLayout().removeAllViews();
questionnaire.getRootLayout().addView(outerLayout);
}
});
}
protected void linkTopPanel(View topBarParent) {
topPanel = topBarParent.findViewById(R.id.top_panel);
if (hideTopPanel) {
topPanel.setVisibility(View.GONE);
} else {
TextView userId = (TextView) topBarParent.findViewById(R.id.user_id);
userId.setText(questionnaire.getFullName());
final Button back = (Button) topBarParent.findViewById(R.id.back);
final Button menu = (Button) topBarParent.findViewById(R.id.main_menu);
if (hideBackButton) {
back.setVisibility(View.GONE);
} else {
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (enterCalled) {
IONode.this.getQuestionnaire().back();
}
}
});
}
if (hideMenuButton) {
menu.setVisibility(View.GONE);
} else {
menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (enterCalled) {
IONode.this.getQuestionnaire().setCurrentNode(MainQuestionnaire.getInstance().getMainMenu());
}
}
});
}
Button logout = (Button) topBarParent.findViewById(R.id.logout);
logout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
logOut();
}
});
}
}
public void logOut() {
getQuestionnaire().logout();
}
@Override
public void leave() {
Log.d(TAG, "leave..");
if (!enterCalled) {
Log.e(TAG, "Enter was not called!");
}
enterCalled = false;
if (null != elements && !elements.isEmpty()) {
for (Element element : elements) {
element.leave();
}
}
removeViews();
}
private void removeViews() {
if (activity == null) {
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (headerLayout != null) {
headerLayout.removeAllViews();
headerLayout = null;
}
if (innerLayout != null) {
innerLayout.removeAllViews();
innerLayout = null;
}
if (menuFrame != null) {
menuFrame.removeAllViews();
menuFrame = null;
}
if (outerLayout != null) {
outerLayout.removeAllViews();
outerLayout = null;
}
for (Element element : elements) {
View view = element.getView();
ViewParent parent = view.getParent();
if (parent != null && parent instanceof ViewGroup) {
((ViewGroup) parent).removeView(view);
}
}
}
});
}
@Override
public void linkNodes(Map<String, Node> map) throws UnknownNodeException {
if (null != elements && !elements.isEmpty()) {
for (Element element : elements) {
element.linkNodes(map);
element.setNode(this);
}
}
}
@Override
public void linkVariables(Map<String, Variable<?>> map) throws VariableLinkFailedException {
if (null != elements && !elements.isEmpty()) {
for (Element element : elements) {
element.linkVariables(map);
}
}
}
public boolean validates() {
boolean result = true;
for (Element element : elements) {
result &= element.validates();
}
return result;
}
public void setHideBackButton(boolean hideBackButton) {
this.hideBackButton = hideBackButton;
}
public void setHideTopPanel(boolean hideTopPanel) {
this.hideTopPanel = hideTopPanel;
}
public void setHideMenuButton(boolean hideMenuButton) {
this.hideMenuButton = hideMenuButton;
}
}