package org.commcare.activities;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Pair;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import org.commcare.CommCareApplication;
import org.commcare.dalvik.R;
import org.commcare.google.services.ads.AdLocation;
import org.commcare.google.services.ads.AdMobManager;
import org.commcare.google.services.analytics.GoogleAnalyticsUtils;
import org.commcare.logic.DetailCalloutListenerDefaultImpl;
import org.commcare.models.AndroidSessionWrapper;
import org.commcare.preferences.DeveloperPreferences;
import org.commcare.print.PrintableDetailField;
import org.commcare.print.TemplatePrinterActivity;
import org.commcare.session.CommCareSession;
import org.commcare.session.SessionFrame;
import org.commcare.suite.model.CalloutData;
import org.commcare.suite.model.Detail;
import org.commcare.util.DetailFieldPrintInfo;
import org.commcare.utils.DetailCalloutListener;
import org.commcare.utils.SerializationUtil;
import org.commcare.utils.SessionStateUninitException;
import org.commcare.views.ManagedUi;
import org.commcare.views.TabbedDetailView;
import org.commcare.views.UiElement;
import org.javarosa.core.model.instance.TreeReference;
import org.javarosa.core.services.locale.Localization;
import java.util.HashMap;
/**
* @author ctsims
*/
@ManagedUi(R.layout.entity_detail)
public class EntityDetailActivity
extends SessionAwareCommCareActivity
implements DetailCalloutListener {
// reference id of selected element being detailed
public static final String CONTEXT_REFERENCE = "eda_crid";
public static final String DETAIL_ID = "eda_detail_id";
public static final String DETAIL_PERSISTENT_ID = "eda_persistent_id";
private static final int MENU_PRINT_DETAIL = Menu.FIRST;
private static final int PRINT_DETAIL = 1;
private Detail detail;
private Pair<Detail, TreeReference> mEntityContext;
private TreeReference mTreeReference;
private int detailIndex;
private AndroidSessionWrapper asw;
// controls whether swiping can toggle exit from case detail screen
private boolean isFinalSwipeActionEnabled = false;
@UiElement(value = R.id.entity_detail)
private RelativeLayout container;
@UiElement(value = R.id.entity_select_button, locale = "select.detail.confirm")
private Button next;
@UiElement(value = R.id.entity_detail_tabs)
private TabbedDetailView mDetailView;
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent i = getIntent();
CommCareSession session;
try {
asw = CommCareApplication.instance().getCurrentSessionWrapper();
session = asw.getSession();
} catch (SessionStateUninitException sue) {
// The user isn't logged in! bounce this back to where we came from
this.setResult(RESULT_CANCELED, this.getIntent());
this.finish();
return;
}
String passedCommand = getIntent().getStringExtra(SessionFrame.STATE_COMMAND_ID);
// Is the detail screen for showing entities, without option for moving
// forward on to form manipulation?
boolean viewMode;
if (passedCommand != null) {
viewMode = session.isViewCommand(passedCommand);
} else {
viewMode = session.isViewCommand(session.getCommand());
}
detail = session.getDetail(getIntent().getStringExtra(EntityDetailActivity.DETAIL_ID));
mTreeReference =
SerializationUtil.deserializeFromIntent(getIntent(),
EntityDetailActivity.CONTEXT_REFERENCE,
TreeReference.class);
String shortDetailId = getIntent().getStringExtra(EntityDetailActivity.DETAIL_PERSISTENT_ID);
if (shortDetailId != null) {
Detail shortDetail = session.getDetail(shortDetailId);
this.mEntityContext = new Pair<>(shortDetail, mTreeReference);
}
super.onCreate(savedInstanceState);
/* Caution: The detailIndex field comes from EntitySelectActivity, which is the
* source of this intent. In some instances, the detailIndex may not have been assigned,
* in which case it will take on a value of -1. If making use of the detailIndex, it may
* be useful to include the debugging print statement below.
*/
this.detailIndex = i.getIntExtra("entity_detail_index", -1);
if (this.getString(R.string.panes).equals("two")) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
//this occurs when the screen was rotated to be vertical on the select activity. We
//want to navigate back to that screen now.
this.setResult(RESULT_CANCELED, this.getIntent());
this.finish();
return;
}
}
next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportEntityDetailContinue(false, mDetailView.getTabCount() == 1);
select();
}
});
if (viewMode) {
next.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
next.setText(Localization.get("select.detail.bypass"));
}
mDetailView.setRoot((ViewGroup)container.findViewById(R.id.entity_detail_tabs));
mDetailView.refresh(detail, mTreeReference, detailIndex);
mDetailView.showMenu();
isFinalSwipeActionEnabled = DeveloperPreferences.isDetailTabSwipeActionEnabled();
AdMobManager.requestBannerAdForView(this, (FrameLayout)this.findViewById(R.id.ad_container),
AdLocation.EntityDetail);
}
@Override
public Pair<Detail, TreeReference> requestEntityContext() {
return mEntityContext;
}
@Override
protected boolean isTopNavEnabled() {
return true;
}
@Override
public String getActivityTitle() {
return null;
}
private void loadOutgoingIntent(Intent i) {
i.putExtra(SessionFrame.STATE_DATUM_VAL, this.getIntent().getStringExtra(SessionFrame.STATE_DATUM_VAL));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case DetailCalloutListenerDefaultImpl.CALL_OUT:
if (resultCode == RESULT_CANCELED) {
mDetailView.refresh(detail, mTreeReference, detailIndex);
return;
} else {
long duration = intent.getLongExtra(CallOutActivity.CALL_DURATION, 0);
Intent i = new Intent(EntityDetailActivity.this.getIntent());
loadOutgoingIntent(i);
i.putExtra(CallOutActivity.CALL_DURATION, duration);
setResult(RESULT_OK, i);
finish();
return;
}
default:
super.onActivityResult(requestCode, resultCode, intent);
}
}
@Override
public void callRequested(String phoneNumber) {
DetailCalloutListenerDefaultImpl.callRequested(this, phoneNumber);
}
@Override
public void addressRequested(String address) {
DetailCalloutListenerDefaultImpl.addressRequested(this, address);
}
@Override
public void playVideo(String videoRef) {
DetailCalloutListenerDefaultImpl.playVideo(this, videoRef);
}
@Override
public void performCallout(CalloutData callout, int id) {
DetailCalloutListenerDefaultImpl.performCallout(this, callout, id);
}
@Override
protected boolean onForwardSwipe() {
// Move along, provided we're on the last tab of tabbed case details
if (isFinalSwipeActionEnabled &&
mDetailView.getCurrentTab() >= mDetailView.getTabCount() - 1) {
select();
GoogleAnalyticsUtils.reportEntityDetailContinue(true, mDetailView.getTabCount() == 1);
return true;
}
return false;
}
@Override
protected boolean onBackwardSwipe() {
// Move back, provided we're on the first screen of tabbed case details
if (isFinalSwipeActionEnabled &&
mDetailView.getCurrentTab() < 1) {
finish();
GoogleAnalyticsUtils.reportEntityDetailExit(true, mDetailView.getTabCount() == 1);
return true;
}
return false;
}
/**
* Move along to form entry.
*/
private void select() {
announceCaseSelect();
Intent i = new Intent(EntityDetailActivity.this.getIntent());
loadOutgoingIntent(i);
setResult(RESULT_OK, i);
finish();
}
private void announceCaseSelect() {
Intent selectIntentBroadcast = new Intent("org.commcare.dalvik.api.action.case.selected");
selectIntentBroadcast.putExtra("case_id", getIntent().getStringExtra(SessionFrame.STATE_DATUM_VAL));
sendBroadcast(selectIntentBroadcast, "org.commcare.dalvik.provider.cases.read");
}
@Override
public void onBackPressed() {
super.onBackPressed();
GoogleAnalyticsUtils.reportEntityDetailExit(false, mDetailView.getTabCount() == 1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_PRINT_DETAIL, 0, Localization.get("menu.print.detail"));
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(MENU_PRINT_DETAIL).setVisible(detail.isPrintEnabled());
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case MENU_PRINT_DETAIL:
printDetail();
return true;
}
return super.onOptionsItemSelected(item);
}
private void printDetail() {
Intent i = new Intent(this, TemplatePrinterActivity.class);
i.putExtra(TemplatePrinterActivity.PRINT_TEMPLATE_REF_STRING,
detail.getDerivedPrintTemplatePath());
HashMap<String, DetailFieldPrintInfo> keyValueMap =
detail.getKeyValueMapForPrint(mTreeReference, asw.getEvaluationContext());
for (String key : keyValueMap.keySet()) {
i.putExtra(key, new PrintableDetailField(keyValueMap.get(key)));
}
startActivityForResult(i, PRINT_DETAIL);
}
}