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 javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

/**
 *
 * @author Admin
 */
public class Dialog3_Decrypt extends JPanel {
    private javax.swing.ButtonGroup connectorGroup;
    private javax.swing.JCheckBox jCheckBox1;

    private JPanel contentPanel;
    private JLabel textLabel;
    private JPanel titlePanel;

    private JButton t_vectorButton = new JButton("<html>Vypočítat koeficienty t<sub>1</sub>, ..., t<sub>n</sub><p>a zaokrouhlit je k nejbližšímu celému číslu</p><p>ze vzorce <b>e</b> ≈ <b>t</b><sub>1</sub><b>v</b><sub>1</sub> + ... + <b>t</b><sub>n</sub><b>v</b><sub>n</sub></p></html>");
    private JButton v_vectorButton = new JButton("<html>Vypočítat vektor <b>v</b> z rovnice <p><b>v</b> = <b>v</b><sub>1</sub><b>t</b><sub>1</sub> + ... + <b>v</b><sub>n</sub><b>t</b><sub>n</sub></p></html>");
    private JButton m_vectorButton = new JButton("<html>Vypočítat vektor <b>m</b> z rovnice <p><b>v</b> = <b>m</b><sub>1</sub><b>w</b><sub>1</sub> + ... + <b>m</b><sub>n</sub><b>w</b><sub>n</sub></p></html>");

    private JTextField[] t_data = new JTextField[5];
    private JTextField[] v_grid_data = new JTextField[5];
    private JTextField[] m_decrypted_data = new JTextField[5];

    public Dialog3_Decrypt() {

        super();

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

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

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


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

        textLabel.setBackground(Color.lightGray);
        textLabel.setFont(new Font("MS Sans Serif", Font.BOLD, 15));
        textLabel.setText("3. Dešifrování");
        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 BorderLayout());
        secondaryPanel.add(contentPanel, BorderLayout.NORTH);
        add(secondaryPanel, BorderLayout.CENTER);

    }

    public void addCheckBoxActionListener(ActionListener l) {
        jCheckBox1.addActionListener(l);
    }

    public boolean isCheckBoxSelected() {
        return jCheckBox1.isSelected();
    }

    public String getRadioButtonSelected() {
        return connectorGroup.getSelection().getActionCommand();
    }

    private JPanel getContentPanel() {
        JPanel contentPanel1 = new JPanel(new GridLayout(4,0, 5, 5));

        JPanel t_vectorBorder = new JPanel(new BorderLayout(5,0));
        t_vectorBorder.setBorder(BorderFactory.createTitledBorder("Výpočet koeficientů tn zaokrouhlených k nebližšímu celému číslu ze vzorce e ≈ t1v1 + t2v2 + ...+ tnvn"));
        JPanel t_vector = new JPanel(new GridLayout(1,5,5,5));

        t_vectorBorder.add(t_vector, BorderLayout.WEST);

        t_vector.add(new JLabel("<html><b>t</b><sub>"));
        for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {
            t_data[i] = new JTextField(14);
            t_vector.add(t_data[i]);
        }

        t_vectorBorder.add(t_vectorButton, BorderLayout.EAST);


        JPanel v_vectorBorder = new JPanel(new BorderLayout(5,0));
        v_vectorBorder.setBorder(BorderFactory.createTitledBorder("Výpočet vektoru mříže v = v1t1 + v2t2 + ... + tnvn, který je velmi blízko k vektoru e:"));
        JPanel v_vector = new JPanel(new GridLayout(1,1,5,5));

        v_vectorBorder.add(v_vector, BorderLayout.WEST);

        v_vector.add(new JLabel("<html><b>v</b><sub>", JLabel.LEFT));
        for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {

            v_grid_data[i] = new JTextField(14);
            v_vector.add(v_grid_data[i]);
        }


        v_vectorBorder.add(v_vectorButton, BorderLayout.EAST);


        JPanel m_vectorBorder = new JPanel(new BorderLayout(10,0));
        m_vectorBorder.setBorder(BorderFactory.createTitledBorder("Výpočet m vyjádřením v jako lineární kombinace veřejného klíče, tedy v = m1w1 + m2w2 + ...+mnwn"));
        JPanel m_vector = new JPanel(new GridLayout(1,1,5,5));

        m_vectorBorder.add(m_vector, BorderLayout.WEST);

        m_vector.add(new JLabel("<html><b>m</b><sub>", JLabel.LEFT));
        for (int i = 0; i < GGHData.MAX_DIMENSION; i++) {

            m_decrypted_data[i] = new JTextField(14);
            m_vector.add(m_decrypted_data[i]);
        }


        m_vectorBorder.add(m_vectorButton, BorderLayout.EAST);


        JPanel text_border = new JPanel();
        text_border.setBorder(BorderFactory.createTitledBorder("Stručný teoretický popis šifrovací metody GGH"));

        JLabel jText1 = new JLabel("<html><p><b>Generování klíčů:</b> </p>Alice si zvolí dobrou bázi <b>v</b><sub>1</sub>, ..., <b>v</b><sub>n</sub>, což je její soukromý klíč. Dále si zvolí celočíselnou matici U, jejíž |det U| = ±1." +
                "Potom vypočítá špatnou bázi <b>w</b><sub>1</sub>, ..., <b>w</b><sub>n</sub>, což jsou řady matice W = UV. Dále zveřejní<br> svůj veřejný klíč <b>w</b><sub>1</sub>, ..., <b>w</b><sub>n</sub>.<br>" +
                "<b>Šifrování: </b>" +
                "<p>Bob si zvolí text k zašifrování jako malý vektor <b>m</b>. Poté si zvolí náhodný malý vektor <b>r</b>." +
                "Použije veřejný klíč od Alice k výpočtu vektoru zašifrovaného textu <b>e</b> = <b>m</b>W + <b>r</b>. Pošle zašifrovaný text Alici.</p>" +
                "<b>Dešifrování: </b>" +
                "<p>Alice použije Babaiův algoritmus k výpočtu vektoru <b>v</b> ∈ L, který je nejblíže vektoru <b>e</b>." +
                "Dále Alice vypočítá <b>v</b>W<sup>-1</sup> k obnově vektoru <b>m</b>, tedy původního textu od Boba.</p></html>");

        jText1.setFont(new Font(null , 0, 10));
        text_border.add(jText1);

	contentPanel1.add(t_vectorBorder);
	contentPanel1.add(v_vectorBorder);
        contentPanel1.add(m_vectorBorder);
        contentPanel1.add(text_border);

        FunctionButtonHandler functionHandler = new FunctionButtonHandler();
        t_vectorButton.addActionListener(functionHandler);
        v_vectorButton.addActionListener(functionHandler);
        m_vectorButton.addActionListener(functionHandler);

        return contentPanel1;
    }

    public Matrix get_t_vector() {
        Matrix t_vector = new Matrix(1, GGHData.getInstance().getDimension());

        try {
            for (int i = 0; i < GGHData.getInstance().getDimension(); i++) {
               t_vector.setElement(0, i, Double.valueOf(t_data[i].getText()));               
            }
         }
         catch (NumberFormatException e) {
              return null;
         }

        return t_vector;
    }

    public Matrix get_v_vector() {
        Matrix v_vector = new Matrix(1, GGHData.getInstance().getDimension());

        try {
                for (int i = 0; i < GGHData.getInstance().getDimension(); i++) {
                        v_vector.setElement(0, i, Double.valueOf(v_grid_data[i].getText()));
                }
         }
         catch (NumberFormatException e) {
            return null;
         }

        return v_vector;
    }

    public Matrix get_m_vector() {
        Matrix m_vector = new Matrix(1, GGHData.getInstance().getDimension());

        try {
                for (int i = 0; i < GGHData.getInstance().getDimension(); i++) {
                        m_vector.setElement(0, i, Double.valueOf(m_decrypted_data[i].getText()));
                }
         }
         catch (NumberFormatException e) {
            return null;
         }

        return m_vector;
    }

    private class FunctionButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
        Object src = evt.getSource();
            if (src == t_vectorButton) {
                 compute_t_vector();
            }
            else if (src == v_vectorButton) {
                 compute_v_vector();
            }
            else if (src == m_vectorButton) {
                 compute_m_vector();
            }
        }

        private void compute_t_vector() {
            Matrix t_vector = GGHData.getInstance().compute_t_vector();

            if (t_vector == null)
                return;

            for (int i = 0; i < GGHData.getInstance().getDimension(); i++)
                  t_data[i].setText(String.valueOf(t_vector.getElement(0, i)));

        }

        private void compute_v_vector() {
            Matrix v_grid = GGHData.getInstance().computer_v_grid();

            if (v_grid == null)
                return;
            
            for (int i = 0; i < GGHData.getInstance().getDimension(); i++) {
                  v_grid_data[i].setText(String.valueOf(v_grid.getElement(0, i)));
            }
        }

        private void compute_m_vector() {
            Matrix m_decrypted = GGHData.getInstance().compute_m_decrypted();

            if (m_decrypted == null)
                return;

            for (int i = 0; i < GGHData.getInstance().getDimension(); i++) {
                  m_decrypted_data[i].setText(String.valueOf(m_decrypted.getElement(0, i)));
            }
        }
    }


    public JTextField[] getT_data() {
        return t_data;
    }

    public void setE_data(JTextField[] t_data) {
        this.t_data = t_data;
    }

    public JTextField[] getV_grid_data() {
        return v_grid_data;
    }

    public void setV_grid_data(JTextField[] v_data) {
        this.v_grid_data = v_data;
    }

    public JTextField[] getM_decrypted_data() {
        return m_decrypted_data;
    }

    public void setM_decrypted_data(JTextField[] m_data) {
        this.m_decrypted_data = m_data;
    }


}
