package ggh.dialog;


import flanagan.math.Matrix;
import ggh.GGHData;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

/**
 *
 * @author Admin
 */
public class Dialog1_Start extends JPanel {
    

    private JPanel contentPanel;

    private JLabel textLabel;
    private JPanel titlePanel;

    private int dimensionData = 2;

    private JTextField[][] u_data = new JTextField[5][5];
    private JTextField[][] v_data = new JTextField[5][5];
    private JTextField[][] w_data = new JTextField[5][5];
    private JRadioButton[] dim_bt = new JRadioButton[4];

    private JButton v_sampleButton = new JButton("Vložit vzor");
    private JButton u_sampleButton = new JButton("Vložit vzor");
    private JButton w_vectorButton = new JButton("Vypočítat vektory matice W");

    private JButton v_testButton = new JButton("<html>Otestovat správnost pomocí Hadamardova poměru:<p>H(<b>v</b><sub>1</sub>, ..., <b>v</b><sub>n</sub>) = ( |det L| / (||<b>v</b><sub>1</sub>||∙...∙||<b>v</b><sub>n</sub>||))<sup>1/n</sup>;</p>0.70 ≤ H ≤ 0.95.<p></p></html>");
    private JButton u_testButton = new JButton("Otestovat správnost: |det U| = ±1");


    public Dialog1_Start() {

        super();

        contentPanel = getContentPanel();
        
        contentPanel.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));

        //ImageIcon icon = getImageIcon();

        titlePanel = new javax.swing.JPanel();
        textLabel = new javax.swing.JLabel();

        setLayout(new java.awt.BorderLayout());


        titlePanel.setLayout(new java.awt.BorderLayout());
        titlePanel.setBackground(Color.white);

        textLabel.setBackground(Color.lightGray);
        textLabel.setFont(new Font("MS Sans Serif", Font.BOLD, 15));
        textLabel.setText("1. Generování klíčů");
        textLabel.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));
        textLabel.setOpaque(true);


        titlePanel.add(textLabel, BorderLayout.CENTER);


        add(titlePanel, BorderLayout.NORTH);
        JPanel secondaryPanel = new JPanel(new GridLayout());
        secondaryPanel.add(contentPanel);
        add(secondaryPanel, BorderLayout.CENTER);
    }

    public void addCheckBoxActionListener(ActionListener l) {
        
    }


    private JPanel getContentPanel() {

        JPanel contentPanel1 = new JPanel();
        BoxLayout layout = new BoxLayout(contentPanel1, BoxLayout.Y_AXIS);

        contentPanel1.setLayout(layout);

        JPanel dimension = new JPanel(new GridLayout(0,9));

        dimension.setBorder(BorderFactory.createTitledBorder("Volba dimenze mříže"));
        ButtonGroup group = new ButtonGroup();
        DimensionButtonHandler dimensionHandler = new DimensionButtonHandler();
      
        for (int i = 0; i <= 3; i++) {
            int index = i + 2;
            dim_bt[i] = new JRadioButton(Integer.toString(index));
            if (i == 0)
                dim_bt[i].setSelected(true);

            dim_bt[i].addItemListener(dimensionHandler);
            group.add(dim_bt[i]);
            dimension.add(dim_bt[i]);
        }


        JPanel v_vectorBorder = new JPanel(new BorderLayout(10,0));
        v_vectorBorder.setBorder(BorderFactory.createTitledBorder("Volba docela vzájemně ortogonální množiny lineárně nezávislých vektorů v s celočíselnými koeficienty tvořící matici V (soukromý klíč)"));
        JPanel v_vector = new JPanel(new GridLayout(5,5,5,5));

        JPanel v_buttonBorder = new JPanel(new BorderLayout(10,0));
        v_vectorBorder.add(v_vector, BorderLayout.WEST);
        v_vectorBorder.add(v_buttonBorder, BorderLayout.EAST);


        for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {
            int index = i + 1;

            v_vector.add(new JLabel("<html><b>v</b><sub>" + index + "</sub></html>"));

            for (int j = 0; j < GGHData.MAX_DIMENSION; j++) {
                v_data[i][j] = new JTextField(7);
                if (j > 1 || i > 1)
                    v_data[i][j].setEditable(false);
                v_vector.add(v_data[i][j]);
            }
            
        }

        v_buttonBorder.add(v_sampleButton, BorderLayout.EAST);
        v_buttonBorder.add(v_testButton, BorderLayout.WEST);


        JPanel u_vectorBorder = new JPanel(new BorderLayout(10,0));
        u_vectorBorder.setBorder(BorderFactory.createTitledBorder("Volba celočíselné matice U, jejíž |det(U)| = ±1"));

        JPanel u_vector = new JPanel(new GridLayout(5,5,5,5));

        JPanel u_buttonBorder = new JPanel(new BorderLayout(10,0));
        u_vectorBorder.add(u_vector, BorderLayout.WEST);
        u_vectorBorder.add(u_buttonBorder, BorderLayout.EAST);

       for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {
            int index = i + 1;
            u_vector.add(new JLabel("<html><b>u</b><sub>" + index + "</sub></html>"));

            for (int j = 0; j < GGHData.MAX_DIMENSION; j++) {
                u_data[i][j] = new JTextField(7);
                if (j > 1 || i > 1)
                    u_data[i][j].setEditable(false);
                u_vector.add(u_data[i][j]);
            }

        }


        u_buttonBorder.add(u_sampleButton, BorderLayout.EAST);
        u_buttonBorder.add(u_testButton, BorderLayout.WEST);


        JPanel w_vectorBorder = new JPanel(new BorderLayout(10,0));
        w_vectorBorder.setBorder(BorderFactory.createTitledBorder("Výpočet vektorů jako řad matice W = UV (veřejný klíč)"));
        JPanel w_vector = new JPanel(new GridLayout(5,5,5,5));

        w_vectorBorder.add(w_vector, BorderLayout.WEST);


        for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {
            int index = i + 1;
            w_vector.add(new JLabel("<html><b>w</b><sub>" + index + "</sub></html>"));

            for (int j = 0; j < GGHData.MAX_DIMENSION; j++) {
                w_data[i][j] = new JTextField(7);
                if (j > 1 || i > 1)
                    w_data[i][j].setEditable(false);
                w_vector.add(w_data[i][j]);
            }

        }

        
        w_vectorBorder.add(w_vectorButton, BorderLayout.EAST);


        contentPanel1.add(dimension);
	contentPanel1.add(v_vectorBorder);
	contentPanel1.add(u_vectorBorder);
	contentPanel1.add(w_vectorBorder);

        FunctionButtonHandler functionHandler = new FunctionButtonHandler();
        u_sampleButton.addActionListener(functionHandler);
        v_sampleButton.addActionListener(functionHandler);
        w_vectorButton.addActionListener(functionHandler);

        u_testButton.addActionListener(functionHandler);
        v_testButton.addActionListener(functionHandler);

        return contentPanel1;
    }

    public Matrix get_u_matrix() {
        Matrix u_vector = new Matrix(dimensionData, dimensionData);

        try {
                for (int i = 0; i < dimensionData; i++) {
                    for (int j = 0; j < dimensionData; j++) {
                        u_vector.setElement(i, j, Double.valueOf(u_data[i][j].getText()));
                    }
                }
         }
         catch (NumberFormatException e) {           
            return null;
         }

        return u_vector;
    }

    public Matrix get_v_matrix() {
        Matrix v_vector = new Matrix(dimensionData, dimensionData);

        try {
                for (int i = 0; i < dimensionData; i++) {
                    for (int j = 0; j < dimensionData; j++) {
                        v_vector.setElement(i, j, Double.valueOf(v_data[i][j].getText()));
                    }
                }
         }
         catch (NumberFormatException e) {         
            return null;
         }

        return v_vector;

    }

    public Matrix get_w_matrix() {
        Matrix w_vector = new Matrix(dimensionData, dimensionData);

        try {
                for (int i = 0; i < dimensionData; i++) {
                    for (int j = 0; j < dimensionData; j++) {
                        w_vector.setElement(i, j, Double.valueOf(w_data[i][j].getText()));
                    }
                }
         }
         catch (NumberFormatException e) {          
            return null;
         }

        return w_vector;

    }

    private class FunctionButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
        Object src = evt.getSource();
            if (src == u_sampleButton) {
                 insert_u_vector();
            }
            else if (src == v_sampleButton) {
                 insert_v_vector();
            }
            else if (src == w_vectorButton) {
                 generate_w_vector();
            }
            else if (src == u_testButton) {
                 test_u_vector();
            }
            else if (src == v_testButton) {
                 test_v_vector();
            }
        }

        private void insert_v_vector() {
            Matrix m = GGHData.getInstance().generate_v_vector(dimensionData);

            for (int i = 0; i < dimensionData; i++) {
                for (int j = 0; j < dimensionData; j++)
                    v_data[i][j].setText(String.valueOf(m.getElement(i, j)));
            }
        }

        private void insert_u_vector() {
            Matrix m = GGHData.getInstance().generate_u_vector(dimensionData);

            for (int i = 0; i < dimensionData; i++) {
                for (int j = 0; j < dimensionData; j++)
                    u_data[i][j].setText(String.valueOf(m.getElement(i, j)));
            }
        }

        private void generate_w_vector() {
            Matrix u_vector = get_u_matrix();
            Matrix v_vector = get_v_matrix();

            if (u_vector == null || v_vector == null)
                return;

       
            //nastavit 'u' a 'v' vektor
            GGHData.getInstance().setU_vector(u_vector);
            GGHData.getInstance().setV_vector(v_vector);

            Matrix m = GGHData.getInstance().generate_w_vector(dimensionData);

            for (int i = 0; i < dimensionData; i++) {
                for (int j = 0; j < dimensionData; j++)
                    w_data[i][j].setText(String.valueOf(m.getElement(i, j)));
            }
        }

       private void test_u_vector() {
            Matrix u_vector = get_u_matrix();
            GGHData.getInstance().setU_vector(u_vector);

            if (GGHData.getInstance().check_vector_u() == true) {
                JOptionPane.showMessageDialog(contentPanel, "Vstupní data vektoru u jsou v pořádku.", "Správná data", JOptionPane.INFORMATION_MESSAGE);

            }
            else {
                JOptionPane.showMessageDialog(contentPanel, "Vstupní data vektoru u jsou zadána chybně!", "Chybná data", JOptionPane.ERROR_MESSAGE);
            }
              
       }

       private void test_v_vector() {
            Matrix v_vector = get_v_matrix();

            GGHData.getInstance().setV_vector(v_vector);

            if (GGHData.getInstance().check_vector_v() == true) {
                JOptionPane.showMessageDialog(contentPanel, "Vstupní data vektoru v jsou v pořádku.", "Správná data", JOptionPane.INFORMATION_MESSAGE);

            }
            else {
                JOptionPane.showMessageDialog(contentPanel, "Vstupní data vektoru v jsou zadána chybně!", "Chybná data", JOptionPane.ERROR_MESSAGE);
            }
       }
    }



    private class DimensionButtonHandler implements ItemListener {
         public void itemStateChanged( ItemEvent e ) {
             if (e.getStateChange() == ItemEvent.SELECTED) {
                 JRadioButton rb = (JRadioButton) e.getSource();
                
                 if (rb.getText().compareTo("2") == 0) {
                     dimensionData = 2;
                     showDimension(dimensionData);
                 }
                 else if (rb.getText().compareTo("3") == 0) {
                     dimensionData = 3;
                     showDimension(dimensionData);
                 }
                 else if (rb.getText().compareTo("4") == 0) {
                     dimensionData = 4;
                     showDimension(dimensionData);
                 }
                 else {
                     dimensionData = 5;
                     showDimension(dimensionData);
                 }
             }
             GGHData.getInstance().setDimension(dimensionData);
         }

         private void showDimension(int dimension) {
             for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {
                  for (int j = 0; j < GGHData.MAX_DIMENSION; j++) {
                      u_data[i][j].setEditable(i < dimension && j < dimension);
                      v_data[i][j].setEditable(i < dimension && j < dimension);
                      w_data[i][j].setEditable(i < dimension && j < dimension);
                  }
             }
         }
     }

}
