package com.fitbank.common.dtoutils;

import com.fitbank.common.beanutils.BeanConversionUtils;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.ScrollableResults;
import com.fitbank.common.logger.FitbankLogger;
import com.fitbank.dto.management.Field;
import com.fitbank.dto.management.Record;
import com.fitbank.dto.management.Table;

/**
 * Clase que se encarga de llenar una tabla tipo Detail dado un ScrollableResults, la tabla que se va a llenar y las
 * columnas.
 * 
 * @author BANTEC Inc.
 * @version 2.0
 */
public class ScrollToPage {

    /** numero de registros recibidos */
    private Integer count;

    /**
     * Constructor de la clase
     *
     * @param sr Resultado de la consulta SQL
     * @param table Tabla
     * @param pColumns Campos para los registros
     * @throws Exception
     */
    public ScrollToPage(ScrollableResults sr, Table table, String[] pColumns) throws Exception {
        this(sr, table, pColumns, true);
    }
    
    /**
     * Constructor de la clase
     *
     * @param sr Resultado de la consulta SQL
     * @param table Tabla
     * @param pColumns Campos para los registros
     * @throws Exception
     */
    public ScrollToPage(ScrollableResults sr, Table table, String[] pColumns, boolean especial) throws Exception {
        this(sr, table, pColumns, especial, true);
    }

    /**
     * Constructor de la clase
     *
     * @param sr Resultado de la consulta SQL
     * @param table Tabla
     * @param pColumns Campos para los registros
     * @throws Exception
     */
    public ScrollToPage(ScrollableResults sr, Table table, String[] pColumns, boolean especial, boolean clean) throws Exception {
        ArrayList<Object> listado = new ArrayList<Object>();
        try {
            while (sr.next()) {
                ArrayList<Object> temp = new ArrayList<Object>();
                for (int i = 0; i < pColumns.length; i++) {
                    temp.add(sr.get(i));
                }
                if (listado.size() > (table.getRequestedRecords() + 1)) {
                    break;
                }
                listado.add(temp);
            }
        } finally {
            sr.close();
        }
        this.count = listado.size();
        FitbankLogger.getLogger().debug(this.count);
        if (this.count != 0) {
            if (this.count > table.getRequestedRecords()) {
                table.setHasMorePages("1");
                this.count--;
            } else {
                table.setHasMorePages("0");
            }
            this.fillTable(table, pColumns, listado, especial, clean);
        }
    }

    /**
     * Llena la tabla con los registros
     *
     * @param table
     * @param pColumns
     * @param listado
     */
    @SuppressWarnings("unchecked")
    private void fillTable(Table table, String[] pColumns, List<Object> listado, boolean especial, boolean clean) {
        if(clean) {
            table.clearRecords();
        }

        if(table.getRecordCount() != 0) {
            FitbankLogger.getLogger().warn("Se esta poblando una tabla, que no esta vacia. Favor revise su codigo o use la funcionalidad de limpiza de registros [" + table.getName() + ":" + table.getAlias() + "]");
        }

        for (int i = 0; i < this.count; i++) {
            if (i >= table.getRequestedRecords()) {
                break;
            }
            Record record = new Record();
            ArrayList<Object> detalle = (ArrayList<Object>) listado.get(i);
            for (int j = 0; j < detalle.size(); j++) {
                Field field = new Field(pColumns[j]);
                field.setAlias(table.getAlias());
                Object value = BeanConversionUtils.process(detalle.get(j));

                if (especial) {
                    if (value == null) {
                        value = "";
                    }
                    if (field.getName().compareTo("CPERSONA") == 0) {
                        field.setValue("" + value);
                        field.setOldValue("" + value);
                    } else {
                        field.setValue(value);
                        field.setOldValue("" + value);
                    }
                } else {
                    field.setValue(value);
                }

                record.addField(field);
            }
            table.addRecord(record);
        }
    }
}
