/* Created on 28. duben 2009, 10:50
 * @author  Dweep
 */
import java.awt.*;
import java.lang.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;


public class GUI extends javax.swing.JFrame {
public int lx1, ly1, lx2, ly2;      //promenne pro souradnice senzoru
public int start, cil;              //vychozi a cilovy senzor pro smerovani
public int vzdalenost, pocetSpoju;  //promenne pro spoje mezi senzory
public int  i=0, j=0;               //pomocne promenne
public boolean shoda = true, maluj = false, smeruj = false; //povoleni jednotlivych akci
public Platno MojePlatno = new Platno();    //platno na vykreslovani
public Legenda MojeLegenda = new Legenda(); //vykresleni legendy
public Senzor Senzory[] = new Senzor[40];   // nejdulezitejsi promenna - seznam vsech vygenerovanych senzoru s jejich vlasnostmi a parametry
public Spoj Spoje[], SpojeNew[] = new Spoj[200];    //druha nejdulezitejsi pomenna Spoje - seznam vsech realnych spojeni - tzn spoje mezi dostatecne blizkymi senzory
                                                    //SpojeNew - pomocna promenna - inicilaizace pro neznamy pocet spoju - dostatecne velky - empiricky overeno
public String[][] data1 = new String[Senzory.length/2][4], data2 = new String[20][4];   //vytvareci promenne pro tabulky
public String hlavicka1[] = {"ID","Energie","ID","Energie"}, hlavicka2[] = {"Vých.","Cílo.","Vzdá.","Spol."};  //hlavicky tabulek

public class Senzor{                //Nova trida pro jednotlive senzory
    Random rd=new Random();         //zahrnujici jejich vlastnosti a metody pro praci s nimi
    private int id, x, y;           //ID senzoru a jeho souradnice
    private int sousedu=0, vzdalenost = Integer.MAX_VALUE;  //pocet sousedu senzoru a jeho vzdalenost od vychoziho senzoru
    private int energie;                //zbyvajici energie senzoru
    private int prevDijkstra0 = Integer.MAX_VALUE, prevDijkstra2 = Integer.MAX_VALUE, prevDijkstra1 = Integer.MAX_VALUE, prevAstar = Integer.MAX_VALUE;
            //Predchozi senzor v ceste smerovani pro jednotlive metriky
    private boolean visited = false;        //urceni, zda byl senzor navstiven a tedy se jim uz nema zabyvat
    private double spolehlivost = Double.MAX_VALUE, ENSP = Double.MAX_VALUE;
        
    public void clear(){        //vycisteni dulezitych promennych provadene pred kazdym smerovanim
        visited = false;        
    }
    public void setID(int newValue){            //metody set* nastavuji nove hodnoty
        id = newValue;                          //ID senzoru
    }
    public int getID(){                         //metody get* ziskvaji nstavene hodnoty
        return id;
    }
    public void setX(int newValue){             //souradnice
        x = newValue;
    }
    public int getX(){        
        return x;
    }
    public void setY(int newValue){
        y = newValue;
    }
    public int getY(){
        return y;
    }
    public void setEN(int newValue){            //zbyvajici energie senzoru
        energie = newValue;
    }
    public int getEN(){        
        return energie;
    }
    public void setSOUSEDU(int newValue){       //pocet sousednich senzoru - se kterymi existuje spojeni
        sousedu = newValue;
    }
    public int getSOUSEDU(){        
        return sousedu;
    }
    public void setVzdalenost(int newValue){    //celkova metrika vzdalenosti od vychoziho senzoru
        vzdalenost = newValue;
    }
    public int getVzdalenost(){
        return vzdalenost;
    }
    public void setENSP(double newValue){       //celkova metrika spolehlivosti a energie od vychoziho senzoru
        ENSP = newValue;
    }
    public double getENSP(){        
        return ENSP;    
    }
    public void setETX(double newValue){        //celkova metrika spolehlivosti od vychoziho senzoru
        spolehlivost = newValue;
    }
    public double getETX(){        
        return spolehlivost;
    }
    public void setVIS(boolean newValue){       //priznak navstiveni senzoru a tedy jeho dasiho nezpracovani
        visited = newValue;
    }
    public boolean getVIS(){        
        return visited;
    }
    public void setPREV(int newValue1,int newValue2){   //predchozi senzor pro jednotlive metriky
        switch (newValue1){
            case 1: prevDijkstra0 = newValue2;
            break;
            case 2: prevDijkstra1 = newValue2;
            break;
            case 3: prevDijkstra2 = newValue2;
            break;
        }
    }
    public int getPREV(int newValue){
        switch (newValue){
            case 1: return prevDijkstra0;
            case 2: return prevDijkstra1;
            case 3: return prevDijkstra2;
            default: return 333;
        }
    }
}
public class Spoj{
    Random rd=new Random();
    private int idv, idc, vzdalenost;                           //definice spoje - vychozi a cilovy senzor a jejich vzdalenost
    private double spolehlivost = (rd.nextInt(33)+60)/100;
    
    public void setIDv(int newValue){                           //ID vychoziho senzoru
        idv = newValue;
    }
    public int getIDv(){        
        return idv;
    }
    public void setIDc(int newValue){                           //ID ciloveho senzoru
        idc = newValue;
    }
    public int getIDc(){        
        return idc;
    }
    public void setVZ(int newValue){                            //vzdalenost oznacenych senzoru
        vzdalenost = newValue;
    }
    public int getVZ(){        
        return vzdalenost;
    }
    public void setETX(double newValue){                        //spolehlivost spoje mezi oznacenymi senzory
        spolehlivost = newValue;
    }
    public double getETX(){        
        return spolehlivost;
    }
    
}

    public GUI() {
        initComponents();
        getRootPane().setDefaultButton(jButton2);        
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        jButton2 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jComboBox1 = new javax.swing.JComboBox();
        jComboBox2 = new javax.swing.JComboBox();
        jCheckBox1 = new javax.swing.JCheckBox();
        jCheckBox2 = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Směrování v WSN - Martin Dušek");
        setMinimumSize(new java.awt.Dimension(740, 700));
        setName("form2"); // NOI18N
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jButton1.setText("Generovat síť");
        jButton1.setFocusCycleRoot(true);
        jButton1.setFocusTraversalPolicyProvider(true);
        jButton1.setNextFocusableComponent(jComboBox1);
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        getContentPane().add(jButton1, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 600, 230, 60));
        getContentPane().add(jScrollPane3, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 10, 550, 550));
        getContentPane().add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 30, 150, 340));
        getContentPane().add(jScrollPane2, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 400, 150, 260));

        jButton2.setText("Směruj");
        jButton2.setEnabled(false);
        jButton2.setNextFocusableComponent(jButton1);
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        getContentPane().add(jButton2, new org.netbeans.lib.awtextra.AbsoluteConstraints(530, 600, 100, 60));

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel1.setText("Výchozí: ");
        getContentPane().add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(420, 600, 60, -1));

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("Cílový: ");
        getContentPane().add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(440, 630, 40, -1));
        getContentPane().add(jScrollPane4, new org.netbeans.lib.awtextra.AbsoluteConstraints(640, 600, 70, 60));

        jTextField1.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        jTextField1.setText("1");
        jTextField1.setEnabled(false);
        getContentPane().add(jTextField1, new org.netbeans.lib.awtextra.AbsoluteConstraints(570, 570, 30, -1));

        jTextField2.setText("1");
        jTextField2.setEnabled(false);
        getContentPane().add(jTextField2, new org.netbeans.lib.awtextra.AbsoluteConstraints(680, 570, 30, -1));

        jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel3.setText("Vliv energie: ");
        getContentPane().add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(600, 570, 80, 20));

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel4.setText("Vliv spolehlivosti: ");
        getContentPane().add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(470, 570, 100, 20));
        getContentPane().add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(300, 570, 210, 20));

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel7.setText("Seznam senzorů:");
        getContentPane().add(jLabel7, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, 150, -1));

        jLabel8.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel8.setText("Seznam spojení:");
        getContentPane().add(jLabel8, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 380, 150, -1));

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40" }));
        jComboBox1.setNextFocusableComponent(jComboBox2);
        getContentPane().add(jComboBox1, new org.netbeans.lib.awtextra.AbsoluteConstraints(480, 600, 40, 20));

        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40" }));
        jComboBox2.setSelectedIndex(39);
        jComboBox2.setSelectedItem(40);
        jComboBox2.setNextFocusableComponent(jButton2);
        getContentPane().add(jComboBox2, new org.netbeans.lib.awtextra.AbsoluteConstraints(480, 630, 40, -1));

        jCheckBox1.setFont(new java.awt.Font("Tahoma", 0, 9)); // NOI18N
        jCheckBox1.setText("Zobrazit dosah");
        jCheckBox1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox1StateChanged(evt);
            }
        });
        getContentPane().add(jCheckBox1, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 560, -1, -1));

        jCheckBox2.setFont(new java.awt.Font("Tahoma", 0, 9)); // NOI18N
        jCheckBox2.setSelected(true);
        jCheckBox2.setText("Zobrazit energie");
        jCheckBox2.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox2StateChanged(evt);
            }
        });
        getContentPane().add(jCheckBox2, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 580, -1, 20));

        pack();
    }// </editor-fold>//GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
    jLabel5.setText("");        //vycisteni napisu pro ohlseni nenalezeni cesty
    GenerovaniSite();
    NalezeniSpoju();
    tab1();         // vykresli setavene tabulky
    tab2();
    jButton2.setEnabled(true);      //aktivace prvku ktere jsou editovatelne az ve chvili, kdy je vygenerovana sit
    jComboBox1.setEnabled(true);    //aby se zabranilo praci se siti bez site
    jComboBox2.setEnabled(true);
    jTextField1.setEnabled(true);
    jTextField2.setEnabled(true);
}//GEN-LAST:event_jButton1ActionPerformed
private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
    
    tab1();                                     //uvodni vykresleni prazdnych tabulek
    tab2();
    MojePlatno.setBackground(Color.white);      //nastaveni bileho platna
    jScrollPane3.setViewportView(MojePlatno);   //prirazeni platna do objektu
    MojeLegenda.setBackground(Color.white);     //to same pro legendu
    jScrollPane4.setViewportView(MojeLegenda);
}//GEN-LAST:event_formWindowOpened
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
    jLabel5.setText("");                                        //vycisteni napisu o nenalezeni cesty pred novym smerovanim
    start = jComboBox1.getSelectedIndex()+1;                    //urceni ID vychoziho
    cil = jComboBox2.getSelectedIndex()+1;                      //a ciloveho senzoru
    for (int a=0;a<Senzory.length;a++) Senzory[a].clear();      //vycisteni navstivenosti senzoru po predchozim smerovani
    dijkstraVZ(start, cil);                                     //spusetni algoritmu pro metriku VZdalenosti
    for (int a=0;a<Senzory.length;a++) Senzory[a].clear();
    dijkstraSP(start, cil);                                     //spusetni algoritmu pro metriku SPolehlivosti cesty
    for (int a=0;a<Senzory.length;a++) Senzory[a].clear();
    dijkstraENSP(start, cil);                                   //spusetni algoritmu pro metriku ENergie a SPolehlivosti cesty
    smeruj = true;                                              //povoleni vykresleni nalezenych cest pro jednotlive metriky
    cesta(start,cil);                                           //vypis cest do konzole
    MojePlatno.repaint();                                       //prekresleni platna vcetne nalezenych cest
}//GEN-LAST:event_jButton2ActionPerformed
private void jCheckBox1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox1StateChanged
MojePlatno.repaint();
}//GEN-LAST:event_jCheckBox1StateChanged
private void jCheckBox2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox2StateChanged
MojePlatno.repaint();
}//GEN-LAST:event_jCheckBox2StateChanged
public void GenerovaniSite(){
    Random rd=new Random();     //spusteni nahodneho generatoru
    int xSouradnice, ySouradnice, blizko;
    for(int GENpomA=0;GENpomA<Senzory.length;GENpomA++){                //generovani souradnic 40 senzoru do pole
        do{
            Senzory[GENpomA] = new Senzor();                            //inicializace kazdeho prvku pole senzoru
            blizko = 0;                                                 //nastaveni podminky aby senzory nebyly moc blizko sebe        
            xSouradnice = rd.nextInt(jScrollPane3.getWidth()-60)+30;    //nahodna souradnice X
            ySouradnice = rd.nextInt(jScrollPane3.getHeight()-60)+30;   //nahodna souradnice Y
            if (GENpomA>0)                                              //kontorluj vzdalenosti az od 2. senzoru
            for (int GENpomB=0;GENpomB<GENpomA;GENpomB++){              //kontrola, jestli vzdalenost vygenerovanych souradnic
                if ((Math.abs(Senzory[GENpomB].getX()-xSouradnice) <50) &&      //a souradnic jiz zapsanych
                        (Math.abs(Senzory[GENpomB].getY()-ySouradnice) < 50)){  //v poli neni blizsi nez 50m
                  blizko++;                                                     // kazdy blizky senzor zvedne hodnotu
                }
            }                   //kontrola podminky jestli alespon jeden senzor je blizko
        } while (blizko>0);     //pokud ano vraci se zpet ke generovani,jinak cyklus konci
        Senzory[GENpomA].setID(GENpomA+1);          //a souradnice se zapisou vcetne indexu !!! od 1 !!!
        Senzory[GENpomA].setX(xSouradnice+5);       //souradnice jsou zapsany jako stred senzoru, ne odkud se kresli
        Senzory[GENpomA].setY(ySouradnice+5);  
        Senzory[GENpomA].setEN(rd.nextInt(39)+60);  //eneregie senzoru - nahodne generovana v rozmezi 60-99%
    }
    for (int GENpomB=0;GENpomB<=1;GENpomB++){       //tabulka ID a Energie
        for (int GENpomID=0;GENpomID<Senzory.length/2;GENpomID++){
            data1[GENpomID][0+GENpomB*2] = Integer.toString(Senzory[GENpomID+GENpomB*Senzory.length/2].getID());          //ID
            data1[GENpomID][1+GENpomB*2] = Integer.toString((Senzory[GENpomID+GENpomB*Senzory.length/2].getEN()));        //EN
        } 
    }
    maluj  = true;     //povoli metode paint vykreslit sestavene pole senozru
    smeruj = false;
    jScrollPane3.setViewportView(MojePlatno);       //prida vykreslene platno do komponenty
    MojePlatno.repaint();
}
public void NalezeniSpoju() {       //nalezeni vsech existujicich spoju v cele siti
                                    //spoj je definovan mezi dvema senzory, mezi kterymi je vzdalenost < 100
    Random rd=new Random();
    pocetSpoju = 0;                 //urcuje pocet spoju, zda je nutne testovat existujici opacny spoj
    for (int SPOJEpomX=0;SPOJEpomX<SpojeNew.length;SPOJEpomX++) SpojeNew[SPOJEpomX] = new Spoj();   //docasna promenna
    for (int SPOJEpomA=0;SPOJEpomA<Senzory.length;SPOJEpomA++){
        for (int SPOJEpomB=0;SPOJEpomB<Senzory.length;SPOJEpomB++){     //testovani kazdeho senzoru s kazdym
            if (SPOJEpomA!=SPOJEpomB){                                  //krome sebe sama
                vzdalenost = (int)Math.sqrt((Math.pow(Senzory[SPOJEpomB].getX()-Senzory[SPOJEpomA].getX(),2))+
                        (Math.pow(Senzory[SPOJEpomB].getY()-Senzory[SPOJEpomA].getY(),2)));
                if (vzdalenost <= 100){                                 //test vzdalenosti testovanych senzoru
                    shoda = true;                    
                    if (pocetSpoju != 0){                               //pokud je vice nez jeden spoj je nutno otestovat
                        for (int SPOJEpomC=0;SPOJEpomC<pocetSpoju;SPOJEpomC++){ //zda neexistuje spoj v seznamu opacnym smerem
                            if ((Senzory[SPOJEpomA].getID() - (SpojeNew[SPOJEpomC].getIDc()) == 0) && 
                                (Senzory[SPOJEpomB].getID() - (SpojeNew[SPOJEpomC].getIDv()) == 0)){
                                shoda = false;                                              //pokud existuje
                                SpojeNew[pocetSpoju].setETX(SpojeNew[SPOJEpomC].getETX());  //zkopiruje se spolehlivost
                            }
                        }
                    }
                    if (shoda){                                                             //pokud neexistuje
                        SpojeNew[pocetSpoju].setETX(((rd.nextInt(49)+Math.ceil(Senzory[SPOJEpomB].getEN()*0.5))/100.0));           //spolehlivost se vygeneruje nahodna    
                    }                                                                       //kazdy spoj tak dostane
                    SpojeNew[pocetSpoju].setIDv(Senzory[SPOJEpomA].getID());                //ID vychoziho senzoru
                    SpojeNew[pocetSpoju].setIDc(Senzory[SPOJEpomB].getID());                //ID ciloveho senzoru
                    SpojeNew[pocetSpoju].setVZ(vzdalenost);                                 //i jejich vzdalenost
                    Senzory[SPOJEpomA].setSOUSEDU(Senzory[SPOJEpomA].getSOUSEDU()+1);       //uvodnimu senzoru se zvysi pocet sousedu          
                    pocetSpoju +=1;                                                         //pocet spoju se zvysi
                }
            }
        }                                                                                   //pokud senzor nema zadne sousedy
        if (Senzory[SPOJEpomA].getSOUSEDU()==0) Senzory[SPOJEpomA].setVIS(true);            //je oznacen jako navstiveny a nebude zvazovan v algoritmech
    }  
    Spoje = new Spoj[pocetSpoju];       //seznam spoju je znovu dekarovan tentokrat uz se znamym poctem
    for (int SPOJEpomD=0;SPOJEpomD<=pocetSpoju-1;SPOJEpomD++){  //prepsani hodnot z docasne promenne do nove definovane
        Spoje[SPOJEpomD] = new Spoj();
        Spoje[SPOJEpomD].setIDv(SpojeNew[SPOJEpomD].getIDv()); 
        Spoje[SPOJEpomD].setIDc(SpojeNew[SPOJEpomD].getIDc());
        Spoje[SPOJEpomD].setVZ(SpojeNew[SPOJEpomD].getVZ());
        Spoje[SPOJEpomD].setETX(1/SpojeNew[SPOJEpomD].getETX());  
    }
    data2 = new String[pocetSpoju][4];  //stejne tak nove definovana tabulka spoju
    for (int SPOJEpomD=0;SPOJEpomD<=pocetSpoju-1;SPOJEpomD++){
            data2[SPOJEpomD][0]=Integer.toString(SpojeNew[SPOJEpomD].getIDv());                    
            data2[SPOJEpomD][1]=Integer.toString(SpojeNew[SPOJEpomD].getIDc());
            data2[SPOJEpomD][2]=Integer.toString(SpojeNew[SPOJEpomD].getVZ());
            data2[SPOJEpomD][3]=Double.toString(SpojeNew[SPOJEpomD].getETX());
        } 
}
//nasledujici 3 metody jsou zalozeny na Dijkstrovo algoritmu, jen s drobnymi modifikacemi pro pouziti prave rozdilne metriky
//uvedene v nazvu. Komentare jsou pouze prvni metody, u ostatnich jen konkretni modifikace
public void dijkstraVZ(int newValue1, int newValue2){
   //aktualni senzor je vzdy ten, jehoz okoli prozkoumavame
   Senzor aktualni = Senzory[newValue1-1];      //index a ID je rozdilne o 1
   aktualni.setVzdalenost(0);                   //vychozi senzor ma metriku nastavenou na 0
   int Vzdalenost;
   int volnych = 40;        //Dijkstru algoritmus prochazi CELOU sit - tedy na zacatku je pocet nenavstivenych senzoru 40
   while (volnych>0){
       for (int a=0;a<Spoje.length;a++){                                //prohledava se seznam spoju
           if (Spoje[a].getIDv()==aktualni.getID()){                    //nez narazi na aktualni senzor jako vychozi daneho spoje
               if (Senzory[Spoje[a].getIDc()-1].getVIS()) continue;     //pokud je navstiven preskoci se
               Senzor soused = Senzory[Spoje[a].getIDc()-1];            //jinak se pouzije pomocna promenna
               Vzdalenost = aktualni.getVzdalenost()+Spoje[a].getVZ();  //vypocita se vzdalenost aktualniho + vzdalenost do sousedniho senzoru
               if(soused.getVzdalenost()>Vzdalenost){                   //porovna se,pokud je vypoctena mensi nez nastvena daneho souseda
                   soused.setVzdalenost(Vzdalenost);                    //prepise se
                   soused.setPREV(1,aktualni.getID());                  //pro souseda se aktualni senzor nastavi jako predchozi uzel
               }
           }                                                            //takto se prozkoumaji vsechny sousedni senzory   
       }                                                                //a nasledne cela sit
       aktualni.setVIS(true);                                           //aktualni se oznaci jako navstiveny a jiz nebude bran v potaz
       aktualni.setVzdalenost(Integer.MAX_VALUE);                       //vycisti se vzdalenost aktualniho
       int volnych2 = volnych;                                          //pomocna promenna
       volnych = 0;                                                     //priprava klicove promenne
       for (int b=0;b<Senzory.length;b++){                              //a kontrola kolik senzoru je jiz navstivenych
           if (!Senzory[b].getVIS()){
               volnych++;
               if(Senzory[b].getVzdalenost()<aktualni.getVzdalenost())  //prvni nalezeny senzor s jiz pocitanou vzdalenosti
                   aktualni = Senzory[b];                               //je vzat jako aktualni
           }
       }
       if (volnych2 == volnych) break;      //pokud je cela sit prokontrolovana algoritmus skonci
   }   
   System.out.println("smerovani pro VZ dokonceno");
}
public void dijkstraSP(int newValue1, int newValue2){
   Senzor aktualni = Senzory[newValue1-1];
   aktualni.setETX(0);      //metrikou misto vzdalenosti je ETX
   double spolehlivost;     //desetinne cislo
   int volnych = 40;
   while (volnych>0){
       for (int a=0;a<Spoje.length;a++){
           if (Spoje[a].getIDv()==aktualni.getID()){
               if (Senzory[Spoje[a].getIDc()-1].getVIS()) continue;
               Senzor soused = Senzory[Spoje[a].getIDc()-1];
               spolehlivost = aktualni.getETX()+Spoje[a].getETX();      //vypocet spolehlivosti stejne jako u vzdalenosti
               if(soused.getETX()>spolehlivost){
                   soused.setETX(spolehlivost);                         //zapis
                   soused.setPREV(2,aktualni.getID());
               }
           }   
       }
       aktualni.setVIS(true);
       aktualni.setETX(Double.MAX_VALUE);
       int volnych2 = volnych;
       volnych = 0;
       for (int b=0;b<Senzory.length;b++){
           if (!Senzory[b].getVIS()){
               volnych++;
               if(Senzory[b].getETX()<aktualni.getETX())
                   aktualni = Senzory[b];
           }
       }
       if (volnych2 == volnych) break;
   }   
   System.out.println("smerovani pro SP dokonceno");
}
public void dijkstraENSP(int newValue1, int newValue2){
   Senzor aktualni = Senzory[newValue1-1];      //nova metrika je pro energii a spolehlivost
   aktualni.setENSP(100/aktualni.getEN());      //vychozi senzor ale spolehlivost zatim nema
   double EneSpo;                               //prevracena hodnota EN je pouzita kvuli neprime umere
   int volnych = 40;                            //energie a vhodnosti pouziti a 100 kvuli srovnani urovne 
   while (volnych>0){                           //se spolehlivosti, ktera je v rozmezi jednotek
       for (int a=0;a<Spoje.length;a++){
           if (Spoje[a].getIDv()==aktualni.getID()){                        
               if (Senzory[Spoje[a].getIDc()-1].getVIS()) continue;
               Senzor soused = new Senzor();
               /* V teto chvili jsem u ostatnich algoritmu mohl pracovat s pomocnou promennou jako se shodnymi adresami
                * na pametovy prostor jako je v seznamu senzoru, protoze jsem zaroven pracoval jak se sousedem
                * tak i se zaznamem v senzamu senzoru. Nyni ale potrebuji provadet v promenne soused zmeny hodnot
                * ktere se NESMI projevit v puvodnim seznamu Senzory. Abych s tomuto vyhnul, NESMIM pouzit prirazeni
                * ale jednotlive hodnoty musim ze Senozru vytahnout a zpetne je ulozti do promenne soused.
                */
               soused.setEN(Senzory[Spoje[a].getIDc()-1].getEN());      //ziskani pouze relevantnich vlastnosti
               soused.setENSP(Senzory[Spoje[a].getIDc()-1].getENSP());
               soused.setID(Senzory[Spoje[a].getIDc()-1].getID());
               soused.setPREV(3,Senzory[Spoje[a].getIDc()-1].getID());
               int pom = soused.getEN()/10;         //umela uprava hodnot energie, ktera dava zvlastni vahu 
               switch (pom){                        //urovne zbytkove energie,tzn. nabity senzor je MNOHEM VICE
                   case 8:                          //vhodnejsi ke smerovani nez senzor vybity
                       int pom2 = soused.getEN();
                       soused.setEN(pom2-10);       //senzory s urovni 80-89% se snizi o 10%
                       break;
                   case 7: 
                       pom2 = soused.getEN();
                       soused.setEN(pom2-20);       //senzory s urovni 70-79% se snizi o 20%
                       break;
                   case 6: 
                       pom2 = soused.getEN();
                       soused.setEN(pom2-40);       //senzory s urovni 60-69% se snizi o 40%
                       break;
                   default:                         //senzory s urovni 90-99% se ponechaji   
               }                                        //koeficienty pro urceni vlivu spolehlivosti a energie
               double vlivSP = Double.valueOf(jTextField1.getText());
               if (vlivSP>1){
                   jTextField1.setText("1");
                   vlivSP = 1.0;
               }
               double vlivEN = Double.valueOf(jTextField2.getText());
               if (vlivEN>1){
                   jTextField2.setText("1");
                   vlivEN = 1.0;
               }                    //metrika je pocitana pomoci koeficientu vlivu, ETX a upravene energie
               EneSpo = aktualni.getENSP()+(vlivSP*Spoje[a].getETX()+ vlivEN*(100/soused.getEN()));
               if(soused.getENSP()>EneSpo){     //zbytek je shodny s osatanimi metrikami
                   Senzory[Spoje[a].getIDc()-1].setENSP(EneSpo);
                   Senzory[Spoje[a].getIDc()-1].setPREV(3,aktualni.getID());
               }
           }   
       }
       aktualni.setVIS(true);
       aktualni.setENSP(Double.MAX_VALUE);
       int volnych2 = volnych;
       volnych = 0;
       for (int b=0;b<Senzory.length;b++){
           if (!Senzory[b].getVIS()){
               volnych++;
               if(Senzory[b].getENSP()<aktualni.getENSP())
                   aktualni = Senzory[b];
           }
       }
       if (volnych2 == volnych) break;
   }   
   System.out.println("smerovani pro ENSP dokonceno");
}
public void cesta(int newValue1,int newValue2){
    int akt = newValue2;
    if (Senzory[akt-1].getPREV(1)>40){      //testovani jestli byla nalzena cesta, tzn jestli cilovy senzor ma predchudce v ceste
            jLabel5.setText("Cesta nenalezena");
            return;
        }    
    System.out.print("VZ cesta: ");
    while (akt!=newValue1 && akt>0){        //vypis cesty do konzole
        System.out.print(akt + "<=");
        if (Senzory[akt-1].getPREV(1)>40){      //testovani jestli byla nalzena cesta, tzn jestli cilovy senzor ma predchudce v ceste
            jLabel5.setText("Cesta nenalezena");
            return;
        }
        akt = Senzory[akt-1].getPREV(1);
    }
    System.out.println(newValue1);
    akt = newValue2;
    if (Senzory[akt-1].getPREV(2)>40){
            jLabel5.setText("Cesta nenalezena");
            return;
        }
    System.out.print("SP cesta: ");
    while (akt!=newValue1 && akt>0){
        if (Senzory[akt-1].getPREV(1)>40){      //testovani jestli byla nalzena cesta, tzn jestli cilovy senzor ma predchudce v ceste
            jLabel5.setText("Cesta nenalezena");
            return;
        }
        System.out.print(akt + "<=");
        akt = Senzory[akt-1].getPREV(2);
    }
    System.out.println(newValue1);
    akt = newValue2;
    if (Senzory[akt-1].getPREV(3)>40){
            jLabel5.setText("Cesta nenalezena");
            return;
        }    
    System.out.print("ENSP cesta: ");
    while (akt!=newValue1 && akt>0){
        if (Senzory[akt-1].getPREV(1)>40){      //testovani jestli byla nalzena cesta, tzn jestli cilovy senzor ma predchudce v ceste
            jLabel5.setText("Cesta nenalezena");
            return;
        }
        System.out.print(akt + "<=");
        akt = Senzory[akt-1].getPREV(3);
    }
    System.out.println(newValue1);
}
public class Platno extends Canvas{   
        @Override
    public void paint(Graphics g) {      //vykresleni cele site vcetne vsech povolenych prvku
        if (maluj){                      //kontrola, jestli je sestavene pole senzoru a muze kreslit
            for (int MALUJpomA=0;MALUJpomA<Senzory.length;MALUJpomA++){     //pro kazdy prvek v poli senzoru:
                int x2 = Senzory[MALUJpomA].getX();     //ziskani souradnic
                int y2 = Senzory[MALUJpomA].getY();
                g.setColor(Color.BLACK);
                g.drawString(Integer.toString(Senzory[MALUJpomA].getID()), x2-10, y2-10);       //ID senzoru
                if (jCheckBox2.isSelected()){   
                    g.drawString("("+Integer.toString(Senzory[MALUJpomA].getEN())+")",              //Energie v zavorce
                            Senzory[MALUJpomA].getX(),Senzory[MALUJpomA].getY()+20);
                }
                if (jCheckBox1.isSelected()){        //vykresleni hranice dosahu senzoru pokud je to zadouci
                g.drawOval(x2-100, y2-100, 200, 200);
                }
                int H=0, G=255;    //sytost odstinu terciku
                //zde se rozhoduje barva teciku podle urovne zbyvajici energie senzoru
                if (Senzory[MALUJpomA].getEN()<70){    //bila pro nejnizsi enegie
                    g.setColor(Color.BLACK);     //vykresleni orkuzi spodniho terciku
                    g.drawOval(x2-7, y2-7, 13, 13);
                    g.setColor(Color.white);     //vykresleni spodniho terciku
                    g.drawOval(x2-6, y2-6, 11, 11);
                }
                else {if (Senzory[MALUJpomA].getEN()>=70 && Senzory[MALUJpomA].getEN()<80) H=200;   //svetle modra pro druhou nejnizsi uroven EN
                else if (Senzory[MALUJpomA].getEN()>=80 && Senzory[MALUJpomA].getEN()<90) H=0;    //stedne syta modra pro druhou nejvyssi uroven EN
                else  {H=0; G = 160;}      //syta modra pro nejvyssi uroven EN
                    g.setColor(Color.BLACK);     //vykresleni okruzi spodniho terciku
                    g.fillOval(x2-7, y2-7, 14, 14);
                g.setColor(new Color(H,H,G));     //vykresleni spodniho terciku
                g.fillOval(x2-6, y2-6, 12, 12);
                }
                g.setColor(Color.BLACK);    //vykresleni okruzi vrchniho terciku
                g.fillOval(x2-3, y2-3, 6, 6);
                g.setColor(Color.CYAN);     //vykresleni vrchniho terciku
                g.fillOval(x2-2, y2-2, 4, 4);
                }
            }
        if (smeruj){                        //pokud je povoleno smerovani - tzn probehly algoritmy pro urceni cest            
            int aktu = cil;                 //cesta se z povahy Dijkstrova algoritmu MUSI vykreslovat OD KONCE
            g.setColor(Color.CYAN);         //vykresleni nejkratsi cesty
            while (aktu!=start && aktu>0){  //kontola zda nejsme jiz u vychoziho bodu
                if (Senzory[aktu-1].getPREV(1)>40){ //kontrola zda existuje predchozi senzor, ze ktereho do aktualnho vede nejlepsi cesta
                    break;                          //pokud ne, vyreslovani se regulerne prerusi
                }
                lx1 = Senzory[aktu-1].getX()+3;     //vykresleni cary od posledniho
                ly1 = Senzory[aktu-1].getY()+3;     //+3 je proto, aby se jednotlive cary neprekryvaly         
                lx2 = Senzory[Senzory[aktu-1].getPREV(1)-1].getX()+3;   //k jeho predchudci
                ly2 = Senzory[Senzory[aktu-1].getPREV(1)-1].getY()+3;
                g.drawLine(lx1, ly1, lx2, ly2);
//                g.drawLine(lx1+1, ly1-1, lx2+1, ly2-1);         //zdvojeni cary pro lepsi viditelnost       
                aktu = Senzory[aktu-1].getPREV(1);
            }
            aktu = cil;                     //vykresleni nejelpsi cesty z pohledu spolehlivosti
            g.setColor(Color.RED);
            while (aktu!=start && aktu>0){
                if (Senzory[aktu-1].getPREV(2)>40){
                    break;
                }
                lx1 = Senzory[aktu-1].getX();       //cesta vede stredem senzoru
                ly1 = Senzory[aktu-1].getY();              
                lx2 = Senzory[Senzory[aktu-1].getPREV(2)-1].getX();
                ly2 = Senzory[Senzory[aktu-1].getPREV(2)-1].getY();
                String SP="12";
                for (int a=0;a<data2.length;a++){
                    if (Senzory[aktu-1].getID()==Integer.valueOf(data2[a][1]) && 
                            Senzory[Senzory[aktu-1].getPREV(2)-1].getID()==Integer.valueOf(data2[a][0])){
                        SP=data2[a][3];
                    }
                }
                g.drawString(SP, (int)lx2+((lx1-lx2)/2), (int)ly2+((ly1-ly2)/2));
                g.drawLine(lx1, ly1, lx2, ly2);
                g.drawLine(lx1+1, ly1-1, lx2+1, ly2-1); 
                aktu = Senzory[aktu-1].getPREV(2);
            }
            aktu = cil;                     //vykresleni nejelpsi cesty z pohledu spolehlivosti a energie
            g.setColor(Color.GREEN);
            while (aktu!=start && aktu>0){
                if (Senzory[aktu-1].getPREV(3)>40){
                    break;
                }
                lx1 = Senzory[aktu-1].getX()-3;     //cesta vede po opacnem kraji senzoru nez cesta nejkratsi vzdalenosti
                ly1 = Senzory[aktu-1].getY()-3;              
                lx2 = Senzory[Senzory[aktu-1].getPREV(3)-1].getX()-3;
                ly2 = Senzory[Senzory[aktu-1].getPREV(3)-1].getY()-3;                
                g.drawLine(lx1, ly1, lx2, ly2);
                g.drawLine(lx1+1, ly1-1, lx2+1, ly2-1); 
                aktu = Senzory[aktu-1].getPREV(3);
            }
        }
    }
}
public class Legenda extends Canvas{
        @Override
    public void paint(Graphics g){      //jednoduche vykresleni legendy
        g.setColor(Color.CYAN);         //jednotlive barevne cary
        g.drawLine(10, 8, 30, 8);
        g.setColor(Color.RED);
        g.drawLine(10, 28, 30, 28);
        g.setColor(Color.GREEN);
        g.drawLine(10, 48, 30, 48);
        g.setColor(Color.BLACK);
        g.drawString("VZ", 40, 13);     //prislusne popisky
        g.drawString("SP", 40, 33);
        g.drawString("EN", 40, 53);
    }
}   
public void tab1(){
    JTable tabulkaId = new JTable(data1, hlavicka1);    //sestavi a prepise tabulku novymi hodnotami
    TableColumn column = null;
    for (int x = 0; x < 4; x++) {
        column = tabulkaId.getColumnModel().getColumn(x);
        if (x%2 == 0) {
            column.setPreferredWidth(40);
        } else {
            column.setPreferredWidth(110);
        }
    }
//    tabulkaId.getCellEditor().addCellEditorListener(tabulkaId);
    
    
    tabulkaId.setFillsViewportHeight(false);            //vygenerovanymi novou siti
    tabulkaId.setAutoResizeMode(5);
    jScrollPane1.setViewportView(tabulkaId);            //a zobrazi ji
}
public void tab2(){        
    JTable tabulkaSpoj = new JTable(data2, hlavicka2);  //stejne jako tab1()
    TableColumn column = null;
    tabulkaSpoj.setFillsViewportHeight(false);
    jScrollPane2.setViewportView(tabulkaSpoj);
}  
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUI().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox2;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JComboBox jComboBox2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    // End of variables declaration//GEN-END:variables
}