// CurrencyConverter5.java
// A program which converts multiple times between US Dollars, British Pounds,
// Euros, Japanese Yen, Singapore Dollars, or Chinese Yuan using JOptionPane
// factory methods for input.

import java.text.DecimalFormat;
import javax.swing.JOptionPane;

public class CurrencyConverter5
{
    // decimal formatting
    DecimalFormat moneyFormat = new DecimalFormat("0.00");
    // number of currencies
    public static final int NUM_CURRENCIES      = 6;
    // constants to define currencies
    public static final int US_DOLLAR           = 0;
    public static final int BRITISH_POUND       = 1;
    public static final int EURO                = 2;
    public static final int JAPANESE_YEN        = 3;
    public static final int SINGAPORE_DOLLAR    = 4;
    public static final int CHINESE_YUAN        = 5;
    // conversion rates from US dollars to the other five currencies
    public static final float USD_TO_BRITISH_POUND      = 0.630f;
    public static final float USD_TO_EURO               = 0.744f;
    public static final float USD_TO_JAPANESE_YEN       = 82.996f;
    public static final float USD_TO_SINGAPORE_DOLLAR   = 1.289f;
    public static final float USD_TO_CHINESE_YUAN       = 6.584f;

    // function converts money to/from various currencies
    public void convertMoney()
    {
        String choice, inputStr;
        do
        {
            inputStr = JOptionPane.showInputDialog(null,
                "What is your starting currency?\n" + currenciesToString());
            int fromCurrency = Integer.parseInt(inputStr);
            if (isValidCurrency(fromCurrency))
            {
                inputStr = JOptionPane.showInputDialog(null,
                    "Enter the amount of " + getCurrencyText(fromCurrency) +
                    " to convert:");
                float fromAmount = Float.parseFloat(inputStr);
                if (fromAmount >= 0.f)
                {
                    inputStr = JOptionPane.showInputDialog(null,
                        "What currency do you want to convert to?\n" +
                        currenciesToString());
                    int toCurrency = Integer.parseInt(inputStr);
                    if (isValidCurrency(toCurrency))
                    {
                        float toCurrencyAmnt = convertCurrency(fromAmount,
                            fromCurrency, toCurrency);
                        displayConversionStatement(fromAmount, fromCurrency,
                            toCurrencyAmnt, toCurrency);
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(null,
                            "ERROR: invalid currency! (" + toCurrency + ")");
                    }
                }
                else
                {
                    JOptionPane.showMessageDialog(null,
                        "ERROR: invalid monetary amount! (" + fromAmount + ")");
                }
            }
            else
            {
                JOptionPane.showMessageDialog(null,
                    "ERROR: invalid currency! (" + fromCurrency + ")");
            }
            choice = JOptionPane.showInputDialog(null,
                "Would you like to convert again? (y/n)");
        }
        while (choice.equalsIgnoreCase("y"));
        JOptionPane.showMessageDialog(null, "Good-bye!");
    }
    
    // print out the currency options
    public String currenciesToString()
    {
        return "(" + US_DOLLAR + ") US Dollars\n" +
               "(" + BRITISH_POUND + ") British Pounds\n" +
               "(" + EURO + ") Euros\n" +
               "(" + JAPANESE_YEN + ") Japanese Yen\n" +
               "(" + SINGAPORE_DOLLAR + ") Singapore Dollars\n" +
               "(" + CHINESE_YUAN + ") Chinese Yuan";
    }
    
    // print a statement about the currency conversion
    public void displayConversionStatement(float amount1, int currency1,
        float amount2, int currency2)
    {
        JOptionPane.showMessageDialog(null, moneyFormat.format(amount1) + " " +
            getCurrencyText(currency1) + " is equal to " +
            moneyFormat.format(amount2) + " " + getCurrencyText(currency2) +
            ".");
    }
    
    // retrieve the string equivalent of each currency
    public String getCurrencyText(int currency)
    {
        switch (currency)
        {
            case US_DOLLAR:
                return "US Dollars";
            case BRITISH_POUND:
                return "British Pounds";
            case EURO:
                return "Euros";
            case JAPANESE_YEN:
                return "Japanense Yen";
            case SINGAPORE_DOLLAR:
                return "Singapore Dollars";
            case CHINESE_YUAN:
                return "Chinese Yuan";
            default:
                return null;
        }
    }
    
    // returns true if the integer represents a valid currency, false otherwise
    public boolean isValidCurrency(int currency)
    {
        return 0 <= currency && currency < NUM_CURRENCIES;
    }
    
    // converts and returns the value of usd in another currency
    public float usdToOtherCurrency(float usd, int otherCurrency)
    {
        switch (otherCurrency)
        {
            case US_DOLLAR:
                return usd;
            case BRITISH_POUND:
                return usd * USD_TO_BRITISH_POUND;
            case EURO:
                return usd * USD_TO_EURO;
            case JAPANESE_YEN:
                return usd * USD_TO_JAPANESE_YEN;
            case SINGAPORE_DOLLAR:
                return usd * USD_TO_SINGAPORE_DOLLAR;
            case CHINESE_YUAN:
                return usd * USD_TO_CHINESE_YUAN;
            default:
                return -1.f;
        }
    }
    
    // converts and returns the amount of US doloars in the given other currency
    public float otherCurrencyToUSD(float amount, int otherCurrency)
    {
        switch (otherCurrency)
        {
            case US_DOLLAR:
                return amount;
            case BRITISH_POUND:
                return amount / USD_TO_BRITISH_POUND;
            case EURO:
                return amount / USD_TO_EURO;
            case JAPANESE_YEN:
                return amount / USD_TO_JAPANESE_YEN;
            case SINGAPORE_DOLLAR:
                return amount / USD_TO_SINGAPORE_DOLLAR;
            case CHINESE_YUAN:
                return amount / USD_TO_CHINESE_YUAN;
            default:
                return -1.f;
        }
    }
    
    // convert between any two currencies
    public float convertCurrency(float fromAmount, int fromCurrency,
        int toCurrency)
    {
        // convert fromCurrency to USD
        float usd = otherCurrencyToUSD(fromAmount, fromCurrency);
        // convert USD to toCurrency
        float toAmount = usdToOtherCurrency(usd, toCurrency);
        // return amount
        return toAmount;
    }
    
    // main method
    public static void main(String[] args)
    {
        CurrencyConverter5 converter = new CurrencyConverter5();
        converter.convertMoney();
    }
}