package com.money.manager.ex.assetallocation;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintManager;
import android.text.TextUtils;
import android.util.Base64;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebView;
import com.money.manager.ex.R;
import com.money.manager.ex.assetallocation.report.ReportHtmlFormatter;
import com.money.manager.ex.common.MmxBaseFragmentActivity;
import com.money.manager.ex.core.ContextMenuIds;
import com.money.manager.ex.core.UIHelper;
import com.money.manager.ex.core.FormatUtilities;
import com.money.manager.ex.core.MenuHelper;
import com.money.manager.ex.core.file.TextFileExport;
import com.money.manager.ex.currency.CurrencyService;
import com.money.manager.ex.domainmodel.AssetClass;
import com.money.manager.ex.servicelayer.AssetAllocationService;
import com.money.manager.ex.settings.InvestmentSettings;
import java.io.File;
import java.io.IOException;
import java.util.List;
import info.javaperformance.money.Money;
import timber.log.Timber;
/**
* Asset Allocation report.
*/
public class AssetAllocationReportActivity
extends MmxBaseFragmentActivity {
private Money differenceThreshold;
private CurrencyService mCurrencyService;
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_asset_allocation_report);
// load difference threshold
InvestmentSettings settings = new InvestmentSettings(this);
this.differenceThreshold = settings.getAssetAllocationDifferenceThreshold();
// get asset allocation
AssetAllocationService service = new AssetAllocationService(this);
AssetClass allocation = service.loadAssetAllocation();
// create a HTML display.
String html = createHtml(allocation);
displayOverview(html);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.asset_allocation);
MenuHelper menuHelper = new MenuHelper(this, menu);
menuHelper.addToContextMenu(ContextMenuIds.Print);
// menuHelper.addToContextMenu(ContextMenuIds.SaveAsHtml, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
ContextMenuIds menuId = ContextMenuIds.get(itemId);
switch (menuId) {
case Print:
// print to pdf
createWebPrintJob(this.webView);
return true;
case SaveAsHtml:
exportHtml();
return true;
default:
return false;
}
}
private String createHtml(AssetClass allocation) {
String html = "<html>";
// Styles
html += "<head>" +
" <style>" +
" body { background: lightgray; padding: 0; } " +
" ul li { border-bottom: 1px solid black; } " +
" li.inline { display: inline; list-style-type: none; padding-right: 10px; } " +
" </style>" +
"</head>";
html += "<body>";
html += getSummaryRow(allocation);
html += getList(allocation.getChildren());
html += "</body></html>";
return html;
}
private void displayOverview(String html) {
webView = (WebView) this.findViewById(R.id.overviewWebView);
// gesture handler
handleGestures(webView);
// context menu
registerForContextMenu(webView);
// enable Unicode
WebSettings settings = webView.getSettings();
settings.setDefaultTextEncodingName("utf-8");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
String base64 = Base64.encodeToString(html.getBytes(), Base64.DEFAULT);
webView.loadData(base64, "text/html; charset=utf-8", "base64");
} else {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
webView.loadData(header + html, "text/html; charset=UTF-8", null);
}
// webView.loadData(html, "text/html", "UTF-8");
}
private void exportHtml() {
File outFile = null;
final TextFileExport export = new TextFileExport(this);
try {
export.clearCache();
outFile = export.createExportFile("asset_allocation.html");
} catch (IOException e) {
Timber.e(e, "creating temp file");
}
if (outFile == null) {
new UIHelper(this).showToast("File could not be created.");
return;
}
final File finalOutFile = outFile;
webView.saveWebArchive(outFile.getAbsolutePath(), false, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
if (!TextUtils.isEmpty(value)) {
// offer export
export.export(finalOutFile, getString(R.string.asset_allocation));
}
}
});
}
private String getAssetRow(AssetClass allocation) {
String color = "black";
double diffPercent = allocation.getDiffAsPercentOfSet().toDouble();
if (diffPercent >= this.differenceThreshold.toDouble()) {
color = "green";
}
if (diffPercent <= this.differenceThreshold.multiply(-1).toDouble()) {
color = "darkred";
}
// style='list-style-position: inside;'
String html = "<li>";
html += getAssetValues(allocation, color);
// html += getAssetValuesAsList(allocation, color);
// Child asset classes
html += getList(allocation.getChildren());
html += "</li>";
return html;
}
private String getAssetValues(AssetClass allocation, String color) {
String html = "";
ReportHtmlFormatter formatter = new ReportHtmlFormatter(allocation, color);
// Name
html += formatter.getName();
html += " · ";
// diff %
html += formatter.getDiffPerc();
html += " · ";
// difference amount
html += formatter.getDiffAmount();
html += "<br/>";
// Allocation
html += formatter.getAllocation();
// current allocation
html += formatter.getCurrentAllocation();
html += " · ";
// Value
html += formatter.getValue();
return html;
}
private String getAssetValuesAsList(AssetClass allocation, String color) {
ReportHtmlFormatter formatter = new ReportHtmlFormatter(allocation, color);
String html = "<ul class='inline'>";
html += "<li class='inline'>";
html += formatter.getName();
html += "</li>";
html += "<li class='inline'>";
html += formatter.getDiffPerc();
html += "</li>";
// difference amount
html += "<li class='inline'>";
html += formatter.getDiffAmount();
html += "</li>";
html += "<li class='inline'>";
html += formatter.getAllocation();
html += "</li>";
html += "<li class='inline'>";
html += formatter.getCurrentAllocation();
html += "</li>";
html += "<li class='inline'>";
html += formatter.getValue();
html += "</li>";
html += "</ul>";
return html;
}
private CurrencyService getCurrencyService() {
if (mCurrencyService == null) {
mCurrencyService = new CurrencyService(this);
}
return mCurrencyService;
}
/**
* Create a list with child elements.
* @param children Asset Allocation/Class
* @return HTML list (ul) of the child Asset Classes with information.
*/
private String getList(List<AssetClass> children) {
String html = "";
if (children.size() == 0) return html;
html += "<ul style='padding-left: 20px;'>";
for(AssetClass child : children) {
html += getAssetRow(child);
}
html += "</ul>";
return html;
}
private String getSummaryRow(AssetClass allocation) {
if (allocation == null) return "n/a";
String html = "";
FormatUtilities formatter = new FormatUtilities(this);
html += "<p>" +
allocation.getName() + ", " +
// currencyService.getBaseCurrencyCode() + " " +
// String.format(VALUE_FORMAT, allocation.getCurrentValue().toDouble()) +
formatter.format(allocation.getCurrentValue(), getCurrencyService().getBaseCurrencyId()) +
"</p>";
return html;
}
private void handleGestures(WebView webView) {
GestureDetector.OnGestureListener listener = new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// show context menu
//Log.d("test", "long-press");
showContextMenu();
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
};
final GestureDetector gd = new GestureDetector(this, listener);
GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// show context menu
// return false;
return showContextMenu();
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
};
gd.setOnDoubleTapListener(doubleTapListener);
View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//return false;
return gd.onTouchEvent(event);
}
};
// attach to the web view
webView.setOnTouchListener(touchListener);
}
private void createWebPrintJob(WebView webView) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
new UIHelper(this).showToast(R.string.min_19);
return;
} else {
// Get a PrintManager instance
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
// Get a print adapter instance
PrintDocumentAdapter printAdapter;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
printAdapter = webView.createPrintDocumentAdapter(getString(R.string.asset_allocation));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
printAdapter = webView.createPrintDocumentAdapter();
} else {
// to satisfy lint.
return;
}
// Create a print job with name and adapter instance
String jobName = getString(R.string.app_name) + " Document";
// PrintJob printJob =
printManager.print(jobName, printAdapter, new PrintAttributes.Builder().build());
}
}
private boolean showContextMenu() {
return webView.showContextMenu();
}
}