/*
 * Windows.java
 */

package dblpconverter;

/**
 *
 * @author Gersk
 *
 * Windows class is the GUI of the application
 */

import javax.swing.*;          
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class Window extends JFrame implements ActionListener, MouseListener
{
    private int returnVal;
    private static final String newline = "\n";
    
    private XMLManager xmlManager;
    private DatabaseManager dbManager;
    private QueryBuilder qBuilder;
    private StatusBar statusBar;
    private Temporized temporized;
    private SaxThread saxThread;
    
    private File xmlFile;
    
    private ButtonGroup radioGroup;
    
    private JButton xmlButton;
    private JButton connectButton;
    private JButton createButton;
    private JButton eraseButton;
    private JButton dropButton;
    private JButton addButton;
    
    public JRadioButton rbutton1;
    public JRadioButton rbutton2;
    private JTextArea log;
    
    private JLabel outFileJL;
    private JLabel odbcName;
    private JLabel db;
    private JLabel userId;
    private JLabel password;
    private JLabel time;
    private JLabel elements;
    private JLabel attributes;
    private JLabel characters;
    private JLabel proceedings;
    private JLabel inproceedings;
    private JLabel books;
    private JLabel incollections;
    private JLabel articles;
    private JLabel phd_thesis;
    private JLabel master_thesis;
    private JLabel www;
            
    private JTextField outFileTf;
    private JTextField odbcTf;
    private JTextField dbTf;
    private JTextField userTf;
    private JTextField passwordTf;
    private JTextField elementsTf;
    private JTextField attributesTf;
    private JTextField charactersTf;
    
    public JCheckBox proceedingsCb;
    public JCheckBox inproceedingsCb;
    public JCheckBox booksCb;
    public JCheckBox incollectionsCb;
    public JCheckBox articlesCb;
    public JCheckBox wwwCb;
    public JCheckBox phd_thesisCb;
    public JCheckBox master_thesisCb;
    
    private JFileChooser fc;
    
    private JScrollPane logScrollPane;
    private JPanel mainPanel;
    private JPanel westPanel;
    private JPanel eastPanel;
    private JPanel topPanel;
    private JPanel xmlPanel;
    private JPanel centerPanel;
    private JPanel southPanel;
    private JPanel addPanel;    
    private JPanel panel1;                
    private JPanel panel2;                 
    private JPanel panel3;                  
    private JPanel panel4;    
    private JPanel panel5;
    private JPanel filePanel;
    private JPanel manPanel;                
    private JPanel modePanel;
    private JPanel connectPanel;            
    private JPanel checkPanel;
    private JPanel statPanel;
    private JPanel statPanel1;

    private JMenuBar mnuBar;                                 
    private JMenu mnuMain;                              
    private JMenuItem mnuExit;       
    private int queryNumber = 0, elems = 0, attrs = 0, chars = 0;
    private boolean connected = false, state = true, processing = false, state1 = true;
    
    public Window() 
    {
        super("DBLP Converter");

        statusBar = new StatusBar();
        temporized = new Temporized(this);
        
        mnuBar = new JMenuBar();
        mnuMain = new JMenu("File");
        mnuExit = new JMenuItem("Exit");
        
        mnuMain.add(mnuExit);
        mnuBar.add(mnuMain);
        
        mainPanel = new JPanel(new BorderLayout()); 
        westPanel = new JPanel(new BorderLayout());
        eastPanel = new JPanel(new BorderLayout());
        topPanel = new JPanel(new GridLayout(2,1));
        centerPanel = new JPanel(new GridLayout(2,1));
        xmlPanel = new JPanel(new FlowLayout());
        centerPanel = new JPanel(new BorderLayout());
        southPanel = new JPanel(new BorderLayout());
        panel1 = new JPanel();
        panel2 = new JPanel();
        panel3 = new JPanel();
        panel4 = new JPanel();
        panel5 = new JPanel();
        modePanel = new JPanel(new FlowLayout());
        filePanel = new JPanel();
        manPanel = new JPanel(new FlowLayout());
        connectPanel = new JPanel(new GridLayout(4,3));
        addPanel = new JPanel(new FlowLayout());
        checkPanel = new JPanel(new GridLayout(4,3));
        statPanel = new JPanel(new BorderLayout());
        statPanel1 = new JPanel(new GridLayout(5,2));
        
        xmlButton = new JButton("Open XML file");
        connectButton = new JButton("Connect");
        createButton = new JButton("Create table");
        eraseButton = new JButton("Erase table");
        dropButton = new JButton("Drop table");
        addButton = new JButton("Start processing");
        
        outFileJL = new JLabel(" Output File: ");
        odbcName = new JLabel(" Link : ");
        db = new JLabel(" Database: ");
        userId = new JLabel(" User ID: ");
        password = new JLabel(" Password: ");
        time = new JLabel(" Time elapsed: ");
        elements = new JLabel(" Elements: ");
        attributes = new JLabel(" Attributes: ");
        characters = new JLabel(" Characters: ");
        proceedings = new JLabel(" Proceedings ");
        inproceedings = new JLabel(" Inproceedings ");
        books = new JLabel(" Books ");
        incollections = new JLabel(" Incollections ");
        articles = new JLabel(" Articles ");
        phd_thesis = new JLabel(" Phd thesis ");
        master_thesis = new JLabel(" Master thesis ");
        www = new JLabel(" Web address ");
        
        
        outFileTf = new JTextField();
        outFileTf.setText("C:\\database");
        outFileTf.setColumns(13);
        odbcTf = new JTextField();
        odbcTf.setText("localhost:3306");
        dbTf = new JTextField();
        dbTf.setText("dblp");
        dbTf.setEditable(false);
        userTf = new JTextField();
        userTf.setText("root");
        passwordTf = new JPasswordField();
        elementsTf = new JTextField();
        elementsTf.setText("0     ");
        elementsTf.setEditable(false);
        attributesTf = new JTextField();
        attributesTf.setText("0     ");
        attributesTf.setEditable(false);
        charactersTf = new JTextField();
        charactersTf.setText("0     ");
        charactersTf.setEditable(false);
        
        proceedingsCb = new JCheckBox();
        proceedingsCb.setSelected(true);
        inproceedingsCb = new JCheckBox();
        inproceedingsCb.setSelected(true);
        booksCb = new JCheckBox();
        booksCb.setSelected(true);
        incollectionsCb = new JCheckBox();
        incollectionsCb.setSelected(true);
        articlesCb = new JCheckBox();
        articlesCb.setSelected(true);
        wwwCb = new JCheckBox();
        wwwCb.setSelected(true);
        phd_thesisCb = new JCheckBox();
        phd_thesisCb.setSelected(true);
        master_thesisCb = new JCheckBox();
        master_thesisCb.setSelected(true); 
        fc = new JFileChooser();
        
        log = new JTextArea(20,40);
        log.setBackground(Color.BLACK);
        log.setForeground(Color.WHITE);
        logScrollPane = new JScrollPane(log);
        logScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Log"));
        
        log.setMargin(new Insets(5,5,5,5));
        log.setEditable(false);
        
        rbutton1 = new JRadioButton("Database");
        rbutton2 = new JRadioButton("File");
        rbutton2.setSelected(true);
        radioGroup = new ButtonGroup();
        radioGroup.add(rbutton1);
        radioGroup.add(rbutton2);
        
        xmlButton.addActionListener(this);
        connectButton.addActionListener(this);
        createButton.addActionListener(this);
        eraseButton.addActionListener(this);
        dropButton.addActionListener(this);
        addButton.addActionListener(this);
        mnuExit.addActionListener(this);
        rbutton1.addActionListener(this);
        rbutton2.addActionListener(this);
        
        odbcTf.setEditable(false);
        userTf.setEditable(false);
        passwordTf.setEditable(false);
        rbutton1.setSelected(false);
            
        connectButton.setEnabled(false);
        createButton.setEnabled(false);
        eraseButton.setEnabled(false);
        dropButton.setEnabled(false);
        
        xmlPanel.add(xmlButton);
        xmlPanel.add(modePanel);
        xmlPanel.add(panel2);
        xmlPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "XML data"));   
        
        topPanel.add(xmlPanel);
        topPanel.add(modePanel);
        
        manPanel.add(createButton);
        manPanel.add(eraseButton);
        manPanel.add(dropButton);
        
        connectPanel.add(odbcName);
        connectPanel.add(odbcTf);
        connectPanel.add(panel1);
        connectPanel.add(db);
        connectPanel.add(dbTf);
        connectPanel.add(connectButton);
        connectPanel.add(userId);
        connectPanel.add(userTf);
        connectPanel.add(panel2);
        connectPanel.add(password);
        connectPanel.add(passwordTf);
        connectPanel.add(panel5);
        
        filePanel.add(outFileJL);
        filePanel.add(outFileTf);
        
        centerPanel.add(connectPanel, BorderLayout.NORTH);
        centerPanel.add(manPanel, BorderLayout.CENTER);
        centerPanel.add(filePanel, BorderLayout.SOUTH);
        centerPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Database"));
        
        checkPanel.add(proceedings);
        checkPanel.add(proceedingsCb);
        checkPanel.add(inproceedings);
        checkPanel.add(inproceedingsCb);
        checkPanel.add(books);
        checkPanel.add(booksCb);
        checkPanel.add(incollections);
        checkPanel.add(incollectionsCb);
        checkPanel.add(articles);
        checkPanel.add(articlesCb);
        checkPanel.add(www);
        checkPanel.add(wwwCb);
        checkPanel.add(phd_thesis);
        checkPanel.add(phd_thesisCb);
        checkPanel.add(master_thesis);
        checkPanel.add(master_thesisCb);
        checkPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Element type"));
        
        addPanel.add(panel3);
        addPanel.add(addButton);
        addPanel.add(panel4);
        addPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Action"));
        
        modePanel.add(rbutton2);
        modePanel.add(rbutton1);
        modePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Mode"));
        
        statPanel1.add(time);
        statPanel1.add(temporized);

        statPanel1.add(elements);
        statPanel1.add(elementsTf);
        statPanel1.add(attributes);
        statPanel1.add(attributesTf);
        statPanel1.add(characters);
        statPanel1.add(charactersTf);
        statPanel.add(statPanel1, BorderLayout.WEST);
        statPanel.add(statusBar, BorderLayout.EAST);
        statPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "Statistics"));
        
        southPanel.add(checkPanel, BorderLayout.NORTH);
        southPanel.add(addPanel, BorderLayout.CENTER);
        
        westPanel.add(topPanel, BorderLayout.NORTH);
        westPanel.add(centerPanel, BorderLayout.CENTER);
        westPanel.add(southPanel, BorderLayout.SOUTH);
        
        eastPanel.add(statPanel, BorderLayout.NORTH);
        eastPanel.add(logScrollPane, BorderLayout.CENTER);
       
        mainPanel.add(westPanel, BorderLayout.WEST);
        mainPanel.add(eastPanel, BorderLayout.EAST);
        
        this.add(mainPanel);
        this.setJMenuBar(mnuBar);
        this.setBounds(260,100, 850, 560);
        this.setResizable(false);
        this.validate();
        this.setVisible(true);
    }
    
    public void setXMLManager(XMLManager xmlManager) 
    {
        this.xmlManager = xmlManager;
    }
    
    public void setDbManager(DatabaseManager dbManager) 
    {
        this.dbManager = dbManager;
    }
    
    public void setQBuilder(QueryBuilder qBuilder)
    {
        this.qBuilder = qBuilder;
    }
    
    public void setSaxThread(SaxThread saxThread)
    {
        this.saxThread = saxThread;
    }
    
    public void append(String string)
    {
        log.append(string + newline);
    }
    
    public void setValue(int elems, int attrs, int chars)
    {
        append("Done.");
        this.elems = elems;
        this.attrs = attrs;
        this.chars = chars;
        
        elementsTf.setText(Integer.toString(elems));
        attributesTf.setText(Integer.toString(attrs));
        charactersTf.setText(Integer.toString(chars));
        statusBar.setMaxBound(elems);
    }
    
    public void stopCounter()
    {
        temporized.stop();
    }
    
    public void finish()
    {
        stopCounter();

        if(rbutton1.isSelected())
        {
            connectButton.setEnabled(true);
            createButton.setEnabled(true);
            eraseButton.setEnabled(true);
            dropButton.setEnabled(true);
            addButton.setText("Start processing");
        }
        
        if(rbutton2.isSelected())
        {
            outFileTf.setEditable(false);
            releaseFile();
        }
        proceedingsCb.setEnabled(true);
        inproceedingsCb.setEnabled(true);
        booksCb.setEnabled(true);
        incollectionsCb.setEnabled(true);
        articlesCb.setEnabled(true);
        wwwCb.setEnabled(true);
        phd_thesisCb.setEnabled(true);
        master_thesisCb.setEnabled(true);
        rbutton1.setEnabled(true);
        rbutton2.setEnabled(true);
        xmlButton.setEnabled(true);
        addButton.setText("Start processing");
        append("Work complete in " + temporized.getHours() + " hours, " + temporized.getMinutes() + " minutes and " + temporized.getSeconds() + " seconds.");
    }
    
    public int getQueryNumber()
    {
        return queryNumber;
    }
    
    public void setFile()
    {
        dbManager.setTableFile(outFileTf.getText() + "_Table.sql");
        dbManager.setQueryFile(outFileTf.getText() + ".sql");
        outFileTf.setEditable(false);
        append("Files created");
    }
    
    public void releaseFile()
    {
        if(rbutton2.isSelected())
        {
            outFileTf.setEditable(true);
            dbManager.closeFile();
            dbManager.closeTableFile();
            append("Output file released");
        }
    }
    
    public void reset()
    {
        statusBar.reset();
        elementsTf.setText("0     ");
        attributesTf.setText("0     ");
        charactersTf.setText("0     ");
    }
    
    
    public void actionPerformed(ActionEvent evt)                              
    {        
        if(evt.getSource() == rbutton1)
        {
            odbcTf.setEditable(true);
            dbTf.setEditable(true);
            userTf.setEditable(true);
            passwordTf.setEditable(true);            
            connectButton.setEnabled(true);
            createButton.setEnabled(true);
            eraseButton.setEnabled(true);
            dropButton.setEnabled(true);
            outFileTf.setEditable(false);
        }
        
        if(evt.getSource() == rbutton2)
        {
            odbcTf.setEditable(false);
            dbTf.setEditable(false);
            userTf.setEditable(false);
            passwordTf.setEditable(false);
            connectButton.setEnabled(false);
            createButton.setEnabled(false);
            eraseButton.setEnabled(false);
            dropButton.setEnabled(false);
            outFileTf.setEditable(true);
        }
        if (evt.getSource() == xmlButton) 
        {
            returnVal = fc.showOpenDialog(this);
            if (returnVal == JFileChooser.APPROVE_OPTION) 
            {
                if(fc.getSelectedFile() != null)
                {    
                    xmlFile = fc.getSelectedFile();
                    saxThread.setFile(xmlFile);
                    append("Opening XML file: " + xmlFile.getName());
                }
            }
            else 
            {
                append("Open command cancelled by user");
            }

        } 
        
        if (evt.getSource() == connectButton) 
        {
            if(!connected & state)
            {    
                append("Connecting to db...");
                try {         
                    dbManager.connect(odbcTf.getText(), dbTf.getText(), userTf.getText(), passwordTf.getText());
                    connectButton.setText("Disconnect");
                    connected = true;
                    state = false;
                    odbcTf.setEditable(false);
                    dbTf.setEditable(false);
                    userTf.setEditable(false);
                    passwordTf.setEditable(false);
                    
                } catch (Exception e) {
                    append(e.getMessage());
                }
            }
            
            if(connected & state)
            {
                append("Disconnected from db...");
                dbManager.disconnect();
                connectButton.setText("Connect");
                connected = false;
                odbcTf.setEditable(true);
                dbTf.setEditable(true);
                userTf.setEditable(true);
                passwordTf.setEditable(true);
                createButton.setEnabled(true);
                eraseButton.setEnabled(true);
                dropButton.setEnabled(true);
            }
            
            state = true;
        }
        
        if (evt.getSource() == createButton) 
        {
            append("Creating table..");
            try {         
                qBuilder.createTables();
            } catch (Exception e) {
                append(e.getMessage());
            }
        }
        
        if (evt.getSource() == eraseButton) 
        {
            append("Erasing data..");
            try {         
                qBuilder.eraseData();
            } catch (Exception e) {
                append(e.getMessage());
            }
        }
        
        if (evt.getSource() == dropButton) 
        {
            append("Dropping table..");
            try {         
                qBuilder.dropTables();
            } catch (Exception e) {
                append(e.getMessage());
            }
        }
        
        if (evt.getSource() == addButton) 
        {   
            if(!processing & state1)
            {
                if(rbutton1.isSelected())
                {
                    connectButton.setEnabled(false);
                    createButton.setEnabled(false);
                    eraseButton.setEnabled(false);
                    dropButton.setEnabled(false);
                }
                if(rbutton2.isSelected())
                {
                    setFile();
                    outFileTf.setEditable(false);
                }
                xmlManager.setStatusBar(statusBar);
                statusBar.reset();
                addButton.setText("Stop processing");
                processing = true;
                state1 = false;
                proceedingsCb.setEnabled(false);
                inproceedingsCb.setEnabled(false);
                booksCb.setEnabled(false);
                incollectionsCb.setEnabled(false);
                articlesCb.setEnabled(false);
                wwwCb.setEnabled(false);
                phd_thesisCb.setEnabled(false);
                master_thesisCb.setEnabled(false);
                rbutton1.setEnabled(false);
                rbutton2.setEnabled(false);
                xmlButton.setEnabled(false);
                new Thread(saxThread).start();
                new Thread(temporized).start();
            }
            if(processing & state1)
            {
                saxThread.stop();
                xmlManager.reset();
                stopCounter();
                releaseFile();
                append("Process stop by user");
                processing = false;
                addButton.setText("Start processing");
                proceedingsCb.setEnabled(true);
                inproceedingsCb.setEnabled(true);
                booksCb.setEnabled(true);
                incollectionsCb.setEnabled(true);
                articlesCb.setEnabled(true);
                wwwCb.setEnabled(true);
                phd_thesisCb.setEnabled(true);
                master_thesisCb.setEnabled(true);
                rbutton1.setEnabled(true);
                rbutton2.setEnabled(true);
                xmlButton.setEnabled(true);
                if(rbutton1.isSelected())
                {
                    connectButton.setEnabled(true);
                    createButton.setEnabled(true);
                    eraseButton.setEnabled(true);
                    dropButton.setEnabled(true);
                }
                if(rbutton2.isSelected())
                {
                   outFileTf.setEditable(true);
                }      
            }
            state1 = true;
        }
        
        if (evt.getSource() == mnuExit) 
        {
            int exit = JOptionPane.showConfirmDialog(this, "Are you sure to quit?", "Exit?", JOptionPane.YES_NO_OPTION);
            if (exit == JOptionPane.YES_OPTION) 
            {
                dbManager.close();
                System.exit(0);    
            }
        }
    }
       
    public void mouseClicked(MouseEvent evt) {}
    public void mousePressed (MouseEvent evt) {}
    public void mouseReleased (MouseEvent evt) {} 
    public void mouseEntered (MouseEvent evt) {}
    public void mouseExited (MouseEvent evt) {} 
    
    protected void processWindowEvent(WindowEvent e)                           
    {
        if (e.getID() == WindowEvent.WINDOW_CLOSING) 
         {
             int exit = JOptionPane.showConfirmDialog(this, "Are you sure to quit?", "Exit?", JOptionPane.YES_NO_OPTION);
             if (exit == JOptionPane.YES_OPTION) 
             {
                dbManager.close();
                System.exit(0);
             }
         } 
         else 
         { 
            super.processWindowEvent(e);
         }
    }
}
