package gui;
import gui.models.AccountsComboBoxModel;
import gui.models.AssetsComboBoxModel;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import qora.account.Account;
import qora.assets.Asset;
import qora.transaction.Transaction;
import utils.Pair;
import controller.Controller;
@SuppressWarnings("serial")
public class SendMoneyPanel extends JPanel
{
private JComboBox<Account> cbxFrom;
private JTextField txtTo;
private JTextField txtAmount;
private JTextField txtFee;
private JButton sendButton;
private AccountsComboBoxModel accountsModel;
private JComboBox<Asset> cbxFavorites;
public SendMoneyPanel()
{
this.setLayout(new GridBagLayout());
//PADDING
this.setBorder(new EmptyBorder(10, 10, 10, 10));
//LABEL GBC
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(5,5,5,5);
labelGBC.fill = GridBagConstraints.HORIZONTAL;
labelGBC.anchor = GridBagConstraints.NORTHWEST;
labelGBC.weightx = 0;
labelGBC.gridx = 0;
//COMBOBOX GBC
GridBagConstraints cbxGBC = new GridBagConstraints();
cbxGBC.insets = new Insets(5,5,5,5);
cbxGBC.fill = GridBagConstraints.NONE;
cbxGBC.anchor = GridBagConstraints.NORTHWEST;
cbxGBC.weightx = 0;
cbxGBC.gridx = 1;
//TEXTFIELD GBC
GridBagConstraints txtGBC = new GridBagConstraints();
txtGBC.insets = new Insets(5,5,5,5);
txtGBC.fill = GridBagConstraints.HORIZONTAL;
txtGBC.anchor = GridBagConstraints.NORTHWEST;
txtGBC.weightx = 1;
txtGBC.gridwidth = 2;
txtGBC.gridx = 1;
//FAVORITES GBC
GridBagConstraints favoritesGBC = new GridBagConstraints();
favoritesGBC.insets = new Insets(5, 5, 5, 5);
favoritesGBC.fill = GridBagConstraints.BOTH;
favoritesGBC.anchor = GridBagConstraints.NORTHWEST;
favoritesGBC.weightx = 1;
favoritesGBC.gridwidth = 2;
favoritesGBC.gridx = 0;
favoritesGBC.gridy = 0;
//ASSET FAVORITES
cbxFavorites = new JComboBox<Asset>(new AssetsComboBoxModel());
this.add(cbxFavorites, favoritesGBC);
//BUTTON GBC
GridBagConstraints buttonGBC = new GridBagConstraints();
buttonGBC.insets = new Insets(5,5,5,5);
buttonGBC.fill = GridBagConstraints.NONE;
buttonGBC.anchor = GridBagConstraints.NORTHWEST;
buttonGBC.gridwidth = 2;
buttonGBC.gridx = 0;
//LABEL FROM
labelGBC.gridy = 1;
JLabel fromLabel = new JLabel("From:");
this.add(fromLabel, labelGBC);
//COMBOBOX FROM
txtGBC.gridy = 1;
this.accountsModel = new AccountsComboBoxModel();
this.cbxFrom = new JComboBox<Account>(accountsModel);
this.add(this.cbxFrom, txtGBC);
//ON FAVORITES CHANGE
cbxFavorites.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
Asset asset = ((Asset) cbxFavorites.getSelectedItem());
if(asset != null)
{
//REMOVE ITEMS
cbxFrom.removeAllItems();
//SET RENDERER
cbxFrom.setRenderer(new AccountRenderer(asset.getKey()));
//UPDATE MODEL
accountsModel.removeObservers();
accountsModel = new AccountsComboBoxModel();
cbxFrom.setModel(accountsModel);
}
}
});
//LABEL TO
labelGBC.gridy = 2;
JLabel toLabel = new JLabel("To:");
this.add(toLabel, labelGBC);
//TXT TO
txtGBC.gridy = 2;
txtTo = new JTextField();
this.add(txtTo, txtGBC);
//LABEL AMOUNT
labelGBC.gridy = 3;
JLabel amountLabel = new JLabel("Amount:");
this.add(amountLabel, labelGBC);
//TXT AMOUNT
txtGBC.gridy = 3;
txtAmount = new JTextField();
this.add(txtAmount, txtGBC);
//LABEL FEE
labelGBC.gridy = 4;
JLabel feeLabel = new JLabel("Fee:");
this.add(feeLabel, labelGBC);
//TXT AMOUNT
txtGBC.gridy = 4;
txtFee = new JTextField();
txtFee.setText("1");
this.add(txtFee, txtGBC);
//BUTTON SEND
buttonGBC.gridy = 5;
sendButton = new JButton("Send");
sendButton.setPreferredSize(new Dimension(80, 25));
sendButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
onSendClick();
}
});
this.add(sendButton, buttonGBC);
//ADD BOTTOM SO IT PUSHES TO TOP
labelGBC.gridy = 4;
labelGBC.weighty = 1;
this.add(new JPanel(), labelGBC);
}
public void onSendClick()
{
//DISABLE
this.sendButton.setEnabled(false);
//CHECK IF NETWORK OKE
if(Controller.getInstance().getStatus() != Controller.STATUS_OKE)
{
//NETWORK NOT OKE
JOptionPane.showMessageDialog(null, "You are unable to send a transaction while synchronizing or while having no connections!", "Error", JOptionPane.ERROR_MESSAGE);
//ENABLE
this.sendButton.setEnabled(true);
return;
}
//CHECK IF WALLET UNLOCKED
if(!Controller.getInstance().isWalletUnlocked())
{
//ASK FOR PASSWORD
String password = PasswordPane.showUnlockWalletDialog();
if(!Controller.getInstance().unlockWallet(password))
{
//WRONG PASSWORD
JOptionPane.showMessageDialog(null, "Invalid password", "Unlock Wallet", JOptionPane.ERROR_MESSAGE);
//ENABLE
this.sendButton.setEnabled(true);
return;
}
}
//READ SENDER
Account sender = (Account) cbxFrom.getSelectedItem();
//READ RECIPIENT
String recipientAddress = txtTo.getText();
Account recipient = new Account(recipientAddress);
int parsing = 0;
try
{
//READ AMOUNT
parsing = 1;
BigDecimal amount = new BigDecimal(txtAmount.getText()).setScale(8);
//READ FEE
parsing = 2;
BigDecimal fee = new BigDecimal(txtFee.getText()).setScale(8);
//CHECK MIMIMUM FEE
if(fee.compareTo(Transaction.MINIMUM_FEE) == -1)
{
JOptionPane.showMessageDialog(new JFrame(), "Fee must be at least 1!", "Error", JOptionPane.ERROR_MESSAGE);
//ENABLE
this.sendButton.setEnabled(true);
return;
}
//CHECK IF PAYMENT OR ASSET TRANSFER
Asset asset = (Asset) this.cbxFavorites.getSelectedItem();
Pair<Transaction, Integer> result;
if(asset.getKey() == 0l)
{
//CREATE PAYMENT
result = Controller.getInstance().sendPayment(Controller.getInstance().getPrivateKeyAccountByAddress(sender.getAddress()), recipient, amount, fee);
}
else
{
//CREATE ASSET TRANSFER
result = Controller.getInstance().transferAsset(Controller.getInstance().getPrivateKeyAccountByAddress(sender.getAddress()), recipient, asset, amount, fee);
}
//CHECK VALIDATE MESSAGE
switch(result.getB())
{
case Transaction.VALIDATE_OKE:
//RESET FIELDS
this.txtAmount.setText("");
this.txtTo.setText("");
JOptionPane.showMessageDialog(new JFrame(), "Payment has been sent!", "Success", JOptionPane.INFORMATION_MESSAGE);
break;
case Transaction.INVALID_ADDRESS:
JOptionPane.showMessageDialog(new JFrame(), "Invalid address!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.NEGATIVE_AMOUNT:
JOptionPane.showMessageDialog(new JFrame(), "Amount must be positive!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.NEGATIVE_FEE:
JOptionPane.showMessageDialog(new JFrame(), "Fee must be at least 1!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.NO_BALANCE:
JOptionPane.showMessageDialog(new JFrame(), "Not enough balance!", "Error", JOptionPane.ERROR_MESSAGE);
break;
default:
JOptionPane.showMessageDialog(new JFrame(), "Unknown error!", "Error", JOptionPane.ERROR_MESSAGE);
break;
}
}
catch(Exception e)
{
//CHECK WHERE PARSING ERROR HAPPENED
switch(parsing)
{
case 1:
JOptionPane.showMessageDialog(new JFrame(), "Invalid amount!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case 2:
JOptionPane.showMessageDialog(new JFrame(), "Invalid fee!", "Error", JOptionPane.ERROR_MESSAGE);
break;
}
}
//ENABLE
this.sendButton.setEnabled(true);
}
}