package calhoun.gebo.internal.db;

import java.sql.ResultSet;
import java.sql.SQLException;

import calhoun.bean.ValuedFeatureType;
import calhoun.gebo.model.FeatureTrack;
import calhoun.gebo.model.Sequence;
import calhoun.gebo.model.ValuedFeature;
import calhoun.gebo.ui.render.SegmentRenderContext;

public class CalhounValuedFeature extends CalhounFeature implements
        ValuedFeature {

    public CalhounValuedFeature(Sequence sequence, FeatureTrack track,
            ResultSet resultSet) throws SQLException {
        super(sequence, track, resultSet, false, false, 0);
        m_bean = (calhoun.bean.ValuedFeature) CalhounConnectionManager
                .getInstance().getDbSession().getById(
                        calhoun.bean.ValuedFeature.class, getId());
        if (((CalhounTrack) track).getSubclass().equals("NQSB")) {
            m_max = 2.0;
        } else {
            m_max = m_bean.getMaxValue();
        }
        m_min = m_bean.getMinValue();
        // findBounds();
    }

    public int getInterval() {
        return m_bean.getSamplingInterval();
    }

    public boolean getBooleanAt(int baseIndex) {
        return m_bean.getBooleanAt(baseIndex);
    }

    public byte getByteAt(int baseIndex) {
        return m_bean.getByteAt(baseIndex);
    }

    public int getIntegerAt(int baseIndex) {
        return m_bean.getIntegerAt(baseIndex);
    }

    public double getDoubleAt(int baseIndex) {
        return m_bean.getDoubleAt(baseIndex);
    }

    public double getForcedDoubleAt(int baseIndex) {
        ValuedFeatureType vt = m_bean.getValueType();
        if (vt.equals(ValuedFeatureType.INTEGER)) {
            return (double) getIntegerAt(baseIndex);
        } else if (vt.equals(ValuedFeatureType.FLOAT)) {
            return getDoubleAt(baseIndex);
        } else if (vt.equals(ValuedFeatureType.BOOLEAN)) {
            boolean b = getBooleanAt(baseIndex);
            return b ? 1.0 : 0.0;
        } else if (vt.equals(ValuedFeatureType.BYTE)) {
            return (double) getByteAt(baseIndex);
        }
        return 0.0;
    }

    public Class getValueClass() {
        ValuedFeatureType vt = m_bean.getValueType();
        if (vt.equals(ValuedFeatureType.INTEGER)) {
            return java.lang.Integer.class;
        } else if (vt.equals(ValuedFeatureType.FLOAT)) {
            return java.lang.Double.class;
        } else if (vt.equals(ValuedFeatureType.BOOLEAN)) {
            return java.lang.Boolean.class;
        } else if (vt.equals(ValuedFeatureType.BYTE)) {
            return java.lang.Byte.class;
        }
        return null;
    }

    public double getRelativeScorePercent(int baseIndex) {
        double score = getForcedDoubleAt(baseIndex);
        return (score - m_min) / (m_max - m_min);
    }

    // protected void findBounds() {
    // for (int sp = getStart(); sp < getLength(); sp += getInterval()) {
    // double score = getForcedDoubleAt(sp);
    // if (score > m_max) {
    // m_max = score;
    // }
    // if (m_min == 0 || m_min > score) {
    // m_min = score;
    // }
    // }
    // }

    public double getMax() {
        return m_max;
    }

    public double getMin() {
        return m_min;
    }

    public void setMax(double max) {
        m_max = max;
    }

    public double getMeanScore(int baseA, int baseZ) {
        int intervals = 0;
        double sumScore = 0.0;
        for (int base = baseA; base <= baseZ; base += getInterval()) {
            sumScore += getForcedDoubleAt(base);
            intervals++;
        }
        return sumScore / (double) intervals;
    }

    public double getMeanRelativeScorePercent(int baseA, int baseZ) {
        return (getMeanScore(baseA, baseZ) - m_min) / (m_max - m_min);
    }

    public double getMeanRelativeScorePercent(SegmentRenderContext src, int px) {
        int spA = src.getSp(px) + 1;
        int spZ = spA + (int) src.getSpPerPx();
        if (spZ > getStop()) {
            spZ = getStop();
        }
        return getMeanRelativeScorePercent(spA, spZ);
    }

    private double m_max;
    private double m_min;
    private calhoun.bean.ValuedFeature m_bean;

}
