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

import java.lang.reflect.Method;
import java.util.ArrayList;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Csubák Péter
 */
public class TableGenerator {

    /**
     * Egy String tömbben visszaadja a megadott osztályban található getterekhez 
     * kapcsolódó guineveket, ami a táblázatok címeként használható.
     * (A működéséhez feltétlenül szükséges, hogy a NameConnector annotáció
     * be legyen állítva az osztály getterein)
     * @param clazz Az osztály amiből ki akarjuk nyerni a guineveket.
     * @return A guineveket tartalmazó String tömb.
     */
    public static String[] getTableTitle(Class clazz) {
        ArrayList<String> res = new ArrayList<String>();
        for (Method m : clazz.getMethods()) {
            if (m.isAnnotationPresent(NameConnector.class)) {
                NameConnector nc = m.getAnnotation(NameConnector.class);
                if (m.getName().startsWith("get") || m.getName().startsWith("is")) {
                    res.add(nc.guiName());

                }
            }
        }

        String[] re = new String[res.size()];
        int i = 0;
        for (String s : res) {
            re[i++] = s;
        }
        return re;
    }

    /**
     * A táblázatok feltöltéséhez adja meg az objektum tömböt, melyhez az adatokat 
     * egy ArrayList-ből nyeri ki. Az adatok sorrendjét a getTableTitle metódus
     * által meghatározott címek sorrendje adja.
     * (A működéséhez feltétlenül szükséges, hogy a NameConnector annotáció
     * be legyen állítva az ArrayList elemeinek getterein)
     * @param elements A táblázatban megjelenítendő elemeket tároló ArrayList
     * @return A Táblázat feltöltéséhez szükséges objektum tömb
     * @throws java.lang.Exception A felhasznált metódusok többféle kivételt is 
     * dobhatnak, amelyek kezelése a hívó félre hárul, de mivel ezek a kivételek
     * csak elég súlyos esetben fordulhatnak elő, így alapvetően elég egy 
     * általános kezelő.
     */
    public static Object[][] getTableContent(ArrayList<?> elements) throws Exception {
        Object[][] res;
        ArrayList<ArrayList<Object>> res2 = new ArrayList<ArrayList<Object>>();
        int i = 0;
        for (Object element : elements) {
            Class clazz = element.getClass();
            String[] title = getTableTitle(clazz);
            res2.add(new ArrayList<Object>());
            int j = 0;
            for (Method m : clazz.getMethods()) {
                if (m.isAnnotationPresent(NameConnector.class)) {
                    NameConnector nc = m.getAnnotation(NameConnector.class);
                    if ((m.getName().startsWith("get") || m.getName().startsWith("is")) && nc.guiName().equals(title[j])) {
                        res2.get(i).add(m.invoke(element));
                        System.out.println(m.getName()+";");
                        System.out.println(m.invoke(element));
                        ++j;
                    }
                }
            }
            ++i;
        }

        res = new Object[res2.size()][];

        int k = 0;
        for (ArrayList<Object> list : res2) {
            res[k++] = list.toArray();
        }

        return res;
    }

    public static ArrayList<?> buildToThis(JTable table, ArrayList<?> list) throws VisibleException {
        if (table != null) {
            try {

                if (!list.isEmpty()) {
                    table.setModel(new DefaultTableModel(getTableContent(list), getTableTitle(list.get(0).getClass())));
                }
                return list;
            } catch (Exception ex) {
                if (ex instanceof VisibleException) {
                    throw (VisibleException) ex;
                } else {
                    ex.printStackTrace();
                }
            }
        }
        return null;
    }
}
