package br.com.bancooriginal.cyberbank.awt.janela.page;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.text.MaskFormatter;

import br.com.bancooriginal.cyberbank.awt.component.PainelImagem;
import br.com.bancooriginal.cyberbank.awt.component.WaitingDialog;
import br.com.bancooriginal.cyberbank.awt.janela.Janela;
import br.com.bancooriginal.cyberbank.awt.validators.LancamentoValidator;
import br.com.bancooriginal.cyberbank.dto.Lancamento;
import br.com.bancooriginal.cyberbank.exception.CyberBankException;
import br.com.bancooriginal.cyberbank.servico.client.CyberbankClient;
import br.com.bancooriginal.cyberbank.util.CBUtil;

import com.jgoodies.binding.PresentationModel;
import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.validation.ValidationResult;
import com.jgoodies.validation.ValidationResultModel;
import com.jgoodies.validation.util.DefaultValidationResultModel;
import com.jgoodies.validation.view.ValidationResultViewFactory;


/**
 * Pagina utilizada para fazer o lancamento em conta corrente.
 * @author filipe.sa
 *
 */
public class LancamentoPage implements IPage{

	//Painel base da pagina
	private final JPanel page = new JPanel(new BorderLayout());
	private final EmptyBorder border = new EmptyBorder(10, 10, 10, 10);
	private final int alinhamentoLabel = SwingConstants.RIGHT;
	
	//Objetos utilizados para a validacao e bind dos inputs com o objeto lancamento
	private final ValidationResultModel validationResultModel = new DefaultValidationResultModel();
	private PresentationModel<?> mPresentationModel = new PresentationModel<Object>(new LancamentoValidator());
	private JLabel mMessageLabel = ValidationResultViewFactory.createReportIconAndTextLabel(validationResultModel);
	

	 //Campos de input do formulario
	private JTextField numConta;
	private JTextField transacao;
	private JTextField motivo;
	private JTextField valor;
	private JTextField data;
	private JTextField comentario = new JTextField(20);
	private JTextField categoria;
	private JTextField valorCheque24;
	private JTextField valorCheque48;
	private JTextField numDocumento;
	private JCheckBox  reversalFlag = new JCheckBox();
	private JTextField reversalNumber = new JTextField(20);
	
	//Formatadores de campos
    private NumberFormat amountFormat;
    private NumberFormat percentFormat;
    private NumberFormat integer9Format;
    private NumberFormat integer18Format;
    private NumberFormat integer25Format;
    
    //Label para as criticas do preenchimento
    private JLabel criticas;
    
    double valorValue = 0;
	
    
    public LancamentoPage(Lancamento lancamento){
    	
    	LancamentoValidator validator = (LancamentoValidator) mPresentationModel.getBean();
    	validator.setILancamento(lancamento);
    	exibir();
    	
    }
    
	public LancamentoPage(){
		
		exibir();
        		
	}
	
	 public JLabel createLabel(String text, int prefWidth, int prefHeight) {
        JLabel label = createLabel(text);
        label.setPreferredSize(new Dimension(prefWidth, prefHeight));
        return label;
    }
	 
	 private JLabel createLabel(String text){
			JLabel label = new JLabel(CBUtil.getMensagem("messages.cyberbank.label.lancamento."+text), alinhamentoLabel);
			label.setBorder(border);
			return label;
	}

	
	@Override
	public Container getContentPane() {
		return this.page;
	}

	@Override
	public void exibir(){
		
		criticas = new JLabel("");
		criticas.setForeground(Color.RED);
		
		JLabel numContaLabel = createLabel("numConta");
		JLabel transacaoLabel = createLabel("transacao");
		JLabel motivoLabel = createLabel("motivo");
		JLabel valorLabel = createLabel("valor");
		JLabel dataLabel = createLabel("data");
		JLabel comentarioLabel = createLabel("comentario");
		JLabel categoriaLabel = createLabel("categoria");
		JLabel valorCheque24Label = createLabel("valorCheque24");
		JLabel valorCheque48Label = createLabel("valorCheque48");
		JLabel numDocumentoLabel = createLabel("numDocumento");
		JLabel reversalFlagLabel = createLabel("reversalFlag");
		JLabel reversalNumberLabel = createLabel("reversalNumber");
		

		setUpFormats();
		
		try {
			
			numConta = new JFormattedTextField(integer25Format);
			numConta.setColumns(20);
			transacao = new JFormattedTextField(integer9Format);
			transacao.setColumns(20);
			motivo = new JFormattedTextField(integer9Format);
			motivo.setColumns(20);
			data = new JFormattedTextField(new MaskFormatter("##/##/####"));
			data.setColumns(20);
			valor = new JFormattedTextField(amountFormat);
			valor.setColumns(20);
			valorCheque24 = new JFormattedTextField(amountFormat);
			valorCheque24.setColumns(20);
			valorCheque48 = new JFormattedTextField(amountFormat);
			valorCheque48.setColumns(20);
			categoria = new JFormattedTextField(integer9Format);
			categoria.setColumns(20);
			numDocumento = new JFormattedTextField(integer18Format);
			numDocumento.setColumns(20);
			
		} catch (ParseException e) {
			e.printStackTrace();
		}


		Bindings.bind(numConta,  mPresentationModel.getBufferedModel("numConta"));
		Bindings.bind(transacao, mPresentationModel.getBufferedModel("transacao"));
		Bindings.bind(motivo, mPresentationModel.getBufferedModel("motivo"));
		Bindings.bind(valor, mPresentationModel.getBufferedModel("valor"));
		Bindings.bind(data, mPresentationModel.getBufferedModel("data"));
		Bindings.bind(comentario, mPresentationModel.getBufferedModel("comentario"));
		Bindings.bind(categoria, mPresentationModel.getBufferedModel("categoria"));
		Bindings.bind(valorCheque24, mPresentationModel.getBufferedModel("valorCheque24"));
		Bindings.bind(numDocumento, mPresentationModel.getBufferedModel("numDocumento"));
		Bindings.bind(valorCheque48, mPresentationModel.getBufferedModel("valorCheque48"));
		Bindings.bind(reversalFlag, mPresentationModel.getBufferedModel("reversalFlag"));
		Bindings.bind(reversalNumber, mPresentationModel.getBufferedModel("reversalNumber"));


		//criacao dos botoes
		JButton btProcessar = createBtProcessar();
		JButton btCancelar = createBtCancelar();
		
		JPanel painelBotao = new JPanel(new GridLayout(1, 3));
		painelBotao.setPreferredSize(new Dimension(600, 600));
		painelBotao.setBorder(BorderFactory.createEmptyBorder(0, 50, 0, 50));
		painelBotao.add(btProcessar);
		painelBotao.add(btCancelar);
		
		//Painel principal
		//FormDebugPanel 
		JPanel panel = new JPanel();
        FormLayout formLayout = new FormLayout(
        										//Colunas
        										"right:pref:grow, left:pref:grow", 
        										//Linhas
        										"35px, "+
        										"25px, 25px, 25px, 25px, 25px, "+ 
        										"25px, 25px, 25px, 25px, 25px, 25px, 25px, "+
        										"25px, bottom:35px"
        										);
        
        
        panel.setLayout(formLayout);

        CellConstraints cc = new CellConstraints();
        //span primeira coluna, primeira linha, duas colunas, uma linha
        panel.add(criticas, cc.xywh (1, 1, 2, 1));
        
        panel.add(numContaLabel, cc.xy (1, 2));
        panel.add(numConta, cc.xy (2, 2));
        
        panel.add(transacaoLabel, cc.xy (1, 3));
        panel.add(transacao, cc.xy (2, 3));
        
        panel.add(motivoLabel, cc.xy (1, 4));
        panel.add(motivo, cc.xy (2, 4));
        
        panel.add(valorLabel, cc.xy (1, 5));
        panel.add(valor, cc.xy (2, 5));
        
        panel.add(dataLabel, cc.xy (1, 6));
        panel.add(data, cc.xy (2, 6));
        
        panel.add(comentarioLabel, cc.xy (1, 7));
        panel.add(comentario, cc.xy (2, 7));
        
        panel.add(categoriaLabel, cc.xy (1, 8));
        panel.add(categoria, cc.xy (2, 8));
        
        panel.add(valorCheque24Label, cc.xy (1, 9));
        panel.add(valorCheque24, cc.xy (2, 9));
        
        panel.add(valorCheque48Label, cc.xy (1, 10));
        panel.add(valorCheque48, cc.xy (2, 10));
        
        panel.add(numDocumentoLabel, cc.xy (1, 11));
        panel.add(numDocumento, cc.xy (2, 11));
        
        panel.add(reversalFlagLabel, cc.xy (1, 12));
        panel.add(reversalFlag, cc.xy (2, 12));
        
        panel.add(reversalNumberLabel, cc.xy (1, 13));
        panel.add(reversalNumber, cc.xy (2, 13));
        
        //span primeira coluna, ultima linha, duas colunas, uma linha
        panel.add(painelBotao, cc.xywh (1, 15, 2, 1, "center, bottom"));

        
        //Cabecalho
        PainelImagem painelTopo = new PainelImagem(CBUtil.createImage("images/barra.png"));
        JLabel logo = new JLabel(CBUtil.getMensagem("messages.cyberbank.title.page.lancamento"));
        logo.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 20));
        logo.setFont(new Font("Arial", Font.PLAIN, 18));
        logo.setForeground(Color.WHITE);
        painelTopo.add(logo);

        page.add(painelTopo, BorderLayout.NORTH);
        page.add(panel, BorderLayout.CENTER);
		
	}
	
	  //Create and set up number formats. These objects also
    //parse numbers input by user.
    private void setUpFormats() {
    	
        amountFormat = NumberFormat.getNumberInstance();
        amountFormat.setMaximumFractionDigits(5);
        amountFormat.setMinimumFractionDigits(0);
        amountFormat.setMaximumIntegerDigits(20);
        amountFormat.setMinimumIntegerDigits(1);
        amountFormat.setGroupingUsed(false);
       
        percentFormat = NumberFormat.getNumberInstance();
        percentFormat.setMinimumFractionDigits(3);
 
        integer9Format = NumberFormat.getIntegerInstance();
        integer9Format.setMaximumIntegerDigits(9);
        integer9Format.setGroupingUsed(false);
        
        integer18Format = NumberFormat.getIntegerInstance();
        integer18Format.setMaximumIntegerDigits(9);
        integer18Format.setGroupingUsed(false);
        
        integer25Format = NumberFormat.getIntegerInstance();
        integer25Format.setMaximumIntegerDigits(25);
        integer25Format.setGroupingUsed(false);
        
    }
    
    private JButton createBotao(String text) {
		
		JButton botao = new JButton(text);
		botao.setToolTipText(text);
		botao.setBorder(new EmptyBorder(6, 5, 6, 5));
		botao.add(Box.createRigidArea(new Dimension(100, 20)));
		return botao;
		
	}

	private JButton createBtProcessar(){
		
		JButton botao = createBotao(CBUtil.getMensagem("messages.cyberbank.button.process"));
		botao.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				
				final WaitingDialog waitingDialog = new WaitingDialog(page);
				
			    SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
			    	
			        @Override
			        protected String doInBackground() throws InterruptedException {
			        	
						//Lancamento lancamento = getLancamento();
						mPresentationModel.triggerCommit();
						LancamentoValidator validator = (LancamentoValidator) mPresentationModel.getBean();
						ValidationResult result = validator.validate();
						validationResultModel.setResult(result);
						
						if (result.isEmpty()) {
							
							Lancamento lancamento = (Lancamento) validator.getILancamento();
														
							try {
								
								CyberbankClient client = new CyberbankClient();
								client.lancar(lancamento);

								/* CASO DE OK EXIBE RESULTADO */
								ResultadoPage page = new ResultadoPage(lancamento);
								Janela.getInstance().show(page);
								
							} catch (CyberBankException e1) {
								waitingDialog.dispose();
								e1.printStackTrace();
							}
							
						}else{
							
							waitingDialog.dispose();
							
							int qtderrors = result.getMessages().size();
							
							JDialog d = new JDialog();
							d.setSize(500, (qtderrors*30)+60);
							d.setLocationRelativeTo(page);
							JLabel critica = new JLabel("<html>"+result.getMessagesText()+"</html>");
							critica.setForeground(Color.RED);
							d.add(critica);
							d.setVisible(true);
							
						}
						
			        	return "ok";
			        }
			        @Override
			        protected void done() {
			        	
			        	waitingDialog.dispose();
			        	
			        }
			    };
			    
			    worker.execute();

			    waitingDialog.setVisible(true);
			    
			    try {
			        worker.get();
			    } catch (Exception e1) {
			        e1.printStackTrace();
			    }
							
			}
		});
		
		return botao;
	}
	

	private JButton createBtCancelar() {
		
		JButton botao = createBotao(CBUtil.getMensagem("messages.cyberbank.button.cancel"));
		botao.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				PrincipalPage principal = new PrincipalPage();
				Janela.getInstance().show(principal);
			}
		});
		
		return botao;
	}

	public JLabel getmMessageLabel() {
		return mMessageLabel;
	}

	public void setmMessageLabel(JLabel mMessageLabel) {
		this.mMessageLabel = mMessageLabel;
	}
	

}
