package isorat;

import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.io.IOException;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.JTextPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import org.xml.sax.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import java.lang.Process;


/** Invokes an XML parser on an XML document and displays
 *  the document in a JTree. Both the parser and the
 *  document can be specified by the user. The parser
 *  is specified by invoking the program with
 *  java -Djavax.xml.parsers.DocumentBuilderFactory=xxx XMLFrame
 *  If no parser is specified, the Apache Xerces parser is used.
 *  The XML document can be supplied on the command
 *  line, but if it is not given, a JFileChooser is used
 *  to interactively select the file of interest.
 */

public class ISOFrame extends JFrame implements TreeSelectionListener, ActionListener{
    
    private String filename;
    private JTree tree;
    private JPanel configuration_rightpanel;
    private JTextField campo_de_texto;
    
    
    private JCheckBox checkbox;
    private JComboBox combo;
    private JButton savebutton,generatebutton,viewbutton;
    private JTextArea textarea;
    
    
    private JTextPane configuration_rightpanel_text;
    private Document document;
    private Node nds;
    private Element nd;
    
    private JMenuBar menubar;
    private String pdfname;

    
    

public JMenuBar createMenuBar()
        {
       
        JMenuItem menuItem;
        JRadioButtonMenuItem rbMenuItem;
        JCheckBoxMenuItem cbMenuItem;
        JMenuBar menubar=new JMenuBar();  
        JMenu menu = new JMenu("Archivo");
        menu.setMnemonic(KeyEvent.VK_A);
        menu.getAccessibleContext().setAccessibleDescription(
                "Menu para el manejo de los archivos");
        menubar.add(menu);
        //a group of JMenuItems
        menuItem = new JMenuItem("Abrir",KeyEvent.VK_A);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.ALT_MASK));
        menuItem.addActionListener(this);
        menuItem.getAccessibleContext().setAccessibleDescription("Menu Item");
        menu.add(menuItem);

        menuItem = new JMenuItem("Guardar",KeyEvent.VK_S);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.ALT_MASK));
        menuItem.addActionListener(this);
        menuItem.getAccessibleContext().setAccessibleDescription("Menu Item");
        menu.add(menuItem);
        
        menuItem = new JMenuItem("Guardar como ...",KeyEvent.VK_G);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.ALT_MASK));
        menuItem.addActionListener(this);
        menuItem.getAccessibleContext().setAccessibleDescription("Menu Item");
        menu.add(menuItem);
        menuItem = new JMenuItem("Salir",KeyEvent.VK_E);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.ALT_MASK));
        menuItem.addActionListener(this);
        menuItem.getAccessibleContext().setAccessibleDescription("Menu Item");
        menu.add(menuItem);
        
        //a group of radio button menu items

        //a submenu
           menubar.add(menu);
        //FIN MENU       
        return menubar;
        
        };

    public ISOFrame(String filename) {
    
        //WindowUtilities.setNativeLookAndFeel();
        
        this.filename=filename;
        this.pdfname="";
     
        document=parseXmlFile(filename,false);
        if(this.filename.equalsIgnoreCase("template/iso_rat.xml"))
        {
        this.filename="./iso_rat_output.xml";
        }
        tree = new XMLTree(document);
        tree.addTreeSelectionListener(this);
        JTabbedPane tabbedPane = new JTabbedPane();
        
        //MENU        
         menubar=createMenuBar();
        JFrame frame = new JFrame("ISO 17799 Risk Analisys Tool");
        frame.setIconImage(new ImageIcon("images/isorat.jpg").getImage()); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setJMenuBar(menubar);
        JPanel configuration_mainpanel= new JPanel();
        configuration_rightpanel= new JPanel();
        JPanel reportpanel= new JPanel();
        
        
        //elementos de entrada de la respuesta de los usuarios
        checkbox=new JCheckBox();
        checkbox.setVisible(false);
        combo=new JComboBox();
        combo.setVisible(false);
        
        savebutton=new JButton("Guardar");
        savebutton.setMaximumSize(new Dimension(30,30));
        savebutton.setVisible(false);
        savebutton.addActionListener(this);
        
        
        //añadimos donde iran las preguntas
        //configuration_rightpanel_text=new JTextPane();
        
//        configuration_rightpanel.add( configuration_rightpanel_text);
//añadimos los elementos de entrada a la derecha del panel
        
        configuration_rightpanel.setLayout(new BorderLayout());
        configuration_rightpanel.add(checkbox,BorderLayout.NORTH);
        configuration_rightpanel.add(combo,BorderLayout.NORTH);
        configuration_rightpanel.add(savebutton,BorderLayout.SOUTH);
    
        //el gestor de eventos del raton sera esta clase
            generatebutton=new JButton("Generar Informe");
            generatebutton.addActionListener(this);
        
        reportpanel.add(generatebutton);
        
        viewbutton=new JButton("Visualizar Informe");
        viewbutton.addActionListener(this);
        reportpanel.add(viewbutton);
        
        
        Container content = frame.getContentPane();
        
        //creamos la ventana de navegacion por el arbol
        configuration_mainpanel.add(new JScrollPane(tree));
        configuration_mainpanel.add(configuration_rightpanel);
        
        //creamos un panel dividdo con tabs
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(configuration_mainpanel);
        splitPane.setRightComponent(configuration_rightpanel);
        
        tabbedPane.addTab("Configuración", null,splitPane); //tooltip text
        tabbedPane.addTab("Informe", null,reportpanel); //tooltip text
        content.add(tabbedPane);
        frame.pack();
        frame.setVisible(true);
        
    }
    
    
    public static Document parseXmlFile(String filename, boolean validating) {
        try {
            // Create a builder factory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(validating);
            
            // Create the builder and parse the file
            Document doc = factory.newDocumentBuilder().parse(new File(filename));
            return doc;
        } catch (SAXException e) {
            // A parsing error occurred; the xml input is not valid
        } catch (ParserConfigurationException e) {
        } catch (IOException e) {
        }
        return null;
    }
    
    
// This method writes a DOM document to a file
    private void writeXmlFile(Document doc, String filename) {
        try {
            // Prepare the DOM document for writing
            Source source = new DOMSource(doc);
            
            // Prepare the output file
            File file = new File(filename);
            Result result = new StreamResult(file);
            
            // Write the DOM docuent to the file
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
        } catch (TransformerException e) {
        }
    }
    
    
    
    
    
    private Document createDocument(InputStream in) {
        try {
            DocumentBuilderFactory builderFactory =  DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            // Standard DOM code from hereon. The "parse"
            // method invokes the parser and returns a fully parsed
            // Document object. We'll then recursively descend the
            // tree and copy non-text nodes into JTree nodes.
            Document document = builder.parse(in);
            //document.getDocumentElement().normalize();
            
            return document;
        } catch(Exception e) {
            String errorMessage =
                    "Error loading the xml: " + e;
            System.err.println(errorMessage);
            e.printStackTrace();
            return null;
            
        }
    }


    
    public void actionPerformed(ActionEvent e) {
        
        //si pulsamos el boton de guardar
        if((e.getSource()==savebutton)||(e.getSource()==viewbutton)||(e.getSource()==generatebutton)){
           
            
       if(e.getSource()==savebutton){
            if(this.checkbox.isVisible()) {
                if(this.checkbox.isSelected()){
                    
                    this.nd.setAttribute("answer","1");
                }else{
                    this.nd.setAttribute("answer","0");
                }
                writeXmlFile(this.document,this.filename);
             
            };
       }
         if(e.getSource()==viewbutton){
           if(!(this.pdfname.isEmpty())){ 
              if (System.getProperty("os.name").equals("Linux")) {
               
               Process theProcess;
                    try {

                        theProcess=Runtime.getRuntime().exec("evince "+this.pdfname);
                    
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
              };
           };
         }
        if(e.getSource()==generatebutton){
           
            writeXmlFile(this.document,this.filename); 
          String[] extensions = { "pdf"};
         this.pdfname = ExtensionFileFilter.getFileName(".","pdf Files",extensions,1);  
         XML2PDF xml2pdf=new XML2PDF(this.filename,"template/transform.xslt",pdfname);
         xml2pdf.generatePDF();
         
         }
       
       
        }else{
            JMenuItem source = (JMenuItem)(e.getSource());
            if (source.getText().equalsIgnoreCase("Abrir")) 
            {
                String[] extensions = { "xml", "tld" };
            // WindowUtilities.setNativeLookAndFeel();
       
                this.filename = ExtensionFileFilter.getFileName(".","XML Files",extensions,0);
                
            
            }
            if (source.getText().equalsIgnoreCase("Guardar")) 
            {
                  writeXmlFile(this.document,this.filename);
            }
            
            
            if (source.getText().equalsIgnoreCase("Guardar como ...")) 
            {
                  String[] extensions = { "xml", "tld" };
            // WindowUtilities.setNativeLookAndFeel();
       
                this.filename = ExtensionFileFilter.getFileName(".","XML Files",extensions,1);
                 writeXmlFile(this.document,this.filename);
            }
            if (source.getText().equalsIgnoreCase("Salir")) 
            {
            System.exit(0);
            }
            
            
            };
        
        };
 

   
    public void valueChanged(TreeSelectionEvent e) {
        
        
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
        
        if (node == null) return;
        
        Object nodeInfo = node.getUserObject();
        
        if (node.isLeaf()) {
            
            String text = (String)nodeInfo;
            String id=text.substring(0,5);
            //obtenemos en nodo de nuestro docmento xml
            
            Element nd=this.document.getElementById(id);
             String text2=nd.getAttribute("question");
            this.checkbox.setText(text2);
      
            
            switch(Integer.parseInt(nd.getAttribute("question_type"))) {
                case 0:
                    
                    this.checkbox.setVisible(true);
                    this.combo.setVisible(false);
                    this.savebutton.setVisible(true);
                
                    
                    if(nd.getAttribute("answer").equalsIgnoreCase("1")) {
                        
                        configuration_rightpanel.add(checkbox);
                        checkbox.setSelected(true);
                        
                    } else {
                        configuration_rightpanel.add(checkbox);
                        checkbox.setSelected(false);
                        
                    }
                    break;
                case 1:
                    this.checkbox.setVisible(false);
                    this.combo.setVisible(true);
                    this.savebutton.setVisible(true);
                    break;
            }
        }
        
    }
    
    public static void main(String[] args) {
   
        String filename;
        if (args.length > 0) {
            filename = args[0];
        } else {
            String[] extensions = { "xml", "tld" };
           
            filename = "template/iso_rat.xml";
            if (filename == null) {
               
               filename = ExtensionFileFilter.getFileName(".","XML Files",extensions,1);
            }
            else
            {
            
            
            }
        }
        new ISOFrame(filename);
    }
    
    
}