package diploma;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.sql.*; 
import java.util.*;
import java.io.*;
import java.text.*;


public class TabelOperatii extends JFrame implements ActionListener,
	ListSelectionListener, TableModelListener{
		StringBuffer comandaString = new StringBuffer("SELECT * FROM "), 
			comandaHtmlString = new StringBuffer("SELECT * FROM ");
		String numeTabel;
		EditManualPanel editManPanel;
		JTable viewTable;
		JButton deleteButton, insertButton, closeButton;
		InterfataGrafica interfataGrafica;
		Hashtable<String, Atribute> arrayCpAtribHash;
		Hashtable<String, Atribute> arrayIdxAtribHash;
		ResultSet rez;	
		ResultSetMetaData metaData;	
		boolean actualizez = false;
		int nrTotCol = 0, nrTotRand = 0; 
	
	public TabelOperatii(InterfataGrafica interfataGrafica, String comanda,
		ResultSet rez) {
		super("Vedere tabel și operații asupra înregistrărilor");
		this.interfataGrafica = interfataGrafica;
		this.rez = rez;
		editManPanel = new EditManualPanel();
		editManPanel.editManButton.setVisible(false);
		// citim structura tabelului numeTabel :
		numeTabel = "";
		numeTabel = (String)
			interfataGrafica.intGrafList.getSelectedValue();
		ObjectInputStream objInStr = null;
		try {
			objInStr = new ObjectInputStream(
				new FileInputStream(interfataGrafica.numeBdString + 
				"\\" + numeTabel + ".txt"));
		}
		catch (FileNotFoundException fileExc) {fileExc.getMessage();}
		catch (IOException ioExc) {ioExc.getMessage();}
		TabelMysqlObj tabObj = null;
		try {
			if (objInStr != null)
				tabObj = (TabelMysqlObj)objInStr.readObject();
			if (objInStr != null) objInStr.close();
			if (comanda.equals("")) {	//e SELECT *
				comandaString = comandaString.append(numeTabel);
				comandaHtmlString = comandaHtmlString.append(
					"<font color=\"red\">" + numeTabel + "</font><br>");
			}
			else {
				comandaString = new StringBuffer(comanda);
				comandaHtmlString = new StringBuffer("<html>" + 
				"<font color=\"green\">" + comanda.toString() + "</font></html>");
			}
			editManPanel.comandaEditorPane.setText(comandaHtmlString.toString());
		}
		
		catch (ClassNotFoundException classExc) {
			classExc.getMessage();
		}
		catch(IOException except) {except.getMessage();}
		if (tabObj != null) {
			arrayCpAtribHash = tabObj.getArrayCpAtribHash();
			arrayIdxAtribHash = tabObj.getArrayIdxAtribHash();
		}
		try {
			metaData = rez.getMetaData();
			nrTotCol = metaData.getColumnCount();
		    rez.last();                   
	      	nrTotRand = rez.getRow();
		}
		catch (SQLException exc) {
			exc.getMessage();
			return;
		}
		Vector<String> randGol = new Vector<String>();
		for (int i = 0; i < nrTotCol; i++)
			randGol.addElement("");
		 //numele coloanelor :
		 String[] nmColArray = new String[nrTotCol];
		 try {
		 	for (int col = 0; col < nrTotCol; col++) {
		 		nmColArray[col] = metaData.getColumnName(col + 1);
		 	}
		 }
		 catch (SQLException exc) {
		  	  exc.getMessage();
			  return;
		 }
		// creăm tabelul
		DefaultTableModel dtm = new DefaultTableModel(nmColArray, nrTotRand);
		dtm.addTableModelListener(this);	//ascultă la modific. date tabel
		viewTable = new JTable(dtm);
		viewTable.setPreferredScrollableViewportSize(new Dimension(
			900, 450));
		viewTable.getSelectionModel().setSelectionMode(
			ListSelectionModel.SINGLE_SELECTION);
		viewTable.getSelectionModel().addListSelectionListener(this);
		// populăm tabelul cu rezultatele din ResultSet:
		int rand = 0;
		try {
		  	 rez.beforeFirst();
		  	 while (rez.next()) {
			  	for (int col = 0; col < nrTotCol; col++) {
					dtm.setValueAt(rez.getString(col + 1), rand, col);
				}
		  		rand++;
		  	 }
		}
		catch (SQLException exc) {
		  	  exc.getMessage();
			  return;
		}
		dtm.fireTableChanged(null);
		//setăm clicuri de editare pt. coloane :
		JTextField textField = new JTextField();
	 	TableColumnModel tcm = viewTable.getColumnModel();
	 	TableColumn tableColumn = null;
	 	for (int col = 0; col < nrTotCol; col++) {
			tableColumn = tcm.getColumn(col);
			tableColumn.setCellEditor(new DefaultCellEditor(textField));	
			((DefaultCellEditor)tableColumn.getCellEditor()
				).setClickCountToStart(2);
	 	}

		//tooltip pt. fiec. coloană cu atrib. cp.:
		try {
			for (int col = 0; col < nrTotCol; col++) {
				TableColumn colCrt = null;
				try {
					colCrt = viewTable.getColumnModel().getColumn(col);
				}
				catch (ArrayIndexOutOfBoundsException exc) {}
				String nmCol = metaData.getColumnName(col + 1);
				Atribute atr = null;
				if (arrayCpAtribHash != null)
					atr = arrayCpAtribHash.get(nmCol);
				if (atr != null) {
					DefaultTableCellRenderer dtcr = 
						new DefaultTableCellRenderer();
					dtcr.setToolTipText("<html>Pentru a edita o celulă, " +
						"obligatoriu faceți dublu clic pe ea<br>" +
						atr.afisAtrib(true) + "</html>");
					if (colCrt != null)
						colCrt.setCellRenderer(dtcr);
				}
			}
		}
		catch (SQLException exc) {
			exc.getMessage();
			return;
		}
		
		JScrollPane scrollPane = new JScrollPane(viewTable);
		closeButton = new JButton("Închide");
		closeButton.addActionListener(this);
		closeButton.setMnemonic(KeyEvent.VK_N);
		deleteButton = new JButton("Șterge");
		deleteButton.addActionListener(this);
		deleteButton.setMnemonic(KeyEvent.VK_T);
		insertButton = new JButton("Inserează");
		insertButton.addActionListener(this);
		insertButton.setMnemonic(KeyEvent.VK_I);
		// Panelul cu butoane
		JPanel butPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 15));
		butPanel.setOpaque(true);
		butPanel.add(closeButton);
		butPanel.add(deleteButton);
		butPanel.add(insertButton);
		// panelul ce cuprinde tot :
		JPanel reuniunePanel = new JPanel();
		reuniunePanel.setOpaque(true);
		reuniunePanel.setLayout(new BorderLayout(0, 20));
		reuniunePanel.add(editManPanel, BorderLayout.NORTH);
		reuniunePanel.add(scrollPane, BorderLayout.CENTER);
		reuniunePanel.add(butPanel, BorderLayout.SOUTH);
		reuniunePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		setContentPane(reuniunePanel);
		dtm.addRow(randGol);
		actualizez = true;
		
	}

	public boolean eRandCorect(int nrRand) {
		for (int nrCol = 0; nrCol < viewTable.getColumnCount(); nrCol++) {
			String nmColCrt = viewTable.getColumnName(nrCol);
			Atribute atr = arrayCpAtribHash.get(nmColCrt);
			String valCellStr = viewTable.getValueAt(nrRand, nrCol).toString();
			if (valCellStr.equals("")) {
				if (! atr.getProperty("default").equals("no")) {	//completăm cu default-ul
					viewTable.setValueAt(atr.getProperty("default").substring(8), 
						nrRand, nrCol);
				}
				else if (! atr.getProperty("auto_increment").equals(
						"auto_increment") && atr.getProperty("not null").equals(
						"not null")){
					JOptionPane.showMessageDialog(null, "Celula\n de pe rândul " 
					+ new Integer(nrRand + 1).toString() + " \n și coloana "
				 	+ new Integer(nrCol + 1).toString() + "\ntrebuie completată!",
				 	"Atenție ! Eroare !", JOptionPane.ERROR_MESSAGE);
				 	return false;
				}
			}
		}
		return true;
	}
	
	public void actionPerformed(ActionEvent e) {
		JButton src = (JButton) e.getSource();
		int selRand = viewTable.getSelectedRow();
		if (src == insertButton) {
			try {
				if (selRand != viewTable.getRowCount() - 1)	// nu e ultimul rând
					return;
				if (! eRandCorect(selRand))
					return;
				else {
					rez.insertRow();
					nrTotRand++;
					Vector<String> randGol = new Vector<String>();
					for (int i = 0; i < nrTotCol; i++)
						randGol.addElement("");
					((DefaultTableModel)viewTable.getModel()).addRow(randGol);
				}
			}
			catch (SQLException exc) {
				JOptionPane.showMessageDialog(null, "Nu s-a putut executa "
			 	+ " comanda MySQL \nINSERT INTO " + numeTabel + " VALUES...\n" + 
			 	exc.getMessage(), "Atenție ! Eroare !", JOptionPane.ERROR_MESSAGE);
			}
		}
		else if (src == deleteButton) {
			if (selRand == viewTable.getRowCount() - 1)	// nu e ultimul rând
				return;
			try {
				rez.deleteRow();
				((DefaultTableModel)viewTable.getModel()).removeRow(selRand);
				nrTotRand--;
			}
			catch (SQLException exc) {
				JOptionPane.showMessageDialog(null, "Nu s-a putut șterge "
			 	+ "rândul selectat\n" + 
			 	exc.getMessage(), "Atenție ! Eroare !", JOptionPane.ERROR_MESSAGE);
			}
		}
		else if (src == closeButton) {
			dispose();
		}
	}
	
	public void tableChanged(TableModelEvent e) {
		if (! actualizez)	//inițial, la creare tabel
			return;
		if (e.getType() != TableModelEvent.UPDATE)
			return;
		int nrRand = e.getFirstRow();
		int nrCol = e.getColumn();
		String tipCrtCol = "";
		String nmColCrt = "";
		try {
			tipCrtCol = metaData.getColumnTypeName(nrCol + 1);
			nmColCrt = metaData.getColumnName(nrCol + 1);
		}
		catch (SQLException exc) {
			JOptionPane.showMessageDialog(null, exc.getMessage(),
		 	"Atenție ! Eroare !", JOptionPane.ERROR_MESSAGE);
		 	return;
		}
		Atribute atr = arrayCpAtribHash.get(nmColCrt);
		try {
			if (tipCrtCol.startsWith("integer")) {
				int val = Integer.parseInt(viewTable.getValueAt(nrRand, 
				nrCol).toString()); 	
//JOptionPane.showMessageDialog(null, nmColCrt+"\n"+new Integer(val));
				rez.updateInt(nmColCrt, val);
			} 
			else if (tipCrtCol.startsWith("tinyint")) {
				byte val = Byte.parseByte(viewTable.getValueAt(nrRand, 
				nrCol).toString());
				rez.updateByte(nmColCrt, val); 	
			}
			else if (tipCrtCol.startsWith("smallint") || tipCrtCol.equals(
				"year")) {
				short val = Short.parseShort(viewTable.getValueAt(nrRand, 
				nrCol).toString());
				rez.updateShort(nmColCrt, val); 	
			} 	
			else if (tipCrtCol.startsWith("bigint")) {
				long val = Long.parseLong(viewTable.getValueAt(nrRand, 
				nrCol).toString());
				rez.updateLong(nmColCrt, val); 	
			} 	 	
			else if (tipCrtCol.startsWith("float")) {
				float val = Float.parseFloat(viewTable.getValueAt(nrRand, 
				nrCol).toString()); 	
				rez.updateFloat(nmColCrt, val); 	
			}
			else if (tipCrtCol.startsWith("double") || tipCrtCol.equals(
				"numeric")) {
				double val = Double.parseDouble(viewTable.getValueAt(nrRand, 
				nrCol).toString()); 	
				rez.updateDouble(nmColCrt, val); 	
			}
			else if (tipCrtCol.startsWith("date")) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				java.util.Date val = sdf.parse(viewTable.getValueAt(
					nrRand,nrCol).toString(), new ParsePosition(0)); 
				rez.updateDate(nmColCrt, java.sql.Date.valueOf(
					viewTable.getValueAt(nrRand,nrCol).toString())); 		
			}
/*			else if (tipCrtCol.equals("time")) {
				SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
				Time val = (Time) sdf.parse(viewTable.getValueAt(
					nrRand,nrCol).toString(), new ParsePosition(0)); 	
				rez.updateTime(nmColCrt, java.sql.Time.valueOf(
					viewTable.getValueAt(nrRand,nrCol).toString())); 	
			}
			else if (tipCrtCol.startsWith("datetime")) {
				SimpleDateFormat sdf = new SimpleDateFormat(
					"yyyy-MM-dd hh:mm:ss");
				java.util.Date val = sdf.parse(viewTable.getValueAt(
					nrRand,nrCol).toString()); 	
				rez.updateDate(nmColCrt, java.sql.Date.valueOf(
					viewTable.getValueAt(nrRand,nrCol).toString())); 	
			}
			else if (tipCrtCol.startsWith("timestamp"))  {
				String format = "yyyyMMddhhmmss";
				if (! atr.getProperty("lungCamp").equals("no")) {
					int lung = Integer.parseInt(atr.getProperty(
						"lungCamp"));
					format = format.substring(0, lung);
				}
				SimpleDateFormat sdf = new SimpleDateFormat(format);
				java.util.Date val = sdf.parse(viewTable.getValueAt(
					nrRand,nrCol).toString()); 	// doar parsăm
				rez.updateTimestamp(nmColCrt, Timestamp.valueOf(
					viewTable.getValueAt(nrRand,nrCol).toString())); 	
			}*/
			else if (tipCrtCol.startsWith("enum(") || 
				tipCrtCol.startsWith("set(")) {
				String val = viewTable.getValueAt(nrRand,
					nrCol).toString();
				if (tipCrtCol.indexOf("(" + val + ", ") < 0 && 
					tipCrtCol.indexOf(", " + val + ", ") < 0 &&
					tipCrtCol.indexOf(", " + val + ")") < 0) {
				}
				else	
					rez.updateString(nmColCrt, viewTable.getValueAt(
						nrRand,nrCol).toString());
			}
			else {
				rez.updateString(nmColCrt, viewTable.getValueAt(
						nrRand,nrCol).toString());
			}
			if (nrRand < viewTable.getRowCount() - 1)
				rez.updateRow();	//e actualizat 
		}
		catch (Exception exc) {
			JOptionPane.showMessageDialog(null, "Nu s-a putut înscrie în  "
		 	+ "celula\n de pe rândul " + new Integer(nrRand + 1).toString() + 
		 	" \n și coloana " + new Integer(nrCol + 1).toString(),
		 	"Atenție ! Eroare !", JOptionPane.ERROR_MESSAGE);
			//viewTable.changeSelection(nrRand, nrCol, false, false);
		}
	}
	
	public void valueChanged(ListSelectionEvent e) {
		if (e.getValueIsAdjusting()) return;
		ListSelectionModel lsm = (ListSelectionModel)e.getSource();
		DefaultTableModel dtm = (DefaultTableModel) viewTable.getModel();
		if (lsm.isSelectionEmpty()) return;
		int rand = lsm.getMinSelectionIndex();
//JOptionPane.showMessageDialog(null, new Integer(rand));
		try {
			if (rand == dtm.getRowCount() - 1) { 		//avem inserare
				rez.moveToInsertRow();
			}
			else
				rez.absolute(rand + 1);
		}	
		catch (SQLException exc) {
			exc.getMessage();
		}
	}
}
