package view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DecimalFormat;
import java.text.Format;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import jp.sf.beanbinder.BeanBinder;
import jp.sf.beanbinder.BeanBinderFactory;
import jp.sf.beanbinder.annotations.AlignType;
import jp.sf.beanbinder.annotations.AnnotationParser;
import jp.sf.beanbinder.annotations.Basic;
import jp.sf.beanbinder.annotations.Column;
import jp.sf.beanbinder.annotations.IMEMode;
import jp.sf.beanbinder.annotations.Select;
import jp.sf.beanbinder.annotations.Table;
import jp.sf.beanbinder.editor.CellEditor;
import jp.sf.beanbinder.listener.EditListener;
import jp.sf.beanbinder.listener.EditListenerEvent;
import jp.sf.beanbinder.validator.NotNullValidator;
import jp.sf.beanbinder.validator.NumberValidator;
import jp.sf.beanbinder.validator.RangeValidator;
import jp.sf.beanbinder.validator.ValidateContainer;
import jp.sf.beanbinder.validator.ValidateDisplay;
import jp.sf.beanbinder.validator.Validator;
import jp.sf.beanbinder.validator.swing.SwingValidateDisplay;
import model.Product;
import controller.AddProduct;
import controller.DeleteProduct;
import controller.FindProduct;
import controller.SaveProduct;

public class ExampleWindow extends JFrame implements ActionListener, MouseListener, EditListener {
    public BeanBinder binder = BeanBinderFactory.createSwingBinder();
    private Format format1 = new DecimalFormat("###,###,###");
    
    //Validatorの作成
    private ValidateDisplay validateDisplay;
    private ValidateContainer validator1 = new ValidateContainer();  //  @jve:decl-index=0:
    private Validator validator2;
    
    @Basic(objectKey="product", prop="name", imeMode=IMEMode.JP, group="group1" )
    private JTextField nameTextBox = null;

    //商品表のマッピング
    @Table(objectKey="productList", sortable=true, editListenerField="editListener1",
            columns = {
                @Column(prop="code", text="品番", validatorField="validator2"),
                @Column(prop="name", text="品名", width=260, validatorField="validator2"),
                @Column(displayProp="category.name", valueProp="category", text="区分", cellEditorField="cellEditor1", validatorField="validator2", horizon=AlignType.CENTER),
                @Column(prop="unitPrice", text="単価", formatField="format1", validatorField="validator1", horizon=AlignType.RIGHT),
                @Column(prop="remarks", text="備考")
            }
    )
    private JTable productTable = null;
    
    //商品表のセルエディタをマッピング
    @Select( srcKey="categoryList", srcDisplayProp="name" )
    private JComboBox combo = new JComboBox();
    private CellEditor cellEditor1 = new CategoryCellEditor(this.binder, combo);
    
    private EditListener editListener1;
    
    
    //下記の多くの記述はVisualEditorによって自動的に生成されています。
    private static final long serialVersionUID = 1L;

    private JPanel jContentPane = null;

    private JScrollPane jScrollPane = null;

    private JPanel jPanel = null;

    private JLabel jLabel1 = null;

    private JButton findButton = null;

    private JPopupMenu jPopupMenu = null;  //  @jve:decl-index=0:visual-constraint="740,129"

    private JMenuItem jMenuItem = null;

    private JMenuItem jMenuItem2 = null;

    /**
     * This is the default constructor
     */
    public ExampleWindow() {
        super();
        initialize();
        
        this.mapping();
        
        this.getFindButton().addActionListener(this);
        this.getProductTable().addMouseListener(this);
        this.getJScrollPane().addMouseListener(this);
        this.getJMenuItem().addActionListener(this);
        this.getJMenuItem2().addActionListener(this);
    }
    public void mapping() {
        //Validatorの作成
        this.validateDisplay = new SwingValidateDisplay(this);
        this.validator1.addValidator(new NumberValidator("単価を正しく入力して下さい。", this.validateDisplay));
        this.validator1.addValidator(new RangeValidator(0, 9999999, "入力可能な範囲は0～9999999までです。", this.validateDisplay));
        
        this.validator2 = new NotNullValidator("商品コード・品名・区分は必須項目です", this.validateDisplay);
        
        //商品表の為のEditListenerを作成
        this.editListener1 = this;
        
        //アノテーションからマッピング
        new AnnotationParser(this.binder, this).parse();
    }
    
    public void actionPerformed(ActionEvent e) {
        if( e.getSource().equals(this.getFindButton()) ) {
            new FindProduct().execute(binder);
        }
        if( e.getSource().equals(this.getJMenuItem()) ) {
            new AddProduct().execute(binder);
        }
        if( e.getSource().equals(this.getJMenuItem2()) ) {
            Product product = (Product)this.binder.getSelectedValue("productTable");
            List<Product> productList = (List<Product>)this.binder.getObject("productList");
            new DeleteProduct().execute(product, productList);
            this.binder.updateComponent(".*");
        }
    }
    public void mouseClicked(MouseEvent e) {
        if( SwingUtilities.isRightMouseButton(e) ) {
            this.getJPopupMenu().show(e.getComponent(), e.getX(), e.getY());
        }
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    
    public void beginEdit(EditListenerEvent e) {
    }
    public void endEdit(EditListenerEvent e) {
        List<Product> list = (List<Product>)this.binder.getObject("productList");
        Product p = list.get(e.getRow());
        new SaveProduct().execute(p);
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setSize(583, 439);
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        this.setContentPane(getJContentPane());
        this.setTitle("BeanBinder Example");
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getJPanel(), BorderLayout.NORTH);
            jContentPane.add(getJScrollPane(), BorderLayout.CENTER);
        }
        return jContentPane;
    }

    /**
     * This method initializes jScrollPane	
     * 	
     * @return javax.swing.JScrollPane	
     */
    private JScrollPane getJScrollPane() {
        if (jScrollPane == null) {
            jScrollPane = new JScrollPane();
            jScrollPane.setPreferredSize(new Dimension(0, 200));
            jScrollPane.setViewportView(getProductTable());
        }
        return jScrollPane;
    }

    /**
     * This method initializes productTable	
     * 	
     * @return javax.swing.JTable	
     */
    private JTable getProductTable() {
        if (productTable == null) {
            productTable = new JTable();
        }
        return productTable;
    }

    /**
     * This method initializes jPanel	
     * 	
     * @return javax.swing.JPanel	
     */
    private JPanel getJPanel() {
        if (jPanel == null) {
            jLabel1 = new JLabel();
            jLabel1.setBounds(new Rectangle(10, 10, 91, 21));
            jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
            jLabel1.setText("品名");
            jPanel = new JPanel();
            jPanel.setLayout(null);
            jPanel.setPreferredSize(new Dimension(1, 40));
            jPanel.add(jLabel1, null);
            jPanel.add(getNameTextBox(), null);
            jPanel.add(getFindButton(), null);
        }
        return jPanel;
    }

    /**
     * This method initializes nameTextBox	
     * 	
     * @return javax.swing.JTextField	
     */
    private JTextField getNameTextBox() {
        if (nameTextBox == null) {
            nameTextBox = new JTextField();
            nameTextBox.setBounds(new Rectangle(110, 10, 261, 21));
        }
        return nameTextBox;
    }

    /**
     * This method initializes findButton	
     * 	
     * @return javax.swing.JButton	
     */
    private JButton getFindButton() {
        if (findButton == null) {
            findButton = new JButton();
            findButton.setBounds(new Rectangle(380, 10, 91, 21));
            findButton.setText("品名検索");
        }
        return findButton;
    }
    /**
     * This method initializes jPopupMenu	
     * 	
     * @return javax.swing.JPopupMenu	
     */
    private JPopupMenu getJPopupMenu() {
        if (jPopupMenu == null) {
            jPopupMenu = new JPopupMenu();
            jPopupMenu.add(getJMenuItem());
            jPopupMenu.add(getJMenuItem2());
        }
        return jPopupMenu;
    }
    /**
     * This method initializes jMenuItem	
     * 	
     * @return javax.swing.JMenuItem	
     */
    private JMenuItem getJMenuItem() {
        if (jMenuItem == null) {
            jMenuItem = new JMenuItem();
            jMenuItem.setText("新規追加");
        }
        return jMenuItem;
    }
    /**
     * This method initializes jMenuItem2	
     * 	
     * @return javax.swing.JMenuItem	
     */
    private JMenuItem getJMenuItem2() {
        if (jMenuItem2 == null) {
            jMenuItem2 = new JMenuItem();
            jMenuItem2.setText("削除");
        }
        return jMenuItem2;
    }

}  //  @jve:decl-index=0:visual-constraint="10,10"
