/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cryptolearning;

import com.sun.rave.web.ui.appbase.AbstractPageBean;
import com.sun.webui.jsf.component.Button;
import com.sun.webui.jsf.component.ImageComponent;
import com.sun.webui.jsf.component.Label;
import com.sun.webui.jsf.component.StaticText;
import java.awt.Component;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlSelectBooleanCheckbox;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.validator.LongRangeValidator;
import javax.swing.JOptionPane;
import logarithm.*;
import core.*;
/**
 * <p>Page bean that corresponds to a similarly named JSP page.  This
 * class contains component definitions (and initialization code) for
 * all components that you have defined on this page, as well as
 * lifecycle methods and event handlers where you may add behavior
 * to respond to incoming events.</p>
 *
 * @version Diffie.java
 * @version Created on 16.2.2009, 10:32:31
 * @author jirka
 */
public class Diffie extends AbstractPageBean {

    private boolean bMITM;

    private void _init() throws Exception {
        ShowMITM(false);


        // levy panel
        txtKlicX.setDisabled(true);
        txtCisloB.setDisabled(true);
        btnVypA.setDisabled(true);
        btnSpojB.setDisabled(true);
        btnVypSdilKlicK.setDisabled(true);

        // velke sipky
        labPrenos1.setVisible(false);
        labPrenos2.setVisible(false);

        // pravy panel
        txtKlicY.setDisabled(true);
        btnVypA1.setDisabled(true);
        btnOdpA.setDisabled(true);
        btnVypSdilKlicK1.setDisabled(true);




    }
    private Label labPrenos1 = new Label();

    public Label getLabPrenos1() {
        return labPrenos1;
    }

    public void setLabPrenos1(Label l) {
        this.labPrenos1 = l;
    }
    private ImageComponent imgArrowBigRight = new ImageComponent();

    public ImageComponent getImgArrowBigRight() {
        return imgArrowBigRight;
    }

    public void setImgArrowBigRight(ImageComponent ic) {
        this.imgArrowBigRight = ic;
    }
    private Label labPrenos2 = new Label();

    public Label getLabPrenos2() {
        return labPrenos2;
    }

    public void setLabPrenos2(Label l) {
        this.labPrenos2 = l;
    }
    private ImageComponent imgArrowBigLeft = new ImageComponent();

    public ImageComponent getImgArrowBigLeft() {
        return imgArrowBigLeft;
    }

    public void setImgArrowBigLeft(ImageComponent ic) {
        this.imgArrowBigLeft = ic;
    }
    private Label labMITM = new Label();

    public Label getLabMITM() {
        return labMITM;
    }

    public void setLabMITM(Label l) {
        this.labMITM = l;
    }
    private Label label19 = new Label();

    public Label getLabel19() {
        return label19;
    }

    public void setLabel19(Label l) {
        this.label19 = l;
    }
    private ImageComponent imgArrowSmallRight = new ImageComponent();

    public ImageComponent getImgArrowSmallRight() {
        return imgArrowSmallRight;
    }

    public void setImgArrowSmallRight(ImageComponent ic) {
        this.imgArrowSmallRight = ic;
    }
    private Label label20 = new Label();

    public Label getLabel20() {
        return label20;
    }

    public void setLabel20(Label l) {
        this.label20 = l;
    }
    private ImageComponent imgArrowSmallLeft = new ImageComponent();

    public ImageComponent getImgArrowSmallLeft() {
        return imgArrowSmallLeft;
    }

    public void setImgArrowSmallLeft(ImageComponent ic) {
        this.imgArrowSmallLeft = ic;
    }
    private Label label11 = new Label();

    public Label getLabel11() {
        return label11;
    }

    public void setLabel11(Label l) {
        this.label11 = l;
    }
    private StaticText labAX = new StaticText();

    public StaticText getLabAX() {
        return labAX;
    }

    public void setLabAX(StaticText st) {
        this.labAX = st;
    }
    private Label label12 = new Label();

    public Label getLabel12() {
        return label12;
    }

    public void setLabel12(Label l) {
        this.label12 = l;
    }
    private StaticText lab_B = new StaticText();

    public StaticText getLab_B() {
        return lab_B;
    }

    public void setLab_B(StaticText st) {
        this.lab_B = st;
    }
    private Label label10 = new Label();

    public Label getLabel10() {
        return label10;
    }

    public void setLabel10(Label l) {
        this.label10 = l;
    }
    private StaticText labSA = new StaticText();

    public StaticText getLabSA() {
        return labSA;
    }

    public void setLabSA(StaticText st) {
        this.labSA = st;
    }
    private Label label14 = new Label();

    public Label getLabel14() {
        return label14;
    }

    public void setLabel14(Label l) {
        this.label14 = l;
    }
    private StaticText labBY = new StaticText();

    public StaticText getLabBY() {
        return labBY;
    }

    public void setLabBY(StaticText st) {
        this.labBY = st;
    }
    private Label label15 = new Label();

    public Label getLabel15() {
        return label15;
    }

    public void setLabel15(Label l) {
        this.label15 = l;
    }
    private StaticText lab_A = new StaticText();

    public StaticText getLab_A() {
        return lab_A;
    }

    public void setLab_A(StaticText st) {
        this.lab_A = st;
    }
    private Label label16 = new Label();

    public Label getLabel16() {
        return label16;
    }

    public void setLabel16(Label l) {
        this.label16 = l;
    }
    private StaticText labSB = new StaticText();

    public StaticText getLabSB() {
        return labSB;
    }

    public void setLabSB(StaticText st) {
        this.labSB = st;
    }
    private Label label21 = new Label();

    public Label getLabel21() {
        return label21;
    }

    public void setLabel21(Label l) {
        this.label21 = l;
    }
    private ImageComponent imgArrowSmallRight1 = new ImageComponent();

    public ImageComponent getImgArrowSmallRight1() {
        return imgArrowSmallRight1;
    }

    public void setImgArrowSmallRight1(ImageComponent ic) {
        this.imgArrowSmallRight1 = ic;
    }
    private Label label22 = new Label();

    public Label getLabel22() {
        return label22;
    }

    public void setLabel22(Label l) {
        this.label22 = l;
    }
    private ImageComponent imgArrowSmallLeft1 = new ImageComponent();

    public ImageComponent getImgArrowSmallLeft1() {
        return imgArrowSmallLeft1;
    }

    public void setImgArrowSmallLeft1(ImageComponent ic) {
        this.imgArrowSmallLeft1 = ic;
    }
    private Button btnSpojB = new Button();

    public Button getBtnSpojB() {
        return btnSpojB;
    }

    public void setBtnSpojB(Button b) {
        this.btnSpojB = b;
    }
    private HtmlInputText txtCisloB = new HtmlInputText();

    public HtmlInputText getTxtCisloB() {
        return txtCisloB;
    }

    public void setTxtCisloB(HtmlInputText hit) {
        this.txtCisloB = hit;
    }
    private HtmlInputText txtKlicX = new HtmlInputText();

    public HtmlInputText getTxtKlicX() {
        return txtKlicX;
    }

    public void setTxtKlicX(HtmlInputText hit) {
        this.txtKlicX = hit;
    }
    private Button btnVypA = new Button();

    public Button getBtnVypA() {
        return btnVypA;
    }

    public void setBtnVypA(Button b) {
        this.btnVypA = b;
    }
    private Button btnVypSdilKlicK = new Button();

    public Button getBtnVypSdilKlicK() {
        return btnVypSdilKlicK;
    }

    public void setBtnVypSdilKlicK(Button b) {
        this.btnVypSdilKlicK = b;
    }
    private HtmlInputText txtKlicY = new HtmlInputText();

    public HtmlInputText getTxtKlicY() {
        return txtKlicY;
    }

    public void setTxtKlicY(HtmlInputText hit) {
        this.txtKlicY = hit;
    }
    private Button btnVypA1 = new Button();

    public Button getBtnVypA1() {
        return btnVypA1;
    }

    public void setBtnVypA1(Button b) {
        this.btnVypA1 = b;
    }
    private Button btnOdpA = new Button();

    public Button getBtnOdpA() {
        return btnOdpA;
    }

    public void setBtnOdpA(Button b) {
        this.btnOdpA = b;
    }
    private Button btnVypSdilKlicK1 = new Button();

    public Button getBtnVypSdilKlicK1() {
        return btnVypSdilKlicK1;
    }

    public void setBtnVypSdilKlicK1(Button b) {
        this.btnVypSdilKlicK1 = b;
    }
    private StaticText labN = new StaticText();

    public StaticText getLabN() {
        return labN;
    }

    public void setLabN(StaticText st) {
        this.labN = st;
    }
    private StaticText labA = new StaticText();

    public StaticText getLabA() {
        return labA;
    }

    public void setLabA(StaticText st) {
        this.labA = st;
    }
    private StaticText labB = new StaticText();

    public StaticText getLabB() {
        return labB;
    }

    public void setLabB(StaticText st) {
        this.labB = st;
    }
    private StaticText labPN = new StaticText();

    public StaticText getLabPN() {
        return labPN;
    }

    public void setLabPN(StaticText st) {
        this.labPN = st;
    }
    private StaticText labPB = new StaticText();

    public StaticText getLabPB() {
        return labPB;
    }

    public void setLabPB(StaticText st) {
        this.labPB = st;
    }
    private HtmlInputText txtRadGrupy = new HtmlInputText();

    public HtmlInputText getTxtRadGrupy() {
        return txtRadGrupy;
    }

    public void setTxtRadGrupy(HtmlInputText hit) {
        this.txtRadGrupy = hit;
    }
    private LongRangeValidator longRangeValidator1 = new LongRangeValidator();

    public LongRangeValidator getLongRangeValidator1() {
        return longRangeValidator1;
    }

    public void setLongRangeValidator1(LongRangeValidator lrv) {
        this.longRangeValidator1 = lrv;
    }
    private Button btnVypN = new Button();

    public Button getBtnVypN() {
        return btnVypN;
    }

    public void setBtnVypN(Button b) {
        this.btnVypN = b;
    }
    private StaticText labZakB = new StaticText();

    public StaticText getLabZakB() {
        return labZakB;
    }

    public void setLabZakB(StaticText st) {
        this.labZakB = st;
    }
    private StaticText labSdilKlicK = new StaticText();

    public StaticText getLabSdilKlicK() {
        return labSdilKlicK;
    }

    public void setLabSdilKlicK(StaticText st) {
        this.labSdilKlicK = st;
    }
    private StaticText labSdilKlicK1 = new StaticText();

    public StaticText getLabSdilKlicK1() {
        return labSdilKlicK1;
    }

    public void setLabSdilKlicK1(StaticText st) {
        this.labSdilKlicK1 = st;
    }
    private HtmlSelectBooleanCheckbox cboMITM = new HtmlSelectBooleanCheckbox();

    public HtmlSelectBooleanCheckbox getCboMITM() {
        return cboMITM;
    }

    public void setCboMITM(HtmlSelectBooleanCheckbox hsbc) {
        this.cboMITM = hsbc;
    }
    private Button btnBack = new Button();

    public Button getBtnBack() {
        return btnBack;
    }

    public void setBtnBack(Button b) {
        this.btnBack = b;
    }
    private Button btnFwd = new Button();

    public Button getBtnFwd() {
        return btnFwd;
    }

    public void setBtnFwd(Button b) {
        this.btnFwd = b;
    }
    private Button btnSkip = new Button();

    public Button getBtnSkip() {
        return btnSkip;
    }

    public void setBtnSkip(Button b) {
        this.btnSkip = b;
    }
    private StaticText labPopis = new StaticText();

    public StaticText getLabPopis() {
        return labPopis;
    }

    public void setLabPopis(StaticText st) {
        this.labPopis = st;
    }
    private StaticText labKrok = new StaticText();

    public StaticText getLabKrok() {
        return labKrok;
    }

    public void setLabKrok(StaticText st) {
        this.labKrok = st;
    }
    private StaticText hiddenCislo = new StaticText();

    public StaticText getHiddenCislo() {
        return hiddenCislo;
    }

    public void setHiddenCislo(StaticText st) {
        this.hiddenCislo = st;
    }
    private HtmlInputText txtOdp1 = new HtmlInputText();

    public HtmlInputText getTxtOdp1() {
        return txtOdp1;
    }

    public void setTxtOdp1(HtmlInputText hit) {
        this.txtOdp1 = hit;
    }
    private HtmlInputText txtOdp2 = new HtmlInputText();

    public HtmlInputText getTxtOdp2() {
        return txtOdp2;
    }

    public void setTxtOdp2(HtmlInputText hit) {
        this.txtOdp2 = hit;
    }
    private HtmlInputText txtOdp3 = new HtmlInputText();

    public HtmlInputText getTxtOdp3() {
        return txtOdp3;
    }

    public void setTxtOdp3(HtmlInputText hit) {
        this.txtOdp3 = hit;
    }
    private StaticText labO1 = new StaticText();

    public StaticText getLabO1() {
        return labO1;
    }

    public void setLabO1(StaticText st) {
        this.labO1 = st;
    }
    private StaticText labO2 = new StaticText();

    public StaticText getLabO2() {
        return labO2;
    }

    public void setLabO2(StaticText st) {
        this.labO2 = st;
    }
    private StaticText labO3 = new StaticText();

    public StaticText getLabO3() {
        return labO3;
    }

    public void setLabO3(StaticText st) {
        this.labO3 = st;
    }
    private HtmlInputText txtOdp4 = new HtmlInputText();

    public HtmlInputText getTxtOdp4() {
        return txtOdp4;
    }

    public void setTxtOdp4(HtmlInputText hit) {
        this.txtOdp4 = hit;
    }
    private HtmlInputText txtOdp5 = new HtmlInputText();

    public HtmlInputText getTxtOdp5() {
        return txtOdp5;
    }

    public void setTxtOdp5(HtmlInputText hit) {
        this.txtOdp5 = hit;
    }
    private HtmlInputText txtOdp6 = new HtmlInputText();

    public HtmlInputText getTxtOdp6() {
        return txtOdp6;
    }

    public void setTxtOdp6(HtmlInputText hit) {
        this.txtOdp6 = hit;
    }
    private StaticText labO4 = new StaticText();

    public StaticText getLabO4() {
        return labO4;
    }

    public void setLabO4(StaticText st) {
        this.labO4 = st;
    }
    private StaticText labO5 = new StaticText();

    public StaticText getLabO5() {
        return labO5;
    }

    public void setLabO5(StaticText st) {
        this.labO5 = st;
    }
    private StaticText labO6 = new StaticText();

    public StaticText getLabO6() {
        return labO6;
    }

    public void setLabO6(StaticText st) {
        this.labO6 = st;
    }

    // </editor-fold>
    /**
     * <p>Construct a new Page bean instance.</p>
     */
    public Diffie() {
    }

    /**
     * <p>Callback method that is called whenever a page is navigated to,
     * either directly via a URL, or indirectly via page navigation.
     * Customize this method to acquire resources that will be needed
     * for event handlers and lifecycle methods, whether or not this
     * page is performing post back processing.</p>
     * 
     * <p>Note that, if the current request is a postback, the property
     * values of the components do <strong>not</strong> represent any
     * values submitted with this request.  Instead, they represent the
     * property values that were saved for this view when it was rendered.</p>
     */
    @Override
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here

        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("template Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e : new FacesException(e);
        }

    // </editor-fold>
    // Perform application initialization that must complete
    // *after* managed components are initialized
    // TODO - add your own initialization code here
    }

    /**
     * <p>Callback method that is called after the component tree has been
     * restored, but before any event processing takes place.  This method
     * will <strong>only</strong> be called on a postback request that
     * is processing a form submit.  Customize this method to allocate
     * resources that will be required in your event handlers.</p>
     */
    @Override
    public void preprocess() {
    }

    /**
     * <p>Callback method that is called just before rendering takes place.
     * This method will <strong>only</strong> be called for the page that
     * will actually be rendered (and not, for example, on a page that
     * handled a postback and then navigated to a different page).  Customize
     * this method to allocate resources that will be required for rendering
     * this page.</p>
     */
    @Override
    public void prerender() {
    }

    /**
     * <p>Callback method that is called after rendering is completed for
     * this request, if <code>init()</code> was called (regardless of whether
     * or not this was the page that was actually rendered).  Customize this
     * method to release resources acquired in the <code>init()</code>,
     * <code>preprocess()</code>, or <code>prerender()</code> methods (or
     * acquired during execution of an event handler).</p>
     */
    @Override
    public void destroy() {
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected SessionBean1 getSessionBean1() {
        return (SessionBean1) getBean("SessionBean1");
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected ApplicationBean1 getApplicationBean1() {
        return (ApplicationBean1) getBean("ApplicationBean1");
    }

    /**
     * Skryje popr. zobrazi komponenty pro Man in the middle
     */
    private void ShowMITM(boolean show) {
        label10.setVisible(show);
        label11.setVisible(show);
        label12.setVisible(show);
        label14.setVisible(show);
        label15.setVisible(show);
        label16.setVisible(show);
        label19.setVisible(show);
        label20.setVisible(show);
        label21.setVisible(show);
        label22.setVisible(show);

        labMITM.setVisible(show);

        imgArrowSmallLeft.setVisible(show);
        imgArrowSmallLeft1.setVisible(show);
        imgArrowSmallRight.setVisible(show);
        imgArrowSmallRight1.setVisible(show);

        labAX.setVisible(show);
        lab_B.setVisible(show);
        lab_A.setVisible(show);
        labBY.setVisible(show);
        labSA.setVisible(show);
        labSB.setVisible(show);

    }

    public String btnSpojB_action() {
        boolean bCboMITMSet = cboMITM.isSelected();
        int n = Integer.parseInt(labN.getText().toString());
        int b = Integer.parseInt(txtCisloB.getValue().toString());

        if (bCboMITMSet) {
            int iRange = n - 3;
            // generovani soukromych klicu s A (AX) a s B (BY)
            Integer iKlicAX = (int) (Math.abs(Math.random()) * iRange + 1);
            Integer iKlicBY = (int) (Math.abs(Math.random()) * iRange + 1);

            // vypocita zaklady
            Integer origA = Integer.parseInt(labA.getText().toString());
            // Integer B = (int) (myExp(b, iKlicAX) % n);
            Integer B = SuperModulo.Modulo(b, iKlicAX, n);
            //Integer A = (int) (myExp(b, iKlicBY) % n);
            Integer A = SuperModulo.Modulo(b, iKlicBY, n);
            // vypocita klice
            
            //Integer sdilKlicA = (int) (myExp(origA, iKlicAX) % n);
            Integer sdilKlicA = SuperModulo.Modulo(origA, iKlicAX, n);

            // nastaveni hodnot
            labAX.setText(iKlicAX.toString());
            lab_B.setText(B.toString());
            labSA.setText(sdilKlicA.toString());

            labBY.setText(iKlicBY.toString());
            lab_A.setText(A.toString());
        }
        else{
            labPrenos1.setVisible(true);
            imgArrowBigRight.setVisible(true);
        }


        labPN.setText(labN.getText().toString());
        labPB.setText(txtCisloB.getValue().toString());

        ShowMITM(bCboMITMSet);
        imgArrowSmallLeft1.setVisible(false);
        label22.setVisible(false);
        txtKlicY.setDisabled(false);
        btnVypA1.setDisabled(false);
        btnSpojB.setDisabled(true);
        cboMITM.setDisabled(true);

        return null;
    }

    public String btnVypN_action() {
        // kontrola vstupu
        String str = txtRadGrupy.getValue().toString();
        if (!IsNumber(str) || !IsPrime(str)) {
            JOptionPane.showMessageDialog(null, "Zadaná hodnota není prvočíslo");
            return null;
        }
        // vypocita cislo n
        Integer p = Integer.parseInt(str);
        Integer n = 2 * p + 1;
        str = n.toString();
        if (!IsPrime(str)){
            JOptionPane.showMessageDialog(null, "Zkuste jiné prvočíslo, je třeba splnit podmínku 2.p+1 je rovno prvočíslu");
            labN.setText("??");
        }
        else{
            labN.setText(n.toString());

        // zapne dalsi ovladaci prvky
            txtCisloB.setDisabled(false);
            txtKlicX.setDisabled(false);
            btnVypA.setDisabled(false);

        // vypne svoje ovladaci prvky
            btnVypN.setDisabled(true);
            txtRadGrupy.setDisabled(true);
        }
        

        return null;
    }

    private boolean IsNumber(String str) {
        if (str.length() == 0) {
            return false;
        }
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) < '0' || str.charAt(i) > '9') {
                return false;
            }
        }

        return true;
    }

    private boolean IsPrime(String str) {
        if (str.length() == 0) {
            return false;
        }
        PrimeGen gen = new PrimeGen(0, 100);
        Integer iNo = Integer.parseInt(str);
        return gen.isPrime(iNo);
    }

    private boolean CheckString(String str) {
        return (IsNumber(str) && IsPrime(str));
    }

    private Double myExp(int a, int exp) {
        Double res = 1.0;
        for (int i = exp; i > 0; i--) {
            res *= a;
        }
        return res;
    }

    public String btnVypA_action() {
        // kontrola vstupu
        String strB = txtCisloB.getValue().toString();
        String strX = txtKlicX.getValue().toString();
        Integer n = Integer.parseInt(labN.getText().toString());
        Integer b = 0;
        Integer x = 0;
        if (IsNumber(strB)) {
            b = Integer.parseInt(strB);
            x = Integer.parseInt(strX);

            // vypocita A
            //Double bNax = myExp(b, x);
            int dA = SuperModulo.Modulo(b, x, n);
       //     Integer A = Integer.parseInt(dA.toString());
        //      labA.setText(dA.toString());
            labA.setText(dA);

            // zapne dalsi ovladaci prvky
            btnSpojB.setDisabled(false);
            cboMITM.setDisabled(false);

            // vypne svoje prvky
            btnVypA.setDisabled(true);
            txtKlicX.setDisabled(true);
            txtCisloB.setDisabled(true);
        }
        if (!IsNumber(strB) || b > n - 2 || b < 1) {
            JOptionPane.showMessageDialog(null, "Chybná hodnota čísla b");
            return null;
        }
        if (!KlicOk(strX)) {
            JOptionPane.showMessageDialog(null, "Chybná hodnota klíče X");
            return null;
        }

        return null;
    }

    private boolean KlicOk(String klicX) {
        Integer n = Integer.parseInt(labN.getText().toString());
        if (klicX.length() == 0) {
            return false;
        }
        Integer iKlic = Integer.parseInt(klicX);
        if (iKlic < 1 || iKlic > n - 2) {
            return false;
        }
        return true;
    }

    public String btnVypA1_action() {
        // kontrola vstupu
        String klic = txtKlicY.getValue().toString();
        if (!KlicOk(klic)) {
            JOptionPane.showMessageDialog(null, "Chybný formát klíče Y.");
            return null;
        }

        // vypocita B
        Integer y = Integer.parseInt(klic);
        Integer b = Integer.parseInt(txtCisloB.getValue().toString());
        Integer n = Integer.parseInt(labN.getText().toString());
        //Integer B = (int) (myExp(b, y) % n);
        int B = SuperModulo.Modulo(b, y, n);
        labB.setText(B);

        // zapne dalsi ovladaci prvky
        btnOdpA.setDisabled(false);
        txtKlicY.setDisabled(true);
        btnVypA1.setDisabled(true);
        btnVypSdilKlicK1.setDisabled(false);
        return null;
    }

    public String btnOdpA_action() {
        btnVypSdilKlicK.setDisabled(false);
        
        btnOdpA.setDisabled(true);

        boolean bCboMITMSet = cboMITM.isSelected();
        if (bCboMITMSet) {
            Integer B = Integer.parseInt(labB.getText().toString());
            Integer iKlicBY = Integer.parseInt(labBY.getText().toString());
            Integer n = Integer.parseInt(labN.getText().toString());
           // Integer sdilKlicB = (int) (myExp(B, iKlicBY) % n);
            Integer sdilKlicB = SuperModulo.Modulo(B, iKlicBY, n);
            labSB.setText(sdilKlicB.toString());
            labZakB.setText(lab_B.getText());
            imgArrowSmallLeft1.setVisible(true);
            label22.setVisible(true);
        } else {
            labZakB.setText(labB.getText().toString());
            labPrenos2.setVisible(true);
            imgArrowBigLeft.setVisible(true);
        }

        return null;
    }

    public String btnVypSdilKlicK_action() {
        Integer B = Integer.parseInt(labZakB.getText().toString());
        Integer n = Integer.parseInt(labN.getText().toString());
        Integer x = Integer.parseInt(txtKlicX.getValue().toString());
        //Integer sdilKlic = (int) (myExp(B, x) % n);
        Integer sdilKlic = SuperModulo.Modulo(B, x, n);
        labSdilKlicK.setText(sdilKlic.toString());
        btnVypSdilKlicK1.setDisabled(false);
        btnVypSdilKlicK.setDisabled(true);
        return null;
    }

    public String btnVypSdilKlicK1_action() {
        Integer A = 0;

        if (cboMITM.isSelected()) {
            A = Integer.parseInt(lab_A.getText().toString());
        } else {
            A = Integer.parseInt(labA.getText().toString());
        }

        Integer n = Integer.parseInt(labN.getText().toString());
        Integer y = Integer.parseInt(txtKlicY.getValue().toString());
        //Integer sdilKlic = (int) (myExp(A, y) % n);
        Integer sdilKlic = SuperModulo.Modulo(A, y, n);
        labSdilKlicK1.setText(sdilKlic.toString());
        btnVypSdilKlicK1.setDisabled(true);
        return null;
    }

    public String btnSkip_action() {
        labKrok.setVisible(false);
        ClearFields();
        btnBack.setDisabled(true);
        btnFwd.setDisabled(true);
        //btnSkip.setDisabled(true);
        btnSkip.setText("Restart okna");
        btnVypN.setDisabled(false);
        txtRadGrupy.setDisabled(false);

        cboMITM.setSelected(false);
        ShowMITM(false);
        imgArrowBigLeft.setVisible(false);
        imgArrowBigRight.setVisible(false);
        labPrenos1.setVisible(false);
        labPrenos2.setVisible(false);

        return null;
    }

    private void ClearFields() {
        ///////////////////////////////////////////////
        // text prvni zpravy
        String zprava = "Diffie-Hellmanův protokol je protokolem pro ustavení tajného klíče mezi dvěma komunikujícími entitami. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.";
        labPopis.setText(zprava);
        ///////////////////////////////////////////////

        txtCisloB.setValue("??");
        txtKlicX.setValue("??");
        labA.setText("??");
        txtRadGrupy.setValue("??");
        txtKlicY.setValue("??");
        labPN.setText("??");
        labN.setText("??");
        labPB.setText("??");
        labB.setText("??");
        labZakB.setText("??");
        labSdilKlicK.setText("??");
        labSdilKlicK1.setText("??");
        labKrok.setText("Krok 1:");
        hiddenCislo.setText(0);
    }

    private void PerformStep(boolean forward) {
        int krok = Integer.parseInt(hiddenCislo.getValue().toString());

        ////////////////////////////////////////////////
        // nastavit pocet kroku
        int pocetKroku = 13;
        ////////////////////////////////////////////////

        labKrok.setText("Krok -1:");

        if (forward) {
            krok = Math.min(pocetKroku, krok + 1);
        } else {
            krok = Math.max(0, krok - 1);
        }

        ////////////////////////////////////////////////
        // zprava se zobrazi uzivateli po provedeni kazdeho kroku       
        String zprava = "";
        // hodnota slouzi pro predani zvolene hodnoty do prislusneho pole
        String hodnota;
        ////////////////////////////////////////////////

        switch (krok - 1) {
            case -1:
                if (!forward) {
                    btnBack.setDisabled(true);
                    txtRadGrupy.setValue("??");
                    labN.setText("??");
                    labKrok.setVisible(false);
                    zprava ="Diffie-Hellmanův protokol je protokolem pro ustavení tajného klíče mezi dvěma komunikujícími entitami. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.";
                }
                break;
            case 0:
                btnBack.setDisabled(false);
                zprava = "Na začátku komunikace určí uživatel řád cyklické grupy, ve které se budou provádět výpočty šifrování. Aby byla zajištěna bezpečnost systému, mělo by jít o velké prvočíslo, viz kapitola \"Diskrétní logaritmus\"";
                labKrok.setVisible(true);
                hodnota = "11";
                txtRadGrupy.setValue(hodnota);
                hodnota = "23";
                labN.setText(hodnota);
                if (!forward) {
                    txtCisloB.setValue("??");
                    txtKlicX.setValue("??");
                    labA.setText("??");
                }
                break;
            case 1:
                zprava = "Ze zvolené grupy si uživatel určí dvě libovolná čísla. Jendo z nich bude sloužit jako generátor a druhé jako soukromý klíč. I když to není bezpodmínečně nutné, jako generátor se zpravidla volí prvočíslo. Z těchto hodnot pak vypočte základ A, které bude předávat uživateli se kterým navazuje komunikaci.";
                hodnota = "7";
                txtCisloB.setValue(hodnota);
                hodnota = "12";
                txtKlicX.setValue(hodnota);
                hodnota = "16";
                labA.setText(hodnota);
                if (!forward) {
                    
                    labPN.setText("??");
                    labPB.setText("??");
                    imgArrowBigRight.setVisible(false);
                    labPrenos1.setVisible(false);
                }
                break;
            case 2:
                zprava = "Iniciátor sppojení naváže komunikaci s druhým uživatelem a předá mu svůj veřejný klíč. Ten je tvořen parametry n, b, A. Z těchto parametrů nelze zpětně vypočítat soukromý klíč x díky obtížnosti řešení diskrétního logaritmu, proto je lze přenášet nezabezpečeným způsobem.";
                imgArrowBigRight.setVisible(true);
                labPrenos1.setVisible(true);
                
                hodnota = "23";
                labPN.setText(hodnota);
                hodnota = "7";
                labPB.setText(hodnota);

                if (!forward) {
                    labB.setText("??");
                    txtKlicY.setValue("??");
                }
                break;
            case 3:
                zprava = "Druhý uživatel si zvolí vlastní soukromý klíč v cyklické grupě, jejíž řád obdržel od prvního uživatele a vypočte svůj základ B. ";
                hodnota = "6";
                txtKlicY.setValue(hodnota);
                hodnota = "4";
                labB.setText(hodnota);
                if (!forward) {
                    labZakB.setText("??");
                    labSdilKlicK1.setText("??");
                    imgArrowBigLeft.setVisible(false);
                    labPrenos2.setVisible(false);
                }
                break;
            case 4:
                zprava = "Nyní druhý uživatel předá svůj základ B prvnímu uživateli. Protože již zná všechny potřebné parametry, umocnění obdržený základ A svým soukromým klíčem a určí zbytek po celočíselném dělení řádem grupy. Tento zbytek je tajným sdíleným klíčem mezi oběma uživately.";
                imgArrowBigLeft.setVisible(true);
                labPrenos2.setVisible(true);
                hodnota = "4";
                labZakB.setText(hodnota);
                labSdilKlicK1.setText(hodnota);
                if (!forward) {
                    labSdilKlicK.setText("??");
                }
                break;
            case 5:
                zprava = "První uživatel si nyní z obdrženého parametru B vypočte tajný sdílený klíč k, který použije k šifrování přenášených zpráv zpravidla některou ze symetrických šifrovacích metod.";
                hodnota = "4";
                labSdilKlicK.setText(hodnota);
                if (!forward) {
                    ShowMITM(false);
                    cboMITM.setSelected(false);
                    imgArrowBigLeft.setVisible(true);
                    labPrenos2.setVisible(true);
                    imgArrowBigRight.setVisible(true);
                    labPrenos1.setVisible(true);

                     txtCisloB.setValue("7");
                    txtKlicX.setValue("12");
                    labA.setText("16");
                    txtRadGrupy.setValue("11");
                    txtKlicY.setValue("5");
                    labPN.setText("23");
                    labN.setText("23");
                    labPB.setText("7");
                    labB.setText("4");
                    labZakB.setText("4");
                    labSdilKlicK.setText("4");
                    labSdilKlicK1.setText("4");
                }
                break;
            case 6:
                zprava = "Velkou slabinou Diffie-Hellmanova protokolu je zranitelnost útokem \"Man In the Middle\". v tomto případě se útočník vloží na začátku komunikace mezi oba účastníky a postupuje způsobem popsaným dále.";
                cboMITM.setSelected(true);
                ShowMITM(true);
                imgArrowBigLeft.setVisible(false);
                labPrenos2.setVisible(false);
                imgArrowBigRight.setVisible(false);
                labPrenos1.setVisible(false);
                                   
                label19.setVisible(false);
                label20.setVisible(false);
                label21.setVisible(false);
                label22.setVisible(false);

                imgArrowSmallLeft.setVisible(false);
                imgArrowSmallLeft1.setVisible(false);
                imgArrowSmallRight.setVisible(false);
                imgArrowSmallRight1.setVisible(false);

                txtCisloB.setValue("??");
                txtKlicX.setValue("??");
                labA.setText("??");
                txtRadGrupy.setValue("??");
                txtKlicY.setValue("??");
                labPN.setText("??");
                labN.setText("??");
                labPB.setText("??");
                labB.setText("??");
                labZakB.setText("??");
                labSdilKlicK.setText("??");
                labSdilKlicK1.setText("??");
                if (!forward) {
                    label19.setVisible(false);
                    imgArrowSmallRight.setVisible(false);
                    txtRadGrupy.setValue("??");
                    labN.setText("??");
                    txtCisloB.setValue("??");
                    txtKlicX.setValue("??");
                    labA.setText("??");
                }
                break;
            case 7:
                zprava = "Komunikace ze strany uživatele je naprosto stejná. Uživatel zvolí velikost cyklické grupy, určí generátor a svůj soukromý klíč. Vygeneruje základ A a odešle druhému uživateli. Komunikace je však zachycena útočníkem a původní paket s veřejným klíčem se nedostane k zamýšlenému příjemci.";
                label19.setVisible(true);
                imgArrowSmallRight.setVisible(true);
                txtRadGrupy.setValue("11");
                labN.setText("23");
                txtCisloB.setValue("7");
                txtKlicX.setValue("12");
                labA.setText("16");
                if (!forward) {
                    label20.setVisible(false);
                    imgArrowSmallLeft.setVisible(false);

                    labAX.setText("??");
                    lab_B.setText("??");
                    labSA.setText("??");
                    labZakB.setText("??");
                }
                break;
           case 8:
                zprava = "Útočník zvolí vlastní soukromý klíč pro komunikaci s prvním uživatelem, vypočte vlastní základ B', který podvrhe uživateli, který se s ním spojil. Vypočte si tajný soukromý klíč pro komunikaci s tímto uživatelem. ";
                label20.setVisible(true);
                imgArrowSmallLeft.setVisible(true);

                labAX.setText("11");
                lab_B.setText("22");
                labSA.setText("1");
                labZakB.setText("22");
                if (!forward) {
                    label21.setVisible(false);
                    imgArrowSmallRight1.setVisible(false);

                    labSdilKlicK.setText("??");

                    labBY.setText("??");
                    lab_A.setText("??");
                }
                break;
           case 9:
                zprava = "Zatímco uživatel počítá sdílený tajný klíč, útočník si zvolí další tajný klíč, tentokrát pro komunikaci s druhým uživatelem, který zatím o spojení ani neví. Vypočte si nový základ A' a odešle informace danému uživateli. Zda použije stejnou cyklickou grupu, jako navrhl původní uživatel, není důležité, jde vlastně o nové nezávislé spojení.";
                label21.setVisible(true);
                imgArrowSmallRight1.setVisible(true);

                labSdilKlicK.setText("1");

                labBY.setText("14");
                lab_A.setText("2");
                if (!forward) {
                    label22.setVisible(false);
                    imgArrowSmallLeft1.setVisible(false);

                    labPN.setText("??");
                    labPB.setText("??");
                    txtKlicY.setValue("??");
                    labB.setText("??");
                    labSdilKlicK1.setText("??");
                }
                break;
           case 10:
                zprava = "Druhý uživatel obdrží informace o veřejném klíči od útočníka, kterého považuje za normálního uživatele. Zvolí si soukromý klíč, určí sdílený tajný klíč, vypočte svůj základ B, a odpoví iniciátorovi spojení";
                label22.setVisible(true);
                imgArrowSmallLeft1.setVisible(true);

                labPN.setText("23");
                labPB.setText("7");
                txtKlicY.setValue("17");
                labB.setText("19");
                labSdilKlicK1.setText("18");

                if (!forward) {
                    labSB.setText("??");
                    btnFwd.setText("Další");
                }
                break;
           case 11:
                zprava = "Poslední co ještě útočníkovi zbývá udělat je vypočítat sdílený tajný klíč pro komunikaci s druhým uživatelem. Pak je schopen předávat komunikaci od jednoho uživatele k druhému tak, že vždy zprávu dešifruje klíčem, který si domluvil s uživatelem a zašifrovat klíčem, který si domluvil s druhým uživatelem. Je tedy schopen vyměňované zprávy jak číst, tak případně upravovat.";
                labSB.setText("18");
                btnFwd.setText("Konec");
                if (!forward) {
                }
                break;
           case 12:
               ClearFields();
               labKrok.setVisible(false);
               zprava ="Diffie-Hellmanův protokol je protokolem pro ustavení tajného klíče mezi dvěma komunikujícími entitami. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.";
               btnSkip.setText("Restart okna");
               btnFwd.setText("Další");
                btnBack.setDisabled(true);
                btnFwd.setDisabled(true);
                //btnSkip.setDisabled(true);
                btnVypN.setDisabled(false);
                txtRadGrupy.setDisabled(false);

                cboMITM.setSelected(false);
                ShowMITM(false);

                labAX.setText("??");
                labBY.setText("??");
                lab_A.setText("??");
                lab_B.setText("??");
                labSA.setText("??");
                labSB.setText("??");

                break;
        }

        hiddenCislo.setValue(krok);
        labKrok.setText("Krok " + (krok - 1) + ":");
        labPopis.setText(zprava);
    }

    public String btnFwd_action() {
        PerformStep(true);
        return null;
    }

    public String btnBack_action() {
        PerformStep(false);
        return null;
    }

    public String button1_action() {
        btnBack.setDisabled(true);
        labKrok.setVisible(false);
        ClearFields();
        btnSkip.setText("Přeskočit průvodce");
        //btnBack.setDisabled(false);
        btnFwd.setDisabled(false);
        btnSkip.setDisabled(false);
        btnVypN.setDisabled(true);
        txtRadGrupy.setDisabled(true);
        
        cboMITM.setSelected(false);
        ShowMITM(false);
        imgArrowBigLeft.setVisible(false);
        imgArrowBigRight.setVisible(false);
        labPrenos1.setVisible(false);
        labPrenos2.setVisible(false);
        
        return null;

    }

    public String btnVyh_action() {
        try
        {
        String odp = txtOdp1.getValue().toString();
        if (odp.equals("C")||odp.equals("c"))
        labO1.setText("OK");
        else
        labO1.setText("KO");

        odp = txtOdp2.getValue().toString();
        if (odp.equals("A")||odp.equals("a"))
        labO2.setText("OK");
        else
        labO2.setText("KO");

        odp = txtOdp3.getValue().toString();
        if (odp.equals("B")||odp.equals("b"))
        labO3.setText("OK");
        else
        labO3.setText("KO");

        odp = txtOdp4.getValue().toString();
        if (odp.equals("0")||odp.equals("12"))
        labO4.setText("OK");
        else
        labO4.setText("KO");

        odp = txtOdp5.getValue().toString();
        if (odp.equals("2"))
        labO5.setText("OK");
        else
        labO5.setText("KO");

        odp = txtOdp6.getValue().toString();
        if (odp.equals("1"))
        labO6.setText("OK");
        else
        labO6.setText("KO");
        }
        catch (Exception e)
        {
        JOptionPane.showMessageDialog(null, "Chybná vstupní data, DH.");
        }
        return null;
    }

    public String btnVysl_action() {
        txtOdp1.setValue("C");
        txtOdp2.setValue("A");
        txtOdp3.setValue("B");
        txtOdp4.setValue("0, 12");
        txtOdp5.setValue("2");
        txtOdp6.setValue("1");
        return null;
    }

    public String hyperlink1_action() {
        // TODO: Process the action. Return value is a navigation
        // case name where null will return to the same page.
        return null;
    }
}

