package gui.assets;
import gui.AccountRenderer;
import gui.PasswordPane;
import gui.models.AccountsComboBoxModel;
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 java.math.RoundingMode;
import java.sql.Date;
import java.text.DateFormat;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import controller.Controller;
import qora.account.Account;
import qora.account.PrivateKeyAccount;
import qora.assets.Asset;
import qora.transaction.Transaction;
import utils.Pair;
@SuppressWarnings("serial")
public class OrderPanel extends JPanel
{
private Asset have;
private Asset want;
private JButton sellButton;
private JComboBox<Account> cbxAccount;
private JTextField txtAmount;
private JTextField txtPrice;
private JTextField txtFee;
private JTextField txtBuyingPrice;
private JTextField txtBuyingAmount;
public OrderPanel(Asset have, Asset want, boolean buying)
{
this.setLayout(new GridBagLayout());
this.have = have;
this.want = want;
//PADDING
this.setBorder(new EmptyBorder(10, 10, 10, 10));
//LABEL GBC
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(0, 5, 5, 0);
labelGBC.fill = GridBagConstraints.HORIZONTAL;
labelGBC.anchor = GridBagConstraints.NORTHWEST;
labelGBC.gridx = 0;
//DETAIL GBC
GridBagConstraints detailGBC = new GridBagConstraints();
detailGBC.insets = new Insets(0, 5, 5, 0);
detailGBC.fill = GridBagConstraints.HORIZONTAL;
detailGBC.anchor = GridBagConstraints.NORTHWEST;
detailGBC.gridx = 1;
//LABEL FROM
labelGBC.gridy = 0;
JLabel fromLabel = new JLabel("Account:");
this.add(fromLabel, labelGBC);
//COMBOBOX FROM
detailGBC.gridy = 0;
this.cbxAccount = new JComboBox<Account>(new AccountsComboBoxModel());
this.cbxAccount.setRenderer(new AccountRenderer(this.have.getKey()));
this.add(this.cbxAccount, detailGBC);
//LABEL PRICE
labelGBC.gridy++;
JLabel priceLabel = new JLabel("Price:");
this.add(priceLabel, labelGBC);
//PRICE
detailGBC.gridy++;
txtPrice = new JTextField();
this.add(txtPrice, detailGBC);
if(buying)
{
//LABEL BUYING PRICE
labelGBC.gridy++;
JLabel buyingPriceLabel = new JLabel("Buying price:");
this.add(buyingPriceLabel, labelGBC);
//BUYING PRICE
detailGBC.gridy++;
txtBuyingPrice = new JTextField();
txtBuyingPrice.setEnabled(false);
this.add(txtBuyingPrice, detailGBC);
//ON PRICE CHANGE
txtPrice.getDocument().addDocumentListener(new DocumentListener()
{
public void changedUpdate(DocumentEvent e)
{
calculateBuyingPrice(txtBuyingPrice);
}
public void removeUpdate(DocumentEvent e)
{
calculateBuyingPrice(txtBuyingPrice);
}
public void insertUpdate(DocumentEvent e)
{
calculateBuyingPrice(txtBuyingPrice);
}
});
}
//LABEL AMOUNT
labelGBC.gridy++;
JLabel amountLabel = new JLabel("Amount:");
this.add(amountLabel, labelGBC);
//AMOUNT
detailGBC.gridy++;
this.txtAmount = new JTextField();
this.add(this.txtAmount, detailGBC);
//LABEL AMOUNT
labelGBC.gridy++;
JLabel buyingAmountLabel = new JLabel("Buying amount:");
this.add(buyingAmountLabel, labelGBC);
//AMOUNT
detailGBC.gridy++;
txtBuyingAmount = new JTextField();
txtBuyingAmount.setEnabled(false);
this.add(txtBuyingAmount, detailGBC);
//ON PRICE CHANGE
txtAmount.getDocument().addDocumentListener(new DocumentListener()
{
public void changedUpdate(DocumentEvent e)
{
calculateBuyingAmount(txtBuyingAmount);
}
public void removeUpdate(DocumentEvent e)
{
calculateBuyingAmount(txtBuyingAmount);
}
public void insertUpdate(DocumentEvent e)
{
calculateBuyingAmount(txtBuyingAmount);
}
});
//LABEL FEE
labelGBC.gridy++;
JLabel feeLabel = new JLabel("Fee:");
this.add(feeLabel, labelGBC);
//FEE
detailGBC.gridy++;
txtFee = new JTextField("1");
this.add(txtFee, detailGBC);
//ADD SELL BUTTON
labelGBC.gridy++;
labelGBC.gridwidth = 2;
this.sellButton = new JButton("Sell");
this.sellButton.setPreferredSize(new Dimension(125, 25));
this.sellButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
onSellClick();
}
});
this.add(this.sellButton, labelGBC);
}
public void calculateBuyingPrice(JTextField target)
{
try
{
BigDecimal price = new BigDecimal(txtPrice.getText());
target.setText(BigDecimal.ONE.setScale(8).divide(price, RoundingMode.DOWN).toPlainString());
}
catch(Exception e)
{
target.setText("0");
}
calculateBuyingAmount(txtBuyingAmount);
}
public void calculateBuyingAmount(JTextField target)
{
try
{
BigDecimal price = new BigDecimal(txtPrice.getText());
BigDecimal amount = new BigDecimal(txtAmount.getText());
target.setText(price.multiply(amount).toPlainString());
}
catch(Exception e)
{
target.setText("0");
}
}
public void onSellClick()
{
//DISABLE
this.sellButton.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.sellButton.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.sellButton.setEnabled(true);
return;
}
}
//READ CREATOR
Account sender = (Account) this.cbxAccount.getSelectedItem();
long parse = 0;
try
{
//READ FEE
BigDecimal fee = new BigDecimal(this.txtFee.getText()).setScale(8);
//READ AMOUNT
parse = 1;
BigDecimal amount = new BigDecimal(this.txtAmount.getText()).setScale(8);
//READ PRICE
parse = 2;
BigDecimal price = new BigDecimal(this.txtPrice.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.sellButton.setEnabled(true);
return;
}
//CREATE POLL
PrivateKeyAccount creator = Controller.getInstance().getPrivateKeyAccountByAddress(sender.getAddress());
Pair<Transaction, Integer> result = Controller.getInstance().createOrder(creator, this.have, this.want, amount, price, fee);
//CHECK VALIDATE MESSAGE
switch(result.getB())
{
case Transaction.VALIDATE_OKE:
JOptionPane.showMessageDialog(new JFrame(), "Order has been sent!", "Success", JOptionPane.INFORMATION_MESSAGE);
break;
case Transaction.NOT_YET_RELEASED:
Date release = new Date(Transaction.ASSETS_RELEASE);
DateFormat format = DateFormat.getDateTimeInstance();
JOptionPane.showMessageDialog(new JFrame(), "Assets will be enabled at " + format.format(release) + "!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.HAVE_EQUALS_WANT:
JOptionPane.showMessageDialog(new JFrame(), "Have can not equal Want!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.ASSET_DOES_NOT_EXIST:
JOptionPane.showMessageDialog(new JFrame(), "The asset does not exist!", "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_PRICE:
JOptionPane.showMessageDialog(new JFrame(), "Price must be positive!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.INVALID_AMOUNT:
JOptionPane.showMessageDialog(new JFrame(), "Invalid amount!", "Error", JOptionPane.ERROR_MESSAGE);
break;
case Transaction.INVALID_RETURN:
JOptionPane.showMessageDialog(new JFrame(), "Invalid total price!", "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)
{
e.printStackTrace();
if(parse == 0)
{
JOptionPane.showMessageDialog(new JFrame(), "Invalid fee!", "Error", JOptionPane.ERROR_MESSAGE);
}
if(parse == 1)
{
JOptionPane.showMessageDialog(new JFrame(), "Invalid amount!", "Error", JOptionPane.ERROR_MESSAGE);
}
if(parse == 2)
{
JOptionPane.showMessageDialog(new JFrame(), "Invalid price!", "Error", JOptionPane.ERROR_MESSAGE);
}
}
//ENABLE
this.sellButton.setEnabled(true);
}
}