package org.commcare.views.widgets;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.commcare.activities.components.FormEntryConstants;
import org.commcare.android.javarosa.IntentCallout;
import org.commcare.logic.PendingCalloutInterface;
import org.commcare.utils.CompoundIntentList;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.form.api.FormEntryPrompt;
/**
* Widget that allows user to scan barcodes and add them to the form.
*
* @author Yaw Anokwa (yanokwa@gmail.com)
*/
public class IntentWidget extends QuestionWidget {
protected final TextView mStringAnswer;
private final Intent intent;
private final String getButtonLocalizationKey;
private final String updateButtonLocalizationKey;
protected final Button launchIntentButton;
protected final PendingCalloutInterface pendingCalloutInterface;
protected final IntentCallout ic;
protected final String missingCalloutKey;
protected final boolean isEditable;
public IntentWidget(Context context, FormEntryPrompt prompt,
Intent in, IntentCallout ic, PendingCalloutInterface pendingCalloutInterface) {
this(context, prompt, in, ic, pendingCalloutInterface,
"intent.callout.get", "intent.callout.update", "intent.callout.activity.missing",
false);
}
protected IntentWidget(Context context, FormEntryPrompt prompt, Intent in, IntentCallout ic,
PendingCalloutInterface pendingCalloutInterface,
String getButtonLocalizationKey, String updateButtonLocalizationKey,
String missingCalloutKey, boolean isEditable) {
super(context, prompt);
this.missingCalloutKey = missingCalloutKey;
this.intent = in;
this.ic = ic;
this.pendingCalloutInterface = pendingCalloutInterface;
this.getButtonLocalizationKey = getButtonLocalizationKey;
this.updateButtonLocalizationKey = updateButtonLocalizationKey;
this.isEditable = isEditable;
if (isEditable) {
mStringAnswer = new EditText(getContext());
} else {
mStringAnswer = new TextView(getContext());
}
launchIntentButton = new Button(getContext());
setupTextView();
setupButton();
}
protected void setupTextView() {
mStringAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontSize);
mStringAnswer.setGravity(Gravity.CENTER);
String s = mPrompt.getAnswerText();
if (s != null) {
mStringAnswer.setText(s);
}
addView(mStringAnswer);
//only auto advance if 1) we have no data 2) its quick 3) we weren't just cancelled
if (s == null
&& "quick".equals(ic.getAppearance())
&& !pendingCalloutInterface.wasCalloutPendingAndCancelled(mPrompt.getIndex())) {
performCallout();
}
}
private void setupButton() {
setOrientation(LinearLayout.VERTICAL);
WidgetUtils.setupButton(launchIntentButton,
getButtonLabel(),
mAnswerFontSize,
!mPrompt.isReadOnly());
// launch barcode capture intent on click
launchIntentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
performCallout();
}
});
addView(launchIntentButton);
}
protected Spannable getButtonLabel() {
if (mStringAnswer.getText() == null || "".equals(mStringAnswer.getText().toString())) {
if (ic.getButtonLabel() != null) {
return new SpannableString(ic.getButtonLabel());
} else {
return new SpannableString(Localization.get(getButtonLocalizationKey));
}
} else {
if (ic.getUpdateButtonLabel() != null) {
return new SpannableString(ic.getUpdateButtonLabel());
} else {
return new SpannableString(Localization.get(updateButtonLocalizationKey));
}
}
}
private void performCallout() {
if (calloutIsSupportedOnDevice()) {
try {
loadCurrentAnswerToIntent();
((Activity) getContext()).startActivityForResult(intent, FormEntryConstants.INTENT_CALLOUT);
pendingCalloutInterface.setPendingCalloutFormIndex(mPrompt.getIndex());
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(),
Localization.get(missingCalloutKey), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(),
Localization.get("intent.callout.not.supported"), Toast.LENGTH_SHORT).show();
}
}
public boolean calloutIsSupportedOnDevice() {
return !(ic.isSimprintsCallout() && Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH);
}
protected void loadCurrentAnswerToIntent() {
String data = mStringAnswer.getText().toString();
if (!"".equals(data)) {
intent.putExtra(IntentCallout.INTENT_RESULT_VALUE, data);
}
}
private void setButtonLabel() {
launchIntentButton.setText(getButtonLabel());
}
@Override
public void clearAnswer() {
ic.processBarcodeResponse(mPrompt.getIndex().getReference(), null);
mStringAnswer.setText(null);
setButtonLabel();
}
@Override
public IAnswerData getAnswer() {
return mPrompt.getAnswerValue();
}
@Override
public void setFocus(Context context) {
// Hide the soft keyboard if it's showing.
InputMethodManager inputManager =
(InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
@Override
public void setOnLongClickListener(OnLongClickListener l) {
mStringAnswer.setOnLongClickListener(l);
launchIntentButton.setOnLongClickListener(l);
}
@Override
public void unsetListeners() {
super.unsetListeners();
mStringAnswer.setOnLongClickListener(null);
launchIntentButton.setOnLongClickListener(null);
}
@Override
public void cancelLongPress() {
super.cancelLongPress();
launchIntentButton.cancelLongPress();
mStringAnswer.cancelLongPress();
}
public IntentCallout getIntentCallout() {
//TODO: This is really not great, but the alternative
//is doubling up all of this code in the ODKView, which
//is silly. It's not generalizable
return ic;
}
public CompoundIntentList addToCompoundIntent(CompoundIntentList compoundedCallout) {
if (!intent.getBooleanExtra(IntentCallout.INTENT_EXTRA_CAN_AGGREGATE, false)) {
return compoundedCallout;
}
if (compoundedCallout == null) {
CompoundIntentList list = new CompoundIntentList(intent, this.getFormId().toString());
list.setTitle(this.getButtonLabel().toString());
return list;
}
if (!compoundedCallout.addIntentIfCompatible(intent, this.getFormId().toString())) {
return null;
} else {
return compoundedCallout;
}
}
}