/*
* Copyright © 2016 TIBCO Software,Inc.All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-android
*
* Unless you have purchased a commercial license agreement from TIBCO Jaspersoft,
* the following license terms apply:
*
* This program is part of TIBCO Jaspersoft Mobile for Android.
*
* TIBCO Jaspersoft Mobile is free software:you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation,either version 3of the License,or
* (at your option)any later version.
*
* TIBCO Jaspersoft Mobile is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY;without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TIBCO Jaspersoft Mobile for Android.If not,see
* <http://www.gnu.org/licenses/lgpl>.
*/
package com.jaspersoft.android.jaspermobile.activities.viewer.html.report;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.jaspersoft.android.jaspermobile.R;
import com.jaspersoft.android.jaspermobile.activities.inputcontrols.InputControlsActivity;
import com.jaspersoft.android.jaspermobile.activities.inputcontrols.InputControlsActivity_;
import com.jaspersoft.android.jaspermobile.data.entity.mapper.ReportParamsMapper;
import com.jaspersoft.android.jaspermobile.dialog.NumberPickerDialogFragment;
import com.jaspersoft.android.jaspermobile.dialog.NumberDialogFragment;
import com.jaspersoft.android.jaspermobile.domain.ReportControlFlags;
import com.jaspersoft.android.jaspermobile.domain.SimpleSubscriber;
import com.jaspersoft.android.jaspermobile.domain.interactor.profile.AuthorizeSessionUseCase;
import com.jaspersoft.android.jaspermobile.domain.interactor.report.GetReportShowControlsPropertyCase;
import com.jaspersoft.android.jaspermobile.network.RequestExceptionHandler;
import com.jaspersoft.android.jaspermobile.ui.view.activity.CastActivity;
import com.jaspersoft.android.jaspermobile.util.ReportParamsStorage;
import com.jaspersoft.android.jaspermobile.util.cast.ResourcePresentationService;
import com.jaspersoft.android.jaspermobile.widget.AbstractPaginationView;
import com.jaspersoft.android.jaspermobile.widget.PaginationBarView;
import com.jaspersoft.android.sdk.client.oxm.control.InputControl;
import com.jaspersoft.android.sdk.client.oxm.report.ReportParameter;
import com.jaspersoft.android.sdk.client.oxm.resource.ResourceLookup;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.InstanceState;
import org.androidannotations.annotations.OnActivityResult;
import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.OptionsMenuItem;
import org.androidannotations.annotations.Touch;
import org.androidannotations.annotations.ViewById;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.inject.Inject;
import timber.log.Timber;
/**
* @author Andrew Tivodar
* @since 2.3
*/
@OptionsMenu({R.menu.webview_menu, R.menu.report_filter_manager_menu})
@EActivity(R.layout.activity_cast_report)
public class ReportCastActivity extends CastActivity
implements
ResourcePresentationService.ResourcePresentationCallback,
NumberPickerDialogFragment.NumberDialogClickListener,
NumberDialogFragment.NumberDialogClickListener,
AbstractPaginationView.OnPageChangeListener,
AbstractPaginationView.OnPickerSelectedListener {
private static final int REQUEST_INITIAL_REPORT_PARAMETERS = 100;
private static final int REQUEST_NEW_REPORT_PARAMETERS = 200;
@Extra
protected ResourceLookup resource;
@ViewById(R.id.progressLoading)
protected ProgressBar reportProgress;
@ViewById(R.id.reportMessage)
protected TextView reportMessage;
@ViewById(R.id.scrollContainer)
protected LinearLayout scrollContainer;
@ViewById(R.id.paginationControl)
protected PaginationBarView paginationBar;
@ViewById(R.id.reload)
protected View reloadControl;
@OptionsMenuItem(R.id.refreshAction)
protected MenuItem refreshAction;
@OptionsMenuItem(R.id.showFilters)
protected MenuItem showFilters;
@InstanceState
protected Boolean mHasControls;
@Inject
protected ReportParamsStorage paramsStorage;
@Inject
protected GetReportShowControlsPropertyCase mGetReportShowControlsPropertyCase;
@Inject
protected AuthorizeSessionUseCase mAuthorizeSessionUseCase;
@Inject
protected ReportParamsMapper mReportParamsMapper;
private ResourcePresentationService mResourcePresentationService;
private Timer mTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getBaseActivityComponent().inject(this);
mResourcePresentationService = (ResourcePresentationService) ResourcePresentationService.getInstance();
mTimer = new Timer();
}
@AfterViews
protected void run() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(resource.getLabel());
}
paginationBar.setOnPageChangeListener(this);
paginationBar.setOnPickerSelectedListener(this);
}
@Override
protected void onStart() {
super.onStart();
if (ResourcePresentationService.isStarted()) {
mResourcePresentationService.addResourcePresentationCallback(this);
mResourcePresentationService.synchronizeState(resource, this);
} else {
finish();
}
}
@Override
protected void onStop() {
super.onStop();
mResourcePresentationService.removeResourcePresentationCallback(this);
cancelScrolling();
}
@Override
protected void onDestroy() {
mGetReportShowControlsPropertyCase.unsubscribe();
mAuthorizeSessionUseCase.unsubscribe();
super.onDestroy();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean isPresenting = mResourcePresentationService.isPresenting();
refreshAction.setVisible(isPresenting);
showFilters.setVisible(isPresenting && !getInputControls().isEmpty());
return super.onPrepareOptionsMenu(menu);
}
@Override
protected String getScreenName() {
return getString(R.string.ja_rc_s);
}
@OptionsItem
public boolean showFilters() {
InputControlsActivity_.intent(ReportCastActivity.this)
.reportUri(resource.getUri())
.startForResult(REQUEST_NEW_REPORT_PARAMETERS);
return true;
}
@OptionsItem
public void refreshAction() {
mResourcePresentationService.refresh();
}
@OnActivityResult(REQUEST_INITIAL_REPORT_PARAMETERS)
final void onInitialsParametersResult(int resultCode) {
if (resultCode == Activity.RESULT_OK) {
requestReportCasting();
} else {
finish();
}
}
@OnActivityResult(REQUEST_NEW_REPORT_PARAMETERS)
final void onNewParametersResult(int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
boolean isNewParamsEqualOld = data.getBooleanExtra(
InputControlsActivity.RESULT_SAME_PARAMS, false);
if (!isNewParamsEqualOld) {
requestApplyParams();
}
}
}
@Touch(R.id.btnScrollUp)
protected boolean scrollUpAction(MotionEvent event) {
scrollTo(event, new TimerTask() {
@Override
public void run() {
mResourcePresentationService.scrollUp();
}
});
return false;
}
@Touch(R.id.btnScrollDown)
protected boolean scrollDownAction(MotionEvent event) {
scrollTo(event, new TimerTask() {
@Override
public void run() {
mResourcePresentationService.scrollDown();
}
});
return false;
}
@Touch(R.id.btnScrollLeft)
protected boolean scrollLeftAction(MotionEvent event) {
scrollTo(event, new TimerTask() {
@Override
public void run() {
mResourcePresentationService.scrollLeft();
}
});
return false;
}
@Touch(R.id.btnScrollRight)
protected boolean scrollRightAction(MotionEvent event) {
scrollTo(event, new TimerTask() {
@Override
public void run() {
mResourcePresentationService.scrollRight();
}
});
return false;
}
@Click(R.id.btnZoomIn)
void zoomInAction() {
mResourcePresentationService.zoomIn();
}
@Click(R.id.btnZoomOut)
void zoomOutAction() {
mResourcePresentationService.zoomOut();
}
@Click(R.id.reload)
void reloadSession() {
mAuthorizeSessionUseCase.execute(new ErrorSubscriber<>(new SimpleSubscriber<Void>() {
@Override
public void onStart() {
showReloadButton(false);
showMessageView(false);
showPaginationBar(false);
resetProgressBar();
showProgressBar(true);
showProgressMessage(getString(R.string.r_pd_running_report_msg));
}
@Override
public void onCompleted() {
mResourcePresentationService.reload();
}
}));
}
//---------------------------------------------------------------------
// Callbacks
//---------------------------------------------------------------------
@Override
public void onPagePickerRequested() {
if (paginationBar.isTotalPagesLoaded()) {
NumberPickerDialogFragment.createBuilder(getSupportFragmentManager())
.setMinValue(1)
.setCurrentValue(paginationBar.getCurrentPage())
.setMaxValue(paginationBar.getTotalPages())
.show();
} else {
NumberDialogFragment.createBuilder(getSupportFragmentManager())
.setMaxValue(Integer.MAX_VALUE)
.show();
}
}
@Override
public void onNumberPicked(int page, int requestCode) {
paginationBar.updateCurrentPage(page);
onNumberSubmit(page, requestCode);
}
@Override
public void onNumberSubmit(int currentPage, int requestCode) {
onPageSelected(currentPage);
}
@Override
public void onPageSelected(int currentPage) {
paginationBar.setEnabled(false);
mResourcePresentationService.selectPage(currentPage);
}
@Override
public void onCastStarted() {
super.onCastStarted();
showProgressMessage(getString(R.string.r_pd_initializing_msg));
}
@Override
public void onInitializationDone() {
showMessageView(false);
showProgressBar(false);
loadInputControls();
}
private void loadInputControls() {
if (controlsLoaded()) {
requestReportCasting();
} else {
loadControls();
}
}
private void loadControls() {
mGetReportShowControlsPropertyCase.execute(resource.getUri(), new ErrorSubscriber<>(new SimpleSubscriber<ReportControlFlags>() {
@Override
public void onNext(ReportControlFlags property) {
mHasControls = property.hasControls();
if (property.needPrompt()) {
InputControlsActivity_.intent(ReportCastActivity.this)
.reportUri(resource.getUri())
.startForResult(REQUEST_INITIAL_REPORT_PARAMETERS);
} else {
requestReportCasting();
}
}
}));
}
@Override
public void onLoadingStarted() {
invalidateOptionsMenu();
showProgressMessage(getString(R.string.r_pd_running_report_msg));
showPaginationBar(false);
resetProgressBar();
}
private void resetProgressBar() {
resetPaginationView();
}
@Override
public void onPresentationBegun() {
invalidateOptionsMenu();
showMessageView(false);
showProgressBar(false);
showScrollControls(true);
setPaginationBarEnable(true);
}
@Override
public void onMultiPage() {
if (paginationBar.getTotalPages() == 0) {
showEmptyView();
showPaginationBar(false);
} else {
showPaginationBar(true);
}
}
@Override
public void onPageCountObtain(int pageCount) {
if (pageCount == 0) {
showEmptyView();
}
setPaginationBarTotal(pageCount);
boolean isMultiPage = pageCount > 1;
showPaginationBar(isMultiPage);
}
@Override
public void onPageChanged(int pageNumb, String errorMessage) {
setPaginationBarPage(pageNumb);
setPaginationBarEnable(true);
if (errorMessage != null) {
Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onErrorOccurred(String error) {
invalidateOptionsMenu();
showErrorMessage(error);
showProgressBar(false);
showPaginationBar(false);
resetPaginationView();
}
@Override
public void onAuthErrorOccurred() {
showPaginationBar(false);
showProgressBar(false);
showErrorMessage(getString(R.string.da_session_expired));
showReloadButton(true);
}
@Override
public void onCastStopped() {
super.onCastStopped();
finish();
}
//---------------------------------------------------------------------
// UI methods
//---------------------------------------------------------------------
public void showProgressMessage(CharSequence message) {
showProgressBar(true);
showMessageView(true);
showMessage(message);
showScrollControls(false);
}
public void showEmptyView() {
showMessageView(true);
showMessage(getString(R.string.rv_error_empty_report));
showScrollControls(false);
}
public void showErrorMessage(CharSequence error) {
showMessageView(true);
showMessage(error);
showScrollControls(false);
}
public void showMessage(CharSequence message) {
reportMessage.setText(message);
}
private void resetPaginationView() {
paginationBar.reset();
}
public void setPaginationBarTotal(int total) {
paginationBar.updateTotalCount(total);
}
public void setPaginationBarEnable(boolean enabled) {
paginationBar.setEnabled(enabled);
}
public void setPaginationBarPage(int page) {
paginationBar.updateCurrentPage(page);
}
public void showPaginationBar(boolean visibility) {
paginationBar.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
public void showReloadButton(boolean visibility) {
reloadControl.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
public void showMessageView(boolean visibility) {
reportMessage.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
private void showProgressBar(boolean visibility) {
reportProgress.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
public void showScrollControls(boolean visibility) {
scrollContainer.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
private void scrollTo(MotionEvent event, TimerTask task) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
cancelScrolling();
mTimer.scheduleAtFixedRate(task, 0, 10);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
cancelScrolling();
}
}
private void cancelScrolling() {
mTimer.cancel();
mTimer.purge();
mTimer = new Timer();
}
//---------------------------------------------------------------------
// Helper methods
//---------------------------------------------------------------------
private boolean controlsLoaded() {
return mHasControls != null;
}
private void requestReportCasting() {
mResourcePresentationService.startPresentation(resource);
}
private void requestApplyParams() {
String params = mReportParamsMapper.legacyParamsToJson(getReportParameters());
mResourcePresentationService.applyParams(params);
}
private List<InputControl> getInputControls() {
List<InputControl> inputControls = paramsStorage.getInputControlHolder(resource.getUri()).getInputControls();
if (inputControls == null) {
return Collections.emptyList();
}
return inputControls;
}
private List<ReportParameter> getReportParameters() {
List<ReportParameter> reportParams = paramsStorage.getInputControlHolder(resource.getUri()).getReportParams();
if (reportParams == null) {
return Collections.emptyList();
}
return reportParams;
}
private class ErrorSubscriber<T> extends SimpleSubscriber<T> {
private final SimpleSubscriber<T> mDelegate;
protected ErrorSubscriber(SimpleSubscriber<T> delegate) {
mDelegate = delegate;
}
@Override
public void onNext(T item) {
mDelegate.onNext(item);
}
@Override
public void onCompleted() {
showProgressBar(false);
showMessageView(false);
mDelegate.onCompleted();
}
@Override
public void onStart() {
showProgressMessage(getString(R.string.loading_msg));
mDelegate.onStart();
}
@Override
public void onError(Throwable e) {
Timber.e(e, "GetReportShowControlsPropertyCase failed");
String error = RequestExceptionHandler.extractMessage(ReportCastActivity.this, e);
showErrorMessage(error);
showProgressBar(false);
mDelegate.onError(e);
}
}
}