package calhoun.gebo.internal.db;

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

import calhoun.bean.BioSequence;
import calhoun.gebo.api.SequenceManager;
import calhoun.gebo.api.TrackManager;
import calhoun.gebo.model.Alphabet;
import calhoun.gebo.model.GeneticCode;
import calhoun.gebo.model.Sequence;
import calhoun.gebo.model.SequenceGroup;
import calhoun.gebo.model.Strand;
import calhoun.gebo.util.Informer;
import calhoun.gebo.util.Q;
import calhoun.gebo.util.S;
import calhoun.gebo.util.U;

public class CalhounSequence extends Sequence {

    private static Informer I = new Informer(CalhounSequence.class);

    public CalhounSequence(ResultSet resultSet) throws Exception {
        super(CalhounSequenceManager.getInstance(), resultSet.getString(2),
                resultSet.getString(1), resultSet.getInt(3),
                CalhounTrackManager.getInstance(),
                CalhounSequenceManager.getInstance().getSequenceGroup(
                        resultSet.getString(6)), resultSet.getInt(7));
        // I.warn("construction(a)");
        this.getTrackManagerRegistry()
                .add(CalhounXMLTrackManager.getInstance());
        this.getTrackManagerRegistry().add(
                CalhounPolymorphicTrackManager.getInstance());
        int geneticCode = resultSet.getInt(4);
        if (geneticCode == 0) {
            I.warn("Genetic code for this." + getId()
                    + " is 0! Please fix in the database."
                    + "\nTreating as Genetic Code 1.");
            geneticCode = 1;
        }
        this.setCode(GeneticCode.getCodeByNumber(geneticCode));
        String alphabetCode = resultSet.getString(5);
        if (alphabetCode != null) {
            if (alphabetCode.equals("P")) {
                U.println("Setting alphabet to Protein!");
                this.setAlphabet(Alphabet.PROTEIN);
            }
        }
        if (getPrimarySequenceGroup() != null) {
            String cellType = ((CalhounSequenceGroup) getPrimarySequenceGroup())
                    .getCellType();
            this.setCellType(cellType);
            setEditability(this);
        }
        // I.warn("construction(z)");
    }

    public void setBioSequence(BioSequence bs) {
        // TODO: horrid hack.
        m_bioSequence = bs;
    }

    public static String getSelectSql() {
        return "SELECT ap_id, ap_description, ap_length, ap_genetic_code, ap_type, ap_group, ap_group_order FROM ap_bio_sequence ";
    }

    private void setEditability(Sequence sequence) {
        // TODO: fix for chinnappa.
        String joinedRoles = S.join("','", CalhounSequenceManager.getInstance()
                .getRoles());
        String sql = "select * from ap_sequence_group_role SGR where SGR.ap_sequence_group = ? and SGR.ap_role IN ('"
                + joinedRoles + "')";
        // + SGR.ap_sequence_group" + " and"
        // + " SG.ap_sequence_id = ?" + " and " + " R.ap_role IN ('"
        // + joinedRoles + "')";
        try {
            Q.startStopWatch(sql);
            PreparedStatement statement = CalhounSequenceManager.getInstance()
                    .getConnection().prepareStatement(sql);
            statement.setString(1, sequence.getPrimarySequenceGroup().getId());
            ResultSet resultSet = statement.executeQuery();
            if (resultSet.next()) {
                // U.println("Setting editable to true");
                sequence.setEditable(true);
            } else {
                // U.println("Keeping editable as false");
            }
            statement.close();
            resultSet.close();
            Q.stopStopWatch(sql);
        } catch (SQLException e) {
            I.error("Could not set editablity for sequence " + sequence.getId()
                    + "\n" + sql, e);
        }
    }

    // public CalhounSequence(BioSequence bioSequence) {

    // }

    public int getLinkageGroupStart() {
        return m_bioSequence.getLinkageGroupStart();
    }

    public Strand getOrientation() {
        return Strand.fromBean(m_bioSequence.getOrientation());
    }

    private CalhounSequence(SequenceManager sequenceManager, String label,
            String id, int unOffsetLength, TrackManager defaultTrackManager,
            SequenceGroup sequenceGroup, int groupOrder) {
        super(sequenceManager, label, id, unOffsetLength, defaultTrackManager,
                sequenceGroup, groupOrder);
        // TODO Auto-generated constructor stub
    }

    private BioSequence m_bioSequence;

}
