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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
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.io.File;
import java.text.NumberFormat;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
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 javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;

import br.com.bancooriginal.cyberbank.awt.component.CampoObrigatorioListener;
import br.com.bancooriginal.cyberbank.awt.component.InstrucoesParametrizacaoModel;
import br.com.bancooriginal.cyberbank.awt.component.MultilineTableCell;
import br.com.bancooriginal.cyberbank.awt.component.PainelImagem;
import br.com.bancooriginal.cyberbank.awt.janela.Janela;
import br.com.bancooriginal.cyberbank.awt.validators.IntegerVerifier;
import br.com.bancooriginal.cyberbank.awt.validators.StringVerifier;
import br.com.bancooriginal.cyberbank.dto.Parametrizacao;
import br.com.bancooriginal.cyberbank.util.CBUtil;
import br.com.bancooriginal.cyberbank.util.XMLUtil;

/**
 * Pagina de parametrizacao
 * @author filipe.sa
 * @author diego.dias
 *
 */
public class ParametrizacaoPage implements IPage {

	private final JPanel panel = new JPanel();
	
	private JPanel painelCentral;
	
	private final int alinhamentoLabel = SwingConstants.RIGHT;
	private final EmptyBorder border = new EmptyBorder(10, 10, 10, 10);
	
	@Override
	public Container getContentPane() {
		return this.panel;
	}
	
	//Criamos os campos de input
	private JTextField userId = new JTextField();
	private JTextField sessionId = new JTextField();
	private JTextField institutionId;
	private JTextField branchId;
	private JTextField channelId = new JTextField();
	private JTextField terminalId = new JTextField();
	private JTextField parityCurrencyCodeId;
	private JTextField parityQuotationTypeNemotecnic;
	private JTextField localCountryId;
	private JTextField localCurrencyCodeId;
	private JTextField bankId;
	private JTextField msgTypeId = new JTextField();
	private JTextField originBranchId;
	private JTextField dependencyId;
	
	//Formatadores
	private NumberFormat integer4Format;
    private NumberFormat integer9Format;
	
    //Objeto de valor (VO) da parametrizacao
	Parametrizacao parametrizacao;

	/**
	 * Metodo que monta e exibe o formulario de parametrizacao.
	 */
	@Override
	public void exibir(){
		
		panel.setLayout(new BorderLayout());
		
		//inicializando os formatadores
		setUpFormats();
		
		CampoObrigatorioListener campoObrigatorioListener = new CampoObrigatorioListener();
		
		//Atribuindo formatadores e tamanho aos campos de input
		institutionId = new JFormattedTextField(integer4Format);
		institutionId.setColumns(20);
		branchId = new JFormattedTextField(integer9Format);
		branchId.setColumns(20);
		parityCurrencyCodeId = new JFormattedTextField(integer4Format);
		parityCurrencyCodeId.setColumns(20);
		parityQuotationTypeNemotecnic = new JFormattedTextField(integer9Format);
		parityQuotationTypeNemotecnic.setColumns(20);
		localCountryId = new JFormattedTextField(integer9Format);
		localCountryId.setColumns(20);
		localCurrencyCodeId = new JFormattedTextField(integer4Format);
		localCurrencyCodeId.setColumns(20);
		bankId = new JFormattedTextField(integer9Format);
		bankId.setColumns(20);
		originBranchId = new JFormattedTextField(integer9Format);
		originBranchId.setColumns(20);
		dependencyId = new JFormattedTextField(integer9Format);
		dependencyId.setColumns(20);
        
        //Recuperamos o xml com os dados da parametrizacao
        parametrizacao = XMLUtil.lerConfiguracoes(new File("parametrizacao.xml"));
        
        //Se a parametrizacao ja existir, carregamos os valores
        //para o formulario
        if(null != parametrizacao){
        	
        	userId.setText(parametrizacao.getUserId());
        	sessionId.setText(parametrizacao.getSessionId());
        	institutionId.setText(parametrizacao.getInstitutionId());
        	branchId.setText(parametrizacao.getBranchId());
        	parityCurrencyCodeId.setText(parametrizacao.getParityCurrencyId());
        	parityQuotationTypeNemotecnic.setText(parametrizacao.getParityQuotationTypeNemotecnic());
        	localCountryId.setText(parametrizacao.getLocalCountryId());
        	localCurrencyCodeId.setText(parametrizacao.getLocalCurrencyId());
        	bankId.setText(parametrizacao.getBankId());
        	originBranchId.setText(parametrizacao.getOriginBranchId());
        	dependencyId.setText(parametrizacao.getDependencyId());
        	
        	channelId.setText(parametrizacao.getChannelId());
        	terminalId.setText(parametrizacao.getTerminalId());
        	msgTypeId.setText(parametrizacao.getMsgTypeId());

        }else{
        	
        	//caso a parametrizacao ainda nao exista carregamos os valores default
        	
        	//Campos fixos
            channelId.setText("20");
        	terminalId.setText("ws");
        	msgTypeId.setText("200");
        	
        	//valores default
        	institutionId.setText("1111");
        	branchId.setText("1");
        	parityCurrencyCodeId.setText("212");
        	parityQuotationTypeNemotecnic.setText("0");
        	localCountryId.setText("55");
        	localCurrencyCodeId.setText("1");
        	bankId.setText("212");
        	userId.setText("Simulador");
        	originBranchId.setText("1");
        	dependencyId.setText("1");
        	
        }
        
        //setando validadores
    	userId.setInputVerifier(new StringVerifier(25, true, null));
    	userId.addActionListener(new StringVerifier(25, true, null));
    	userId.addKeyListener(campoObrigatorioListener);
    	sessionId.setInputVerifier(new StringVerifier(40, true, null));
    	sessionId.addActionListener(new StringVerifier(40, true, null));
    	sessionId.addKeyListener(campoObrigatorioListener);
        institutionId.setInputVerifier(new IntegerVerifier(4, true));
        institutionId.addActionListener(new IntegerVerifier(4, true));
        institutionId.addKeyListener(campoObrigatorioListener);
        branchId.setInputVerifier(new IntegerVerifier(9, true));
        branchId.addActionListener(new IntegerVerifier(9, true));
        branchId.addKeyListener(campoObrigatorioListener);
    	parityCurrencyCodeId.setInputVerifier(new IntegerVerifier(4, true));
    	parityCurrencyCodeId.addActionListener(new IntegerVerifier(4, true));
    	parityCurrencyCodeId.addKeyListener(campoObrigatorioListener);
    	parityQuotationTypeNemotecnic.setInputVerifier(new IntegerVerifier(9, true));
    	parityQuotationTypeNemotecnic.addActionListener(new IntegerVerifier(9, true));
    	parityQuotationTypeNemotecnic.addKeyListener(campoObrigatorioListener);
    	localCountryId.setInputVerifier(new IntegerVerifier(9, true));
    	localCountryId.addActionListener(new IntegerVerifier(9, true));
    	localCountryId.addKeyListener(campoObrigatorioListener);
    	localCurrencyCodeId.setInputVerifier(new IntegerVerifier(4, true));
    	localCurrencyCodeId.addActionListener(new IntegerVerifier(4, true));
    	localCurrencyCodeId.addKeyListener(campoObrigatorioListener);
    	bankId.setInputVerifier(new IntegerVerifier(9, true));
    	bankId.addActionListener(new IntegerVerifier(9, true));
    	bankId.addKeyListener(campoObrigatorioListener);
    	originBranchId.setInputVerifier(new IntegerVerifier(9, true));
    	originBranchId.addActionListener(new IntegerVerifier(9, true));
    	originBranchId.addKeyListener(campoObrigatorioListener);
    	dependencyId.setInputVerifier(new IntegerVerifier(9, true));
    	dependencyId.addActionListener(new IntegerVerifier(9, true));
    	dependencyId.addKeyListener(campoObrigatorioListener);
        
        //Campos fixos nao editaveis
        channelId.setEditable(false);
    	terminalId.setEditable(false);
    	msgTypeId.setEditable(false);

        
        //criando labels
		JLabel userIdLabel = createLabel("userId");
		JLabel sessionIdLabel = createLabel("sessionId");
		JLabel institutionIdLabel = createLabel("institutionId");
		JLabel branchIdLabel = createLabel("branchId");
		JLabel channelIdLabel = createLabel("channelId");
		JLabel terminalIdLabel = createLabel("terminalId");
		JLabel parityCurrencyCodeIdLabel = createLabel("parityCurrencyCodeId");
		JLabel parityQuotationTypeNemotecnicLabel = createLabel("parityQuotationTypeNemotecnic");
		JLabel localCountryIdLabel = createLabel("localCountryId");
		JLabel localCurrencyCodeIdLabel = createLabel("localCurrencyCodeId");
		JLabel bankIdLabel = createLabel("bankId");
		JLabel msgTypeIdLabel = createLabel("msgTypeId");
		JLabel originBranchIdLabel = createLabel("originBranchId");
		JLabel dependencyIdLabel = createLabel("dependencyId");

		//criando botoes
		JButton btProcessar = createBtProcessar();
		JButton btInstrucoes = createBtInstrucoes();
		JButton btCancelar = createBtCancelar();
		
		//Criando titulo da janela
        JLabel logo = new JLabel(CBUtil.getMensagem("messages.cyberbank.title.page.parametrizacao"));
        logo.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 20));
        logo.setFont(new Font("Arial", Font.PLAIN, 18));
        logo.setForeground(Color.WHITE);
		
        //Criando painel superior da janela com imagem de fundo
		PainelImagem painelTopo = new PainelImagem(CBUtil.createImage("images/barra.png"));
		
		//criando painel central que vai conter os campos de inputs
		painelCentral = new JPanel(new GridLayout(16, 2));
		painelCentral.setBorder(BorderFactory.createEmptyBorder(30, 20, 30, 20));
		
		//criando painel inferior que vai conter os botoes
		JPanel painelBotao = new JPanel(new GridLayout(1, 3));
		painelBotao.setBorder(BorderFactory.createEmptyBorder(0, 20, 30, 20));
		
		//adicionando os botoes ao painel inferior
		painelBotao.add(btProcessar);
		painelBotao.add(btInstrucoes);
		painelBotao.add(btCancelar);
		
		//adicionando titulo ao painel superior
		painelTopo.add(logo);
		
		//adiconando labels e campos de input ao painel central
		painelCentral.add(userIdLabel);
		painelCentral.add(userId);
		
		painelCentral.add(sessionIdLabel);
		painelCentral.add(sessionId);
		
		painelCentral.add(institutionIdLabel);
		painelCentral.add(institutionId);
		
		painelCentral.add(branchIdLabel);
		painelCentral.add(branchId);
		
		painelCentral.add(channelIdLabel);
		painelCentral.add(channelId);
		
		painelCentral.add(terminalIdLabel);
		painelCentral.add(terminalId);
		
		painelCentral.add(parityCurrencyCodeIdLabel);
		painelCentral.add(parityCurrencyCodeId);
		
		painelCentral.add(parityQuotationTypeNemotecnicLabel);
		painelCentral.add(parityQuotationTypeNemotecnic);
		
		painelCentral.add(localCountryIdLabel);
		painelCentral.add(localCountryId);
		
		painelCentral.add(localCurrencyCodeIdLabel);
		painelCentral.add(localCurrencyCodeId);
		
		painelCentral.add(bankIdLabel);
		painelCentral.add(bankId);
		
		painelCentral.add(msgTypeIdLabel);
		painelCentral.add(msgTypeId);
		
		painelCentral.add(originBranchIdLabel);
		painelCentral.add(originBranchId);
		
		painelCentral.add(dependencyIdLabel);
		painelCentral.add(dependencyId);
		
		//adicionando os paineis ao painel principal
		panel.add(painelTopo, BorderLayout.NORTH);
		panel.add(painelCentral, BorderLayout.CENTER);
		panel.add(painelBotao, BorderLayout.SOUTH);
		
	}
	
	/**
	 * metodo que seta os valores dos campos de input no objeto de valor (VO)
	 * @return
	 */
	private Parametrizacao getParametrizacao(){
		
		Parametrizacao p = new Parametrizacao();
		
		p.setUserId(userId.getText());
		p.setSessionId(sessionId.getText());
		p.setInstitutionId(institutionId.getText());
		p.setBranchId(branchId.getText());
		p.setChannelId(channelId.getText());
		p.setTerminalId(terminalId.getText());
		p.setParityCurrencyId(parityCurrencyCodeId.getText());
		p.setParityQuotationTypeNemotecnic(parityQuotationTypeNemotecnic.getText());
		p.setLocalCountryId(localCountryId.getText());
		p.setLocalCurrencyId(localCurrencyCodeId.getText());
		p.setBankId(bankId.getText());
		p.setMsgTypeId(msgTypeId.getText());
		p.setOriginBranchId(originBranchId.getText());
		p.setDependencyId(dependencyId.getText());
		
		p.setAmbiente(parametrizacao.getAmbiente());
		p.setEnderecoAmbienteAce(parametrizacao.getEnderecoAmbienteAce());
		p.setEnderecoAmbienteDes(parametrizacao.getEnderecoAmbienteDes());
		p.setEnderecoAmbienteHom(parametrizacao.getEnderecoAmbienteHom());
		
		return p;
	}
	
	/**
	 * Cria labels recuperando textos doo arquivo de propriedades
	 * @param text
	 * @return
	 */
	private JLabel createLabel(String text){
		JLabel label = new JLabel(CBUtil.getMensagem("messages.cyberbank.label.param."+text), alinhamentoLabel);
		label.setBorder(border);
		return label;
	}
	
	/**
	 * Cria botao generico com o texto passado como parametro
	 * @param text
	 * @return
	 */
	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;
		
	}

	/**
	 * Cria botao de processamento com sua respectiva acao
	 * @return
	 */
	private JButton createBtProcessar(){
		
		JButton botao = createBotao(CBUtil.getMensagem("messages.cyberbank.button.process"));
	
		botao.addActionListener(new ActionListener() {
			//listener que eh chamado quando obotao eh pressionado
			@Override
			public void actionPerformed(ActionEvent e) {
				
				//Valida o formulario. Caso nao passe na validacao
				//interrompe o processamento
				if(!validarFormulario()){
					return;
				}
					
				//passando na validacao escreve os valores para o xml que armazena a parametrizacao
				XMLUtil.escreverXML(getParametrizacao(), new File(CBUtil.ARQUIVO_XML));
					
				//exibe mensagem de sucesso
				JOptionPane.showMessageDialog (null, "Alteração realizada com sucesso!", "Parametrização", JOptionPane.INFORMATION_MESSAGE);
			
			}
		});
		
		return botao;
	}

	/**
	 * Cria botao de voltar que retorna para a pagina inicial cancelando qualquer modificacao
	 * @return
	 */
	private JButton createBtCancelar() {
		
		JButton botao = createBotao("voltar");
		
		botao.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				
				PrincipalPage principal = new PrincipalPage();
				Janela.getInstance().show(principal);
				
			}
			
		});
		
		return botao;
	}
	
	/**
	 * Metodo que valida so campos do formulario no momento em que o botao processar eh acionado.
	 */
	private boolean validarFormulario(){
		
		boolean valido = true;
		
		//Iteramos por todos os componentes do painel central
		for(Component c:painelCentral.getComponents()){
			
			JComponent j = (JComponent) c;
			
			//Verificamos os que sao campos de input, invocamos o validador que foi registrado
			//para o campo e chamamos o metodo de verificacao
			if(j instanceof JTextField){
				InputVerifier verifier = j.getInputVerifier();
				if(null != verifier){
					if(valido){
						valido = j.getInputVerifier().verify(j);
					}else{
						j.getInputVerifier().verify(j);
					}
				}
			}
			
		}
		
		return valido;
		
	}

	/**
	 * Cria botao de instrucoes de preenchimento do formulario
	 * @return
	 */
	private JButton createBtInstrucoes() {
		
		JButton botao = createBotao(CBUtil.getMensagem("messages.cyberbank.button.instructions"));
		botao.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				JFrame framepop = new JFrame();
				framepop.setLayout(new BorderLayout());
				
				Dimension dim = new Dimension(680, 600);
				framepop.setSize(dim);
				framepop.setMinimumSize(dim);
				framepop.setMaximumSize(dim);
				framepop.setLocationRelativeTo(null);
				framepop.setResizable(false);
				framepop.setVisible(true);
				
				JPanel panelpop = new JPanel();
				panelpop.setLayout(new BorderLayout());
				panelpop.setVisible(true);
				panelpop.setBackground(Color.YELLOW);
				
				JLabel logoPop = new JLabel(CBUtil.getMensagem("Instruções"));
				logoPop.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 20));
				logoPop.setFont(new Font("Arial", Font.PLAIN, 18));
				logoPop.setForeground(Color.WHITE);
				
				PainelImagem painelTopoPop = new PainelImagem(CBUtil.createImage("images/barra.png"));
				painelTopoPop.setLocation(0, 0);
				painelTopoPop.add(logoPop);
				
				JPanel painelCentralPop = new JPanel();
				painelCentralPop.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));

				JTable table = new JTable(new InstrucoesParametrizacaoModel()){
					
					/**
					 * 
					 */
					private static final long serialVersionUID = 1L;

					public TableCellRenderer getCellRenderer(int row, int column) {
						MultilineTableCell wordWrapRenderer = new MultilineTableCell();
				        if (row <= 8 && column == 2) {
				            return wordWrapRenderer;
				        } else if (row > 8 && row < 13 && column == 3){
				        	return wordWrapRenderer;
				        } else if (row > 13 && column == 2){
				            return wordWrapRenderer;
				        } else {
				        	return super.getCellRenderer(row, column);
				        }
				    }
					
				};
				
				Dimension dim2 = new Dimension(600, 500);
				JScrollPane scrollPane = new JScrollPane(table);
				table.setFillsViewportHeight(true);
				scrollPane.setPreferredSize(dim2);
				
				painelCentralPop.add(scrollPane);
				
				JPanel painelBotaoPop = new JPanel(new GridLayout(1, 3));
				painelBotaoPop.setBorder(BorderFactory.createEmptyBorder(0, 20, 30, 20));
				
				panelpop.add(painelTopoPop, BorderLayout.NORTH);
				panelpop.add(painelCentralPop, BorderLayout.CENTER);

				framepop.add(panelpop);
				
				JButton botao = new JButton("fechar");
				botao.setToolTipText("fechar");
				botao.setBorder(new EmptyBorder(6, 5, 6, 5));
				botao.add(Box.createRigidArea(new Dimension(100, 20)));
								 
				PopupFactory popupFactory = PopupFactory.getSharedInstance();
				Popup popup = popupFactory.getPopup(framepop, botao, 0, 0);
		
				popup.show();
				
			}
		});
		
		return botao;
	}
	
	/**
	 * Inicializao os formatadores numericos do campos de input
	 */
	 private void setUpFormats() {
	    	
        integer4Format = NumberFormat.getIntegerInstance();
        integer4Format.setMaximumIntegerDigits(4);
        integer4Format.setGroupingUsed(false);
        
        integer9Format = NumberFormat.getIntegerInstance();
        integer9Format.setMaximumIntegerDigits(9);
        integer9Format.setGroupingUsed(false);
        
    }
	
	
	
}
