package ee.ut.math.tvt2008.salessystem.ui.panel;

import ee.ut.math.tvt2008.salessystem.domain.data.SoldItem;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.beans.EventHandler;
import java.util.NoSuchElementException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import ee.ut.math.tvt2008.salessystem.domain.data.StockItem;
import ee.ut.math.tvt2008.salessystem.ui.model.SalesSystemModel;
import ee.ut.math.tvt2008.salessystem.util.Translations;

/**
 * Purchase pane + shopping cart tabel UI.
 */
public class PurchaseItemPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	private static final String ADD_ITEM_HANDLER = "addItemEventHandler";
	private static final String FILL_DIALOG_HANDLER = "fillDialogFields";

	private final JTextField barCode = new JTextField();
	private final JTextField quantity = new JTextField("1");
	private final JTextField name = new JTextField();
	private final JTextField price = new JTextField();
	private final JTextField[] fields = new JTextField[] { barCode, quantity,
			name, price };

	private JButton addItem;

	// application data model 
	private SalesSystemModel model;

	/**
	 * Constructs new purchase item panel.
	 * 
	 * @param model
	 *            composite model of the warehouse and the shopping cart.
	 */
	public PurchaseItemPanel(SalesSystemModel model) {
		this.model = model;

		drawWidgets();
		setEnabled(false);
	}

	// build UI
	private void drawWidgets() {
		GridBagConstraints gc = new GridBagConstraints();
		GridBagLayout gb = new GridBagLayout();

		setLayout(gb);
		gc.anchor = GridBagConstraints.WEST;
		gc.weightx = 0.2;
		gc.weighty = 0d;
		gc.gridwidth = GridBagConstraints.REMAINDER;
		gc.fill = GridBagConstraints.NONE;

		add(drawDialogPane(), gc);

		gc.fill = GridBagConstraints.BOTH;
		gc.weighty = 1.0;
		add(drawBasketPane(), gc);
	}

	// shopping cart pane
	private JComponent drawBasketPane() {
		JPanel pane = new JPanel();
		GridBagConstraints gc = new GridBagConstraints();
		GridBagLayout gb = new GridBagLayout();

		pane.setLayout(gb);

		JTable table = new JTable(model.getCurrentPurchaseTableModel());
		JScrollPane scrollPane = new JScrollPane(table);

		gc.fill = GridBagConstraints.BOTH;
		gc.weightx = 1.0;
		gc.weighty = 1.0;
		pane.add(scrollPane, gc);
		pane.setBorder(BorderFactory.createTitledBorder(Translations.getString("purchaseItem.basket")));
		return pane;
	}

	// purchase dialog
	private JComponent drawDialogPane() {
		JPanel panel = new JPanel();

		panel.setLayout(new GridLayout(5, 2));

		JLabel label = new JLabel(Translations.getString("purchaseItem.barCode") + ":");
		panel.add(label);

		barCode.addFocusListener(EventHandler.create(FocusListener.class, 
				this, FILL_DIALOG_HANDLER));
		panel.add(barCode);

		label = new JLabel(Translations.getString("main.quantity") + ":");
		panel.add(label);

		panel.add(quantity);

		label = new JLabel(Translations.getString("main.name") + ":");
		panel.add(label);

		name.setEditable(false);
		panel.add(name);

		label = new JLabel(Translations.getString("main.price") + ":");
		panel.add(label);

		price.setEditable(false);
		panel.add(price);

		addItem = new JButton(Translations.getString("purchaseItem.addToBasket"));
		addItem.addActionListener(EventHandler.create(ActionListener.class, 
				this, ADD_ITEM_HANDLER));
		panel.add(addItem);

		panel.setBorder(BorderFactory.createTitledBorder(Translations.getString("purchaseItem.article")));
		return panel;
	}

	// fill dialog with data from the "database"
	public void fillDialogFields() {
		StockItem stockItem = getStockItemByBarcode();

		if (stockItem != null) {
			name.setText(stockItem.getName());
			price.setText("" + stockItem.getPrice());
		} else {
			reset();
		}
	}

	private StockItem getStockItemByBarcode() {
		StockItem stockItem;
		try {
			stockItem = model.getWarehouseTableModel().getItemById(
					Integer.parseInt(barCode.getText()));
		} catch (NumberFormatException ex) {
			stockItem = null;
		} catch (NoSuchElementException ex) {
			stockItem = null;
		}
		return stockItem;
	}

	/**
	 * Add new item to the cart.
	 */
	public void addItemEventHandler() {
		// add chosen item to the shopping cart.
		StockItem stockItem = getStockItemByBarcode();
		if (stockItem != null) {
			int stockQuantity = stockItem.getQuantity();
			stockItem = stockItem.clone();

			try {
				stockItem.setQuantity(Integer.parseInt(quantity.getText()));
			} catch (NumberFormatException ex) {
				stockItem.setQuantity(1);
			}

			int existingQuantity = 0;
			try {
                            SoldItem tempItem = model.getCurrentPurchaseTableModel().getItemById(stockItem.getId());
                            if(tempItem!=null)
				existingQuantity = tempItem.getQuantity();
			} catch (Exception ne) {
                        }
			
			if (stockQuantity < stockItem.getQuantity() + existingQuantity) {
				JOptionPane.showMessageDialog(null, 
						Translations.getString("purchaseItem.notEnoughGoods", stockItem.getName()),
						Translations.getString("purchaseItem.notEnoughGoodsTitle"), 
						JOptionPane.PLAIN_MESSAGE);
				return;
			}
			model.getCurrentPurchaseTableModel().addItem(stockItem);
                        model.getCurrentPurchaseTableModel().fireTableDataChanged();
		}
	}

	/**
	 * Sets whether or not this component is enabled.
	 */
	@Override
	public void setEnabled(boolean enabled) {
		this.addItem.setEnabled(enabled);
		this.barCode.setEnabled(enabled);
		this.quantity.setEnabled(enabled);
	}

	/**
	 * Reset dialog fields.
	 */
	public void reset() {
		for (int i = 0; i < fields.length; i++) {
			fields[i].setText("");
		}
		quantity.setText("1");
	}
}
