/* * Copyright (C) 2010-2014 Geometer Plus <contact@geometerplus.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.android.fbreader.network; import java.util.*; import android.app.AlertDialog; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Button; import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.network.ZLNetworkException; import org.geometerplus.zlibrary.core.money.Money; import net.sourceforge.arabicReader.R; import org.geometerplus.android.util.UIUtil; import org.geometerplus.fbreader.network.*; import org.geometerplus.fbreader.network.tree.NetworkBookTree; import org.geometerplus.fbreader.network.urlInfo.BookBuyUrlInfo; import org.geometerplus.fbreader.network.authentication.NetworkAuthenticationManager; public class BuyBooksActivity extends Activity implements NetworkLibrary.ChangeListener { public static void run(Activity activity, NetworkBookTree tree) { run(activity, Collections.singletonList(tree)); } public static void run(Activity activity, List<NetworkBookTree> trees) { if (trees.isEmpty()) { return; } final Intent intent = new Intent(activity, BuyBooksActivity.class); final ArrayList<NetworkTree.Key> keys = new ArrayList<NetworkTree.Key>(trees.size()); for (NetworkBookTree t : trees) { keys.add(t.getUniqueKey()); } intent.putExtra(NetworkLibraryActivity.TREE_KEY_KEY, keys); activity.startActivity(intent); } private NetworkLibrary myLibrary; // we assume all the books are from the same catalog private INetworkLink myLink; private List<NetworkBookItem> myBooks; private Money myCost; private Money myAccount; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)); myLibrary = NetworkLibrary.Instance(); final List<NetworkTree.Key> keys = (List<NetworkTree.Key>)getIntent().getSerializableExtra( NetworkLibraryActivity.TREE_KEY_KEY ); if (keys == null || keys.isEmpty()) { finish(); return; } myBooks = new ArrayList<NetworkBookItem>(keys.size()); for (NetworkTree.Key k : keys) { final NetworkTree tree = myLibrary.getTreeByKey(k); if (tree instanceof NetworkBookTree) { myBooks.add(((NetworkBookTree)tree).Book); } else { finish(); return; } } myLink = myBooks.get(0).Link; final NetworkAuthenticationManager mgr = myLink.authenticationManager(); if (mgr == null) { finish(); return; } setContentView(R.layout.buy_book); try { if (!mgr.isAuthorised(true)) { findViewById(R.id.buy_book_buttons).setVisibility(View.GONE); AuthorizationMenuActivity.runMenu(this, myLink, 1); } } catch (ZLNetworkException e) { } myCost = calculateCost(); if (myCost == null) { // TODO: error message finish(); return; } myAccount = mgr.currentAccount(); setupUI(AuthorizationState.Authorized); NetworkLibrary.Instance().addChangeListener(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { findViewById(R.id.buy_book_buttons).setVisibility(View.VISIBLE); super.onActivityResult(requestCode, resultCode, data); } private static enum AuthorizationState { Authorized, NotAuthorized }; private void setupUI(final AuthorizationState state) { runOnUiThread(new Runnable() { public void run() { setupUIInternal(state); } }); } private void setupUIInternal(AuthorizationState state) { final ZLResource dialogResource = ZLResource.resource("dialog"); final ZLResource buttonResource = dialogResource.getResource("button"); final TextView textArea = (TextView)findViewById(R.id.buy_book_text); final Button okButton = (Button)findViewById(R.id.buy_book_buttons).findViewById(R.id.ok_button); final Button cancelButton = (Button)findViewById(R.id.buy_book_buttons).findViewById(R.id.cancel_button); final ZLResource resource = ZLResource.resource("buyBook"); if (myBooks.size() > 1) { setTitle(resource.getResource("titleSeveralBooks").getValue()); } else { setTitle(resource.getResource("title").getValue()); } switch (state) { case NotAuthorized: textArea.setText(resource.getResource("notAuthorized").getValue()); okButton.setText(buttonResource.getResource("authorize").getValue()); cancelButton.setText(buttonResource.getResource("cancel").getValue()); okButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { AuthorizationMenuActivity.runMenu(BuyBooksActivity.this, myLink); } }); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } }); break; case Authorized: if (myAccount == null) { textArea.setText(resource.getResource("noAccountInformation").getValue()); okButton.setText(buttonResource.getResource("refresh").getValue()); cancelButton.setText(buttonResource.getResource("cancel").getValue()); okButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { refreshAccountInformation(); } }); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } }); } else if (myCost.compareTo(myAccount) > 0) { if (Money.ZERO.equals(myAccount)) { textArea.setText( resource.getResource("zeroFunds").getValue() .replace("%0", myCost.toString()) ); } else { textArea.setText( resource.getResource("unsufficientFunds").getValue() .replace("%0", myCost.toString()) .replace("%1", myAccount.toString()) ); } okButton.setText(buttonResource.getResource("pay").getValue()); cancelButton.setText(buttonResource.getResource("refresh").getValue()); okButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { TopupMenuActivity.runMenu(BuyBooksActivity.this, myLink, myCost.subtract(myAccount)); } }); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { refreshAccountInformation(); } }); } else { okButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { UIUtil.wait("purchaseBook", buyRunnable(), BuyBooksActivity.this); } }); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } }); if (myBooks.size() > 1) { textArea.setText( resource.getResource("confirmSeveralBooks").getValue() .replace("%s", String.valueOf(myBooks.size())) ); okButton.setText(buttonResource.getResource("buy").getValue()); cancelButton.setText(buttonResource.getResource("cancel").getValue()); } else if (myBooks.get(0).getStatus() == NetworkBookItem.Status.CanBePurchased) { textArea.setText( resource.getResource("confirm").getValue().replace("%s", myBooks.get(0).Title) ); okButton.setText(buttonResource.getResource("buy").getValue()); cancelButton.setText(buttonResource.getResource("cancel").getValue()); } else { textArea.setText(resource.getResource("alreadyBought").getValue()); cancelButton.setText(buttonResource.getResource("ok").getValue()); okButton.setVisibility(View.GONE); } } break; } } @Override protected void onDestroy() { NetworkLibrary.Instance().removeChangeListener(this); super.onDestroy(); } @Override protected void onResume() { super.onResume(); updateAuthorizationState(); } private Money calculateCost() { Money cost = Money.ZERO; for (NetworkBookItem b : myBooks) { if (b.getStatus() != NetworkBookItem.Status.CanBePurchased) { continue; } final BookBuyUrlInfo info = b.buyInfo(); if (info == null || info.Price == null) { return null; } cost = cost.add(info.Price); } return cost; } private void refreshAccountInformation() { runOnUiThread(new Runnable() { public void run() { refreshAccountInformationInternal(); } }); } private void refreshAccountInformationInternal() { UIUtil.wait( "updatingAccountInformation", new Runnable() { public void run() { final NetworkAuthenticationManager mgr = myLink.authenticationManager(); try { boolean updated = false; mgr.refreshAccountInformation(); final Money account = mgr.currentAccount(); if (account != null && !account.equals(myAccount)) { myAccount = account; updated = true; } final Money cost = calculateCost(); if (cost != null && !cost.equals(myCost)) { myCost = cost; updated = true; } if (updated) { runOnUiThread(new Runnable() { public void run() { setupUI(AuthorizationState.Authorized); } }); } myLibrary.invalidateVisibility(); myLibrary.synchronize(); } catch (ZLNetworkException e) { // ignore } } }, this ); } private Runnable buyRunnable() { return new Runnable() { public void run() { try { final NetworkAuthenticationManager mgr = myLink.authenticationManager(); for (final NetworkBookItem b : myBooks) { if (b.getStatus() != NetworkBookItem.Status.CanBePurchased) { continue; } mgr.purchaseBook(b); runOnUiThread(new Runnable() { public void run() { Util.doDownloadBook(BuyBooksActivity.this, b, false); } }); } finish(); } catch (final ZLNetworkException e) { final ZLResource dialogResource = ZLResource.resource("dialog"); final ZLResource buttonResource = dialogResource.getResource("button"); final ZLResource boxResource = dialogResource.getResource("networkError"); runOnUiThread(new Runnable() { public void run() { new AlertDialog.Builder(BuyBooksActivity.this) .setTitle(boxResource.getResource("title").getValue()) .setMessage(e.getMessage()) .setIcon(0) .setPositiveButton(buttonResource.getResource("ok").getValue(), null) .create().show(); } }); } finally { myLibrary.invalidateVisibility(); myLibrary.synchronize(); } } }; } // method from NetworkLibrary.ChangeListener public void onLibraryChanged(final NetworkLibrary.ChangeListener.Code code, final Object[] params) { switch (code) { case SignedIn: updateAuthorizationState(); break; } } private void updateAuthorizationState() { new Thread(new Runnable() { public void run() { final NetworkAuthenticationManager mgr = myLink.authenticationManager(); try { if (mgr.isAuthorised(true)) { setupUI(AuthorizationState.Authorized); refreshAccountInformation(); } else { setupUI(AuthorizationState.NotAuthorized); } } catch (ZLNetworkException e) { e.printStackTrace(); setupUI(AuthorizationState.NotAuthorized); } } }).start(); } }