package usda.weru.weps.reports.query;

import de.schlichtherle.truezip.file.TFile;
import java.sql.SQLException;
import java.sql.Types;
import org.apache.log4j.Logger;
import usda.weru.util.ConversionCalculator;
import usda.weru.util.Util;
import usda.weru.weps.RunFileData;

/**
 *
 * @author joelevin
 */
public class BarriersResultSet extends WepsResultSet {

    private static final Logger LOGGER = Logger.getLogger(BarriersResultSet.class);

    /**
     *
     */
    public static final String NAME = "barriers";

    /**
     *
     */
    public static final String COLUMN_RUNID = "runid";

    /**
     *
     */
    public static final String COLUMN_LOCATION = "location";

    /**
     *
     */
    public static final String COLUMN_TYPE = "type";

    /**
     *
     */
    public static final String COLUMN_HEIGHT = "height";

    /**
     *
     */
    public static final String COLUMN_WIDTH = "width";

    /**
     *
     */
    public static final String COLUMN_POROSITY = "porosity";
    private final WepsConnection c_con;
    private boolean c_filled;

    /**
     *
     * @param con
     * @throws SQLException
     */
    public BarriersResultSet(WepsConnection con) throws SQLException {
        c_con = con;
        addColumn(COLUMN_RUNID, Types.INTEGER, 10, 0);
        addColumn(COLUMN_LOCATION, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_TYPE, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_HEIGHT, Types.DOUBLE, 10, 3);
        addColumn(COLUMN_WIDTH, Types.DOUBLE, 10, 3);
        addColumn(COLUMN_POROSITY, Types.DOUBLE, 10, 3);
    }

    /**
     *
     * @return
     */
    @Override
    public String getName() {
        return NAME;
    }

    /**
     *
     * @return
     */
    protected boolean isUSUnits() {
        return Util.USUnits.equals(c_con.getUnits());
    }

    /**
     *
     * @throws SQLException
     */
    @Override
    public synchronized void fill() throws SQLException {
        if (c_filled) {
            return;
        }
        RunFileData[] files = c_con.getRFD();

        for (int i = 0; i < files.length; i++) {
            RunFileData data = files[i];

            parseBarrier(i, "North", data.getData(RunFileData.BarrierN));
            parseBarrier(i, "East", data.getData(RunFileData.BarrierE));
            parseBarrier(i, "South", data.getData(RunFileData.BarrierS));
            parseBarrier(i, "West", data.getData(RunFileData.BarrierW));

        }

        c_filled = true;
    }

    private void parseBarrier(int runId, String location, String barrierString) throws SQLException {
        if (barrierString == null || barrierString.startsWith("none")) {
            return;
        }
        Object[] row = createNewRow(true);
        setRowValue(row, COLUMN_RUNID, runId);
        setRowValue(row, COLUMN_LOCATION, location);

        String[] parts = barrierString.split("\\|", 4);

        setRowValue(row, COLUMN_TYPE, parts[0].trim());

        //height
        try {
            Double height = Double.valueOf(parts[1].trim());
            if (isUSUnits()) {
                height = ConversionCalculator.convert(height, "m", "ft");
            }
            setRowValue(row, COLUMN_HEIGHT, height);
        } catch (NumberFormatException nfe) {
            LOGGER.error("Unable to parse barrier height.", nfe);
        } catch (ConversionCalculator.ConversionNotFoundException | ConversionCalculator.UnitNotFoundException e) {
            LOGGER.error("Unable to convert barrier height.", e);
        }

        //width
        try {
            Double width = Double.valueOf(parts[2].trim());
            if (isUSUnits()) {
                width = ConversionCalculator.convert(width, "m", "ft");
            }
            setRowValue(row, COLUMN_WIDTH, width);
        } catch (NumberFormatException nfe) {
            LOGGER.error("Unable to parse barrier width.", nfe);
        } catch (ConversionCalculator.ConversionNotFoundException | ConversionCalculator.UnitNotFoundException e) {
            LOGGER.error("Unable to convert barrier width.", e);
        }

        //porosity
        try {
            Double porosity = Double.valueOf(parts[3].trim());
            setRowValue(row, COLUMN_POROSITY, porosity);
        } catch (NumberFormatException nfe) {
            LOGGER.error("Unable to parse barrier porosity.", nfe);
        }

    }

}
