diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..20ec878
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gen/net/thauvin/erik/android/emprunt/R.java b/gen/net/thauvin/erik/android/emprunt/R.java
new file mode 100644
index 0000000..e9186c8
--- /dev/null
+++ b/gen/net/thauvin/erik/android/emprunt/R.java
@@ -0,0 +1,59 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package net.thauvin.erik.android.emprunt;
+
+public final class R {
+ public static final class attr {
+ }
+ public static final class drawable {
+ public static final int border=0x7f020000;
+ public static final int green_gradient=0x7f020001;
+ public static final int icon=0x7f020002;
+ }
+ public static final class id {
+ public static final int amount=0x7f060002;
+ public static final int calculate=0x7f060007;
+ public static final int cost=0x7f06000e;
+ public static final int interest=0x7f060004;
+ public static final int months=0x7f060006;
+ public static final int payment=0x7f06000b;
+ public static final int tableLayout1=0x7f060008;
+ public static final int tableRow1=0x7f060009;
+ public static final int tableRow2=0x7f06000c;
+ public static final int textView1=0x7f060001;
+ public static final int textView2=0x7f060003;
+ public static final int textView3=0x7f060005;
+ public static final int textView4=0x7f06000a;
+ public static final int textView6=0x7f06000d;
+ public static final int titleBar=0x7f060000;
+ }
+ public static final class layout {
+ public static final int main=0x7f030000;
+ }
+ public static final class string {
+ public static final int about_copyright=0x7f040001;
+ public static final int about_copyright_blackberry=0x7f040002;
+ public static final int about_title=0x7f040003;
+ public static final int app_name=0x7f040000;
+ public static final int btn_calculate=0x7f040004;
+ public static final int hint_amount=0x7f040005;
+ public static final int hint_calculate=0x7f040006;
+ public static final int hint_interest=0x7f040007;
+ public static final int hint_months=0x7f040008;
+ public static final int label_amount=0x7f040009;
+ public static final int label_cost=0x7f04000a;
+ public static final int label_interest=0x7f04000b;
+ public static final int label_months=0x7f04000c;
+ public static final int label_payment=0x7f04000d;
+ public static final int label_version=0x7f04000e;
+ public static final int menu_about=0x7f04000f;
+ }
+ public static final class style {
+ public static final int Emprunt=0x7f050000;
+ }
+}
diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..5221a2d
Binary files /dev/null and b/res/drawable-hdpi/icon.png differ
diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..abfae11
Binary files /dev/null and b/res/drawable-ldpi/icon.png differ
diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..af89ff7
Binary files /dev/null and b/res/drawable-mdpi/icon.png differ
diff --git a/res/drawable-xhdpi/icon.png b/res/drawable-xhdpi/icon.png
new file mode 100644
index 0000000..3bc9e93
Binary files /dev/null and b/res/drawable-xhdpi/icon.png differ
diff --git a/res/drawable/border.xml b/res/drawable/border.xml
new file mode 100644
index 0000000..a8c0c3b
--- /dev/null
+++ b/res/drawable/border.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/green_gradient.xml b/res/drawable/green_gradient.xml
new file mode 100644
index 0000000..79721a5
--- /dev/null
+++ b/res/drawable/green_gradient.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/main.xml b/res/layout/main.xml
new file mode 100644
index 0000000..ff2ffbe
--- /dev/null
+++ b/res/layout/main.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
new file mode 100644
index 0000000..7d6066c
--- /dev/null
+++ b/res/values-fr/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ Emprunt
+ © 2011–12 Erik C. Thauvin.\nTous droits réservés.\n\nhttp://m.thauvin.net/android/
+ © 2011–12 Erik C. Thauvin.\nTous droits réservés.\n\nhttp://m.thauvin.net/blackberry/
+ À propos d\'
+ Calculer
+ ex. 100000
+ à calculer…
+ ex. 5.2
+ ex. 240
+ Montant emprunté:
+ Coût total:
+ Taux d\'intérêt:
+ Nombre de mensualités:
+ Mensualité:
+ Version:
+ À propos
+
+
\ No newline at end of file
diff --git a/res/values-v11/themes.xml b/res/values-v11/themes.xml
new file mode 100644
index 0000000..a839251
--- /dev/null
+++ b/res/values-v11/themes.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..94ce30b
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ Loan
+ © 2011–12 Erik C. Thauvin.\nAll Rights Reserved.\n\nhttp://m.thauvin.net/android/
+ © 2011–12 Erik C. Thauvin.\nAll Rights Reserved.\n\nhttp://m.thauvin.net/blackberry/
+ About
+ Calculate
+ e.g. 100000
+ to be calculated…
+ e.g. 5.2
+ e.g. 240
+ Loan Amount:
+ Total Cost:
+ Interest Rate:
+ Number of Months:
+ Payment:
+ Version:
+ About
+
+
\ No newline at end of file
diff --git a/res/values/themes.xml b/res/values/themes.xml
new file mode 100644
index 0000000..08848c5
--- /dev/null
+++ b/res/values/themes.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/screenshots/bb-640.jpg b/screenshots/bb-640.jpg
new file mode 100644
index 0000000..6011145
Binary files /dev/null and b/screenshots/bb-640.jpg differ
diff --git a/screenshots/bb-featured.png b/screenshots/bb-featured.png
new file mode 100644
index 0000000..2b12d16
Binary files /dev/null and b/screenshots/bb-featured.png differ
diff --git a/screenshots/bb-fr-640.jpg b/screenshots/bb-fr-640.jpg
new file mode 100644
index 0000000..483f0fc
Binary files /dev/null and b/screenshots/bb-fr-640.jpg differ
diff --git a/screenshots/bb-fr.jpg b/screenshots/bb-fr.jpg
new file mode 100644
index 0000000..a945bed
Binary files /dev/null and b/screenshots/bb-fr.jpg differ
diff --git a/screenshots/bb.jpg b/screenshots/bb.jpg
new file mode 100644
index 0000000..157f3e8
Binary files /dev/null and b/screenshots/bb.jpg differ
diff --git a/screenshots/icon480.png b/screenshots/icon480.png
new file mode 100644
index 0000000..5bc337a
Binary files /dev/null and b/screenshots/icon480.png differ
diff --git a/screenshots/loan.gif b/screenshots/loan.gif
new file mode 100644
index 0000000..3460077
Binary files /dev/null and b/screenshots/loan.gif differ
diff --git a/src/net/thauvin/erik/android/emprunt/AboutDialogBuilder.java b/src/net/thauvin/erik/android/emprunt/AboutDialogBuilder.java
new file mode 100644
index 0000000..cfd251a
--- /dev/null
+++ b/src/net/thauvin/erik/android/emprunt/AboutDialogBuilder.java
@@ -0,0 +1,76 @@
+/*
+ * @(#)AboutDialogBuilder.java
+ *
+ * $Id$
+ *
+ */
+package net.thauvin.erik.android.emprunt;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Color;
+import android.text.SpannableString;
+import android.text.util.Linkify;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+/**
+ * The AboutDialogBuilder
class implements a simple "About" dialog.
+ *
+ * @author Sebastian Bauer
+ * @author Erik C. Thauvin
+ * @version $Revision$
+ * @created October 14, 2011
+ * @since 1.0
+ */
+public class AboutDialogBuilder
+{
+ public static AlertDialog create(Context context) throws NameNotFoundException
+ {
+ // Try to load the a package matching the name of our own package
+ final PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_META_DATA);
+ final String versionInfo = pInfo.versionName;
+
+ final String aboutTitle = String.format("%s%s", context.getString(R.string.about_title), context.getString(R.string.app_name));
+ final String versionString = String.format("%s %s", context.getString(R.string.label_version), versionInfo);
+
+ // Set up the TextView
+ final TextView message = new TextView(context);
+ // message.setTextSize(18);
+ message.setTextAppearance(context, android.R.style.TextAppearance_Medium);
+ message.setBackgroundColor(Color.WHITE);
+
+ // We'll use a spannablestring to be able to make links clickable
+ final SpannableString s;
+ if (System.getProperty("os.name").equalsIgnoreCase("qnx"))
+ {
+ s = new SpannableString(context.getString(R.string.about_copyright_blackberry));
+ }
+ else
+ {
+ s = new SpannableString(context.getString(R.string.about_copyright));
+ }
+
+ // Get screen metrics
+ final DisplayMetrics metrics = new DisplayMetrics();
+ ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics);
+
+ // Set some padding
+ final int pad = (int) ((10 / metrics.density) + 0.5f);
+ message.setPadding(pad, pad, pad, pad * 2);
+
+ // Set up the final string
+ message.setText(versionString + "\n\n" + s);
+
+ // Now linkify the text
+ Linkify.addLinks(message, Linkify.ALL);
+
+ return new AlertDialog.Builder(context).setTitle(aboutTitle).setCancelable(true).setIcon(R.drawable.icon)
+ .setPositiveButton(context.getString(android.R.string.ok), null).setView(message).create();
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/thauvin/erik/android/emprunt/EmpruntActivity.java b/src/net/thauvin/erik/android/emprunt/EmpruntActivity.java
new file mode 100644
index 0000000..74efe4c
--- /dev/null
+++ b/src/net/thauvin/erik/android/emprunt/EmpruntActivity.java
@@ -0,0 +1,302 @@
+/*
+ * @(#)EmpruntActivity.java
+ *
+ * Copyright (c) 2011-2012 Erik C. Thauvin (http://erik.thauvin.net/)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the authors nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ *
+ */
+package net.thauvin.erik.android.emprunt;
+
+import java.text.NumberFormat;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.TextWatcher;
+import android.text.style.StyleSpan;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * The EmpruntActivity
class implements a simple loan payment calculator.
+ *
+ * @author Erik C. Thauvin
+ * @version $Revision$
+ * @created October 14, 2011
+ * @since 1.0
+ */
+public class EmpruntActivity extends Activity
+{
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ final TextView titleBar = (TextView) findViewById(R.id.titleBar);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ {
+ titleBar.setLayoutParams(new LinearLayout.LayoutParams(0, 0, 0));
+ titleBar.setVisibility(View.INVISIBLE);
+ }
+
+ final TextView paymentFld = (TextView) findViewById(R.id.payment);
+ final TextView costFld = (TextView) findViewById(R.id.cost);
+
+ final EditText amountFld = ((EditText) findViewById(R.id.amount));
+ final EditText interestFld = ((EditText) findViewById(R.id.interest));
+ final EditText monthsFld = ((EditText) findViewById(R.id.months));
+
+ final Drawable imgX = getResources().getDrawable(android.R.drawable.presence_offline);
+
+ final TextWatcher tw = new TextWatcher()
+ {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ amountFld.setTextColor(Color.BLACK);
+ interestFld.setTextColor(Color.BLACK);
+ monthsFld.setTextColor(Color.BLACK);
+
+ paymentFld.setText(R.string.hint_calculate);
+ paymentFld.setTextColor(Color.LTGRAY);
+
+ costFld.setText(R.string.hint_calculate);
+ costFld.setTextColor(Color.LTGRAY);
+
+ manageClearButton(amountFld, imgX);
+ manageClearButton(interestFld, imgX);
+ manageClearButton(monthsFld, imgX);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+ // TODO Auto-generated method stub
+ }
+ };
+
+ amountFld.addTextChangedListener(tw);
+ interestFld.addTextChangedListener(tw);
+ monthsFld.addTextChangedListener(tw);
+
+ amountFld.setOnTouchListener(buildOnTouchListener(amountFld, imgX));
+ interestFld.setOnTouchListener(buildOnTouchListener(interestFld, imgX));
+ monthsFld.setOnTouchListener(buildOnTouchListener(monthsFld, imgX));
+
+ final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ final Button button = (Button) findViewById(R.id.calculate);
+ button.setOnClickListener(new View.OnClickListener()
+ {
+ public void onClick(View v)
+ {
+ // Hide the soft keyboard
+ imm.hideSoftInputFromWindow(button.getApplicationWindowToken(), 0);
+
+ final String amount = amountFld.getText().toString();
+ final String interest = interestFld.getText().toString();
+ final String months = monthsFld.getText().toString();
+
+ if (amount.isEmpty())
+ {
+ amountFld.requestFocus();
+ }
+ else if (interest.isEmpty())
+ {
+ interestFld.requestFocus();
+ }
+ else if (months.isEmpty())
+ {
+ monthsFld.requestFocus();
+ }
+ else
+ {
+ amountFld.requestFocus();
+
+ final int capital = Integer.valueOf(amount);
+
+ if (capital > 0)
+ {
+ final double rate = Double.valueOf(interest);
+
+ if (rate > 0)
+ {
+ final int term = Integer.valueOf(months);
+
+ if (term > 0)
+ {
+ final double mrate = (rate / 100) / 12;
+ final double payment = (capital * mrate) / (1 - Math.pow((1 + mrate), -term));
+ final double cost = (payment * term) - capital;
+
+ final Editable s = Editable.Factory.getInstance().newEditable(
+ NumberFormat.getCurrencyInstance().format(payment));
+
+ s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ paymentFld.setTextColor(Color.BLACK);
+ paymentFld.setText(s);
+
+ costFld.setTextColor(Color.BLACK);
+ costFld.setText(NumberFormat.getCurrencyInstance().format(cost));
+ }
+ else
+ {
+ monthsFld.setTextColor(Color.RED);
+ monthsFld.requestFocus();
+ }
+ }
+ else
+ {
+ interestFld.setTextColor(Color.RED);
+ interestFld.requestFocus();
+ }
+ }
+ else
+ {
+ amountFld.setTextColor(Color.RED);
+ amountFld.requestFocus();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ menu.add(0, 0, 0, R.string.menu_about).setIcon(android.R.drawable.ic_menu_info_details);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ if (item.getItemId() == 0)
+ {
+ AlertDialog builder;
+ try
+ {
+ builder = AboutDialogBuilder.create(this);
+ builder.show();
+ }
+ catch (NameNotFoundException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Manages the clear button.
+ *
+ * @param view The text view.
+ * @param img The image.
+ */
+ private void manageClearButton(TextView view, Drawable img)
+ {
+ if (view.getText().toString().equals(""))
+ {
+ view.setCompoundDrawablesWithIntrinsicBounds(view.getCompoundDrawables()[0], view.getCompoundDrawables()[1], null,
+ view.getCompoundDrawables()[3]);
+ }
+ else
+ {
+ view.setCompoundDrawablesWithIntrinsicBounds(view.getCompoundDrawables()[0], view.getCompoundDrawables()[1], img,
+ view.getCompoundDrawables()[3]);
+ }
+ }
+
+ /**
+ * Builds OnTouchListener for clear buttons.
+ *
+ * @param field The EditText field.
+ * @return A new OnTouchListener.
+ */
+ private OnTouchListener buildOnTouchListener(final EditText field, final Drawable img)
+ {
+ return new OnTouchListener()
+ {
+ @Override
+ public boolean onTouch(View v, MotionEvent event)
+ {
+ // Is there an X showing?
+ if (field.getCompoundDrawables()[2] == null)
+ {
+ return false;
+ }
+
+ // Only do this for up touches
+ if (event.getAction() != MotionEvent.ACTION_UP)
+ {
+ return false;
+ }
+
+ // Is touch one of our clear buttons?
+ if (event.getX() > field.getWidth() - field.getPaddingRight() - img.getIntrinsicWidth())
+ {
+ field.requestFocusFromTouch();
+ field.setText("");
+ }
+
+ return false;
+ }
+ };
+ }
+}