import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.text.*;

import java.net.URL;
import java.net.MalformedURLException;

import opencard.core.event.CardTerminalEvent;
import opencard.core.event.CTListener;
import opencard.core.event.EventGenerator;
import opencard.core.service.CardServiceException;
import opencard.core.service.SmartCard;
import opencard.core.terminal.CardTerminalException;
import opencard.core.terminal.CardTerminalRegistry;
import opencard.core.util.OpenCardPropertyLoadingException;
import opencard.core.service.CardRequest;

import com.silentmission.ewallet.cardservices.TestWalletCardService;

public class DemoLoyaltyApplet extends JApplet implements CTListener
{

    JPanel mainPanel;
    JButton buttonPanel;
    JLabel nameLabel;
    JLabel eeashBalanceLabel;
    JTextField creditAmount;
    JTextField cashBack2UAmount;
    JButton paymentButton;

    int totalCost = -1;
    int eCashBalance = -1;

    TestWalletCardService svc;

    public void init()
    {	
	initializeUI();

	try 
	{
	    SmartCard.start();
	    EventGenerator.getGenerator().addCTListener(this);
	    System.out.println("OCF started");
	}
	catch(OpenCardPropertyLoadingException plfe) 
	{
	    System.out.println("OpenCardPropertyLoadingException: ");
	    System.out.println(plfe.getMessage());
	}
	catch(ClassNotFoundException cnfe) 
	{
	    System.out.println("ClassNotFoundException: ");
	    System.out.println(cnfe.getMessage());
        }
	catch(CardServiceException cse) 
	{
	    System.out.println("CardServiceException: ");
	    System.out.println(cse.getMessage());
	}
	catch(CardTerminalException cte) 
	{
	    System.out.println("CardTerminalException 2: ");
	    System.out.println(cte.getMessage());
 	}

    }  // init

    public void start()
    {
    }  // start

    public void stop()
    {
    }  // stop

    public void destroy()
    {
	try
	{
	    SmartCard.shutdown();
	    System.out.println("OCF stopped");
	}
	catch(Exception e)
	{
	    e.printStackTrace(System.out);
	}
	
    }  // destroy

    public void cardInserted (CardTerminalEvent ctEvent)
    {
	try
	{
	    CardRequest req = new CardRequest(CardRequest.ANYCARD, 
					      null,
					      TestWalletCardService.class);
	    
	    SmartCard card = SmartCard.getSmartCard(ctEvent, req);
	    svc = (TestWalletCardService)card.getCardService(TestWalletCardService.class, true);

	}
	catch(ClassNotFoundException cnfe) 
	{
	    System.out.println("ClassNotFoundException: ");
	    System.out.println(cnfe.getMessage ());
	    System.exit(0);
        }
	catch(CardServiceException cse) 
	{
	    System.out.println("CardServiceException: ");
	    System.out.println(cse.getMessage ());
	}
	catch(CardTerminalException cte) 
	{
	    System.out.println("CardTerminalException: ");
	    System.out.println(cte.getMessage ());
	}
	enableControls();
    } // cardInserted
 
    public void cardRemoved(CardTerminalEvent ctEvent) 
    {
	disableControls();
    } // cardRemoved

    public String getCardHolder()
    {
	String name = null;
	try
	{	    
	    name = svc.getCardHolderName();
	}
	catch (CardServiceException cse) 
	{
	    System.out.println ("CardServiceException: ");
	    System.out.println (cse.getMessage () );
	}
	catch (CardTerminalException cte) 
	{
	    System.out.println ("CardTerminalException: ");
	    System.out.println (cte.getMessage () );
	}
	return name;
    }

    public int geteCashBalance()
    {
	if(eCashBalance != -1)
	    return eCashBalance;
        try
        {
	    eCashBalance = svc.eCashBalance();
	}
	catch (CardServiceException cse) 
	{
	    System.out.println ("CardServiceException: ");
	    System.out.println (cse.getMessage () );
	}
	catch (CardTerminalException cte) 
	{
	    System.out.println ("CardTerminalException: ");
	    System.out.println (cte.getMessage () );
	}
	return eCashBalance;
    }

    public void debiteCash(int amount)
    {
        try
        {
	    svc.debiteCash(amount);
	}
	catch (CardServiceException cse) 
	{
	    System.out.println ("CardServiceException: ");
	    System.out.println (cse.getMessage () );
	}
	catch (CardTerminalException cte) 
	{
	    System.out.println ("CardTerminalException: ");
	    System.out.println (cte.getMessage () );
	}
    }

    public void crediteCash(int amount)
    {
        try
        {
	    svc.crediteCash(amount);
	}
	catch (CardServiceException cse) 
	{
	    System.out.println ("CardServiceException: ");
	    System.out.println (cse.getMessage () );
	}
	catch (CardTerminalException cte) 
	{
	    System.out.println ("CardTerminalException: ");
	    System.out.println (cte.getMessage () );
	}
    }

    public void enableControls()
    {
	nameLabel.setText(getCardHolder());
	eCashBalanceLabel.setText("eCash Balance $" + asMoneyString(geteCashBalance()));
	eCashAmount.setText(getDefaulteCashAmount());
	creditAmount.setText(getDefaultCreditAmount()); 
	paymentButton.setEnabled(true);
	creditAmount.setEnabled(true);
	eCashAmount.setEnabled(true);
	paymentButton.requestFocus();
    }

    public void disableControls()
    {
	eCashBalance = -1;
	totalCost = -1;
	nameLabel.setText("Please Insert Your eWallet.");
	eCashAmount.setText("0.00");
	creditAmount.setText("0.00"); 
	eCashBalanceLabel.setText("");
	paymentButton.setEnabled(false);
	creditAmount.setEnabled(false);
	eCashAmount.setEnabled(false);
    }

    public void createMainPanel() 
    {
	mainPanel = new JPanel();
	mainPanel.setLayout(new BorderLayout());
	mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 10, 20));
	mainPanel.setBackground(Color.black);
    } // createMainPanel

    public Component createButtonPanel()
    {
	paymentButton = new JButton("Transfer Funds");
	//paymentButton.setPreferredSize(new Dimension(25, 25));
	paymentButton.setMnemonic(KeyEvent.VK_P);
        paymentButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		paymentButtonPushed();
	    }
	});	

	JPanel buttonPanel = new JPanel(new GridLayout(0,1,0,0));
	buttonPanel.setBorder(BorderFactory.createBevelBorder(0));
	buttonPanel.add(paymentButton);
	return buttonPanel;
    }

    public Component createInfoPanel()
    {
	JPanel infoPanel = new JPanel();
	infoPanel.setBackground(Color.black);
	infoPanel.setLayout(new GridLayout(2, 0, 0, 15));
	infoPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));
	nameLabel = new JLabel("Test Name");
	nameLabel.setForeground(Color.white);
	infoPanel.add(nameLabel);

	eCashBalanceLabel = new JLabel("Loyalty Balance : $0.00");
	eCashBalanceLabel.setForeground(Color.white);
	infoPanel.add(eCashBalanceLabel);

	return infoPanel;
    }

    public Component createAmountPanel()
    {
	JPanel paymentPanel = new JPanel();
	paymentPanel.setLayout(new GridLayout(2, 2, 5, 15));
	paymentPanel.setBackground(Color.black);	
	paymentPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));

	JLabel eCashAmountLabel = new JLabel("Cash Back 2U Amount $", JLabel.RIGHT);
	paymentPanel.add(eCashAmountLabel);
	eCashAmount = new JTextField("0.00");
	paymentPanel.add(eCashAmount);

	JLabel creditAmountLabel = new JLabel("Credit Amount $", JLabel.RIGHT);
	paymentPanel.add(creditAmountLabel);
	creditAmount = new JTextField("0.00");
	paymentPanel.add(creditAmount);

	return paymentPanel;
    }

    public void initializeUI()
    {
	createMainPanel();
	createButtonPanel();
	mainPanel.add(createInfoPanel(), BorderLayout.WEST);
	mainPanel.add(createButtonPanel(), BorderLayout.SOUTH);
	mainPanel.add(createAmountPanel(), BorderLayout.EAST);
	getContentPane().add(mainPanel);
	disableControls();
    }

    public int getTotalCost()
    {
	if(totalCost != -1)
	{
	    return totalCost;
	}

	String cost = getParameter("totalAmount");
	if(cost == null)
	{
	    totalCost = 0;
	    return totalCost;
	}
	
	int total = 0;
	try
	{
	    total = Integer.parseInt(cost);
	}
	catch(NumberFormatException e)
	{
	    System.out.println(e.getMessage());
	}
	totalCost = total;
	return totalCost;
    }

    public String getDefaulteCashAmount()
    {
	getTotalCost();
	geteCashBalance();
	if(eCashBalance >= totalCost)
	    return asMoneyString(totalCost);
	return asMoneyString(eCashBalance);
    }
  
    public String getDefaultCreditAmount()
    {
	geteCashBalance();
	getTotalCost();
	if(eCashBalance - totalCost >= 0)
	    return "0.00";
	return asMoneyString((totalCost - eCashBalance));
    } 
   
    public String asMoneyString(int amount)
    {
 	String dollars = Integer.toString(amount / 100);
	String cents = Integer.toString(amount % 100);
	if(cents.length() == 1)
	    cents = "0" + cents;
 	return dollars + "." + cents;
    }

    public int moneyStringAsInt(String money) throws NumberFormatException
    {
	int index = money.indexOf(".");
	if (index == -1)
	    money += ".00";	    
	String buf = money.substring(0, money.indexOf("."));
	buf += money.substring(money.indexOf(".") + 1);
        int moneyInt = 0;
	moneyInt= Integer.parseInt(buf);
	return moneyInt;
    }

    public void paymentButtonPushed()
    {
 	int debit = 0;
	try
	{
	    debit = moneyStringAsInt(eCashAmount.getText());
	}
	catch(NumberFormatException e)
	{
	    JOptionPane.showMessageDialog(this,
					  "Invalid Cash Back 2U Amount",
					  "Payment Error",
					  JOptionPane.ERROR_MESSAGE);
	    eCashAmount.requestFocus();
	    return;
	}
	int credit = 0;
	try
	{
	    credit = moneyStringAsInt(creditAmount.getText());
	}
	catch(NumberFormatException e)
	{
	    JOptionPane.showMessageDialog(this,
					  "Invalid Credit Amount",
					  "Payment Error",
					  JOptionPane.ERROR_MESSAGE);
	    creditAmount.requestFocus();
	    return;
	}
	if(debit > geteCashBalance())
	{
	    JOptionPane.showMessageDialog(this,
					  "Insuficient Cash Back 2U Funds",
					  "Payment Error",
					  JOptionPane.ERROR_MESSAGE);
	    return;
	}
	int total = getTotalCost();
	if(debit + credit != total)
	{
// 	    JOptionPane.showMessageDialog(this,
// 					  "Payment Amounts Don't Equal Total : $" + asMoneyString(getTotalCost()),
// 					  "Payment Error",
// 					  JOptionPane.ERROR_MESSAGE);
	    if(debit > total)
		debit = total;

	    credit = total - debit;
		
	    //	    return;
	}

	if(debit > 0)
	    debiteCash(debit);

	int award = 0;
	if(credit > 0)
	{
	    award = (int)(.03 * credit);
	    crediteCash(award);
	}

    //calculateLoyalty and hit the card

	String urlString = "http://localhost/SmartMall.asp?page=thankyou";
	String name = getCardHolder();
	String fname = null;
	String lname = null;
	int index = name.indexOf(" ");	
	if(index == -1)
	    // there is no space then its just a first name which is stupid
	    fname = name;
	else
	{
	    fname = name.substring(0, index);
	    lname = name.substring(index + 1);
	}
	urlString += "&firstname=" + fname;
	urlString += "&lastname=" + lname;
	urlString += "&creditamount=$" + asMoneyString(credit);
	urlString += "&eCashamount=$" + asMoneyString(debit);
	urlString += "&eCashaward=$" + asMoneyString(award);
	try
	{
	    URL url = new URL(urlString);
	    getAppletContext().showDocument(url);
	}
	catch(MalformedURLException e)
	{
	    System.out.println(e.getMessage());
	}
    }
}



















