package usda.weru.weps.reports.query;

import java.sql.SQLException;
import java.sql.Types;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import org.apache.log4j.Logger;
import org.jscience.economics.money.Currency;
import usda.weru.util.Units;
import usda.weru.util.Util;
import usda.weru.weps.fuel.EnergyPerVolume;
import usda.weru.weps.fuel.Fuel;
import usda.weru.weps.fuel.FuelDAO;
import usda.weru.weps.fuel.PricePerVolume;

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

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

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

    /**
     *
     */
    public static final String COLUMN_NAME = "name";

    /**
     *
     */
    public static final String COLUMN_DISPLAY = "display";

    /**
     *
     */
    public static final String COLUMN_DESCRIPTION = "description";

    /**
     *
     */
    public static final String COLUMN_DIESEL = "diesel";

    /**
     *
     */
    public static final String COLUMN_ENERGY = "energy";

    /**
     *
     */
    public static final String COLUMN_PRICE = "price";

    private final WepsConnection c_con;
    private boolean c_filled;

    /**
     *
     * @param con
     * @throws SQLException
     */
    public FuelsResultSet(WepsConnection con) throws SQLException {
        c_con = con;

        //Columns expected in the file
        addColumn(COLUMN_NAME, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_DISPLAY, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_DESCRIPTION, Types.VARCHAR, 250, 0);

        addColumn(COLUMN_DIESEL, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_ENERGY, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_PRICE, Types.DOUBLE, 10, 5);
    }

    /**
     *
     * @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;
        }
        //used as the reference fuel in the science model
        Fuel diesel = FuelDAO.getInstance().getFuel("diesel");
        double dieselEnergy = diesel.getEnergy().doubleValue(getEnergyUnit(isUSUnits()));

        Fuel[] fuels = FuelDAO.getInstance().getFuels();

        for (Fuel fuel : fuels) {
            Object[] row = createNewRow(true);

            setRowValue(row, COLUMN_NAME, fuel.getName());
            setRowValue(row, COLUMN_DISPLAY, fuel.getDisplayName());
            setRowValue(row, COLUMN_DESCRIPTION, fuel.getDescription());

            double energy = fuel.getEnergy().doubleValue(getEnergyUnit(isUSUnits()));
            setRowValue(row, COLUMN_ENERGY, energy);

            double price = fuel.getPrice().doubleValue(getPriceUnit(isUSUnits()));
            setRowValue(row, COLUMN_PRICE, price);

            setRowValue(row, COLUMN_DIESEL, energy / dieselEnergy);
        }
        c_filled = true;
    }

    private static Unit<EnergyPerVolume> getEnergyUnit(boolean us) {
        if (us) {
            return Units.createEnergyPerVolumeUnit(Units.BTU, NonSI.GALLON_LIQUID_US);
        } else {
            return Units.createEnergyPerVolumeUnit(SI.KILO(SI.JOULE), NonSI.LITER);
        }
    }

    private static Unit<PricePerVolume> getPriceUnit(boolean us) {
        if (us) {
            return Units.createPricePerVolumeUnit(Currency.USD, NonSI.GALLON_LIQUID_US);
        } else {
            return Units.createPricePerVolumeUnit(Currency.USD, NonSI.LITER);
        }
    }

    /**
     *
     * @param columnName
     * @param us
     * @return
     */
    public static String getDisplayUnits(String columnName, Boolean us) {
        if (COLUMN_ENERGY.equals(columnName)) {
            Unit<EnergyPerVolume> unit = getEnergyUnit(us);
            return unit.toString();
        } else if (COLUMN_PRICE.equals(columnName)) {
            Unit<PricePerVolume> unit = getPriceUnit(us);
            return unit.toString();
        } else if ("volume".equals(columnName)) {
            if (us) {
                return NonSI.GALLON_LIQUID_US.toString();
            } else {
                return NonSI.LITER.toString();
            }
        } else if ((COLUMN_ENERGY + "novolume").equals(columnName)) {
            if (us) {
                return Units.BTU.toString();
            } else {
                return SI.KILO(SI.JOULE).toString();
            }
        } else if ((COLUMN_PRICE + "novolume").equals(columnName)) {
            return Currency.USD.toString();
        }
        return null;
    }
}
