package org.genemania.dw.tools;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import org.genemania.dw.util.DWUtil;
import org.genemania.dw.util.GenUtil;

/**
 * A class for handling IV summary/detail report. Serves as a container
 * for the IVReportDetail objects.
 * toString () represents an entry in the summary report, while 
 * toStringDetail () represents the corresponding entries in the detailed report.
 * This class has a package level access for the class itself, and
 * all its methods.
 *
 * @author rashadbadrawi
 */

class IVReportSummary {

    //validationType is also in IdentifierValidator,
    //but listed here for convenience when dumping.
    private String source;
    private String speciesName;
    private String validationType;

    private String IDType;
    private int numOfOccur;
    private int numTotal;
    private boolean isDisplayable;
    private ArrayList <IVReportDetail> IVDetSharedList = new ArrayList <IVReportDetail> ();
    private ArrayList <IVReportDetail> IVDetLOList = new ArrayList <IVReportDetail> ();
    private ArrayList <IVReportDetail> IVDetDepList = new ArrayList <IVReportDetail> ();

    protected IVReportSummary () {

        setIDType (GenUtil.NA);                                //defaults
        setIsDisplayable(true);
    }

    protected void setSource (String source) {

        GenUtil.validateString(source);
        this.source = source;
    }

    protected void setSpeciesName (String speciesName) {

        if (!DWUtil.isSupportedSpecies(speciesName)) {
            throw new IllegalArgumentException ("Unsupported species: " + speciesName);
        }
        this.speciesName = speciesName;
    }

    protected void setValidationType (String validationType) {

        if (!IdentifierValidator.VALID_TYPE_DEPRECATED.equals (validationType) &&
            !IdentifierValidator.VALID_TYPE_LEFTOVER.equals (validationType) &&
            !IdentifierValidator.VALID_TYPE_SHARED.equals (validationType)) {
            throw new IllegalArgumentException (
                                         "Invalid argument: " + validationType);
        }
        this.validationType = validationType;
    }

    protected void setIDType (String IDType) {

        GenUtil.validateString(IDType);
        this.IDType = IDType;
    }
    
    protected void incrementOccur () { numOfOccur++; }

    protected void incrementTotal () { numTotal++; }

    protected void setNumOfOccur (int numOfOccur) {

        GenUtil.validateNonNegativeInt(numOfOccur);
        this.numOfOccur = numOfOccur;
    }

    protected void setNumTotal (int numTotal) {

        GenUtil.validateNonNegativeInt(numTotal);
        this.numTotal = numTotal;
    }

    protected void setIsDisplayable (boolean isDisplayable) {

        this.isDisplayable = isDisplayable;
    }

    protected void setIVDetList (ArrayList <IVReportDetail> IVDetList, String
                              validationType) {

        if (IVDetList == null) {
            throw new IllegalArgumentException ("Invalid argument: " + IVDetList);
        }
        if (IdentifierValidator.VALID_TYPE_SHARED.equals (validationType)) {
           this.IVDetSharedList = IVDetList;
        } else if (IdentifierValidator.VALID_TYPE_LEFTOVER.equals (validationType)) {
           this.IVDetLOList = IVDetList;
        } else if (IdentifierValidator.VALID_TYPE_DEPRECATED.equals (validationType)) {
           this.IVDetDepList = IVDetList;
        } else {
            throw new IllegalArgumentException ("Unsupported validation type: " +
                                                validationType);
        }
    }

    protected String getSource () { return source; }

    protected String getSpeciesName () { return speciesName; }

    protected String getValidationType () { return validationType; }

    protected String getIDType () { return IDType; }

    protected int getNumOfOccur () { return numOfOccur; }

    protected int getNumTotal () { return numTotal; }

    protected boolean isDisplayable () { 
    
        //this section is needed to handle Ecoli single source special case
        if (getSpeciesName().equals (DWUtil.SP_ECOLI)) {
            return true;
        }
        //end section
        
        return isDisplayable;
    }

    protected ArrayList <IVReportDetail> getIVDetList (String validationType) {
        
        if (IdentifierValidator.VALID_TYPE_SHARED.equals (validationType)) {
           return this.IVDetSharedList;   
        } else if (IdentifierValidator.VALID_TYPE_LEFTOVER.equals (validationType)) {
           return this.IVDetLOList;        
        } else if (IdentifierValidator.VALID_TYPE_DEPRECATED.equals (validationType)) {
           return this.IVDetDepList;  
        } else {
            throw new IllegalArgumentException ("Unsupported validation type: " +
                                                validationType);
        }
    }

    @Override
    public String toString () {

        String tempStr = "";

        tempStr += getSource();
        tempStr += GenUtil.TAB;

        tempStr += getSpeciesName() + " (" + DWUtil.getTaxIDByName (getSpeciesName()) + ")";
        tempStr += GenUtil.TAB;

        tempStr += getValidationType();
        tempStr += GenUtil.TAB;

        tempStr += getIDType();
        tempStr += GenUtil.TAB;

        tempStr += getNumOfOccur();
        tempStr += GenUtil.TAB;

        tempStr += getNumTotal();
        
        return tempStr;
    }

    protected void toStringDetailShared (BufferedWriter bw) throws IOException {

        toStringDetail (IdentifierValidator.VALID_TYPE_SHARED, IVDetSharedList, bw);
    }

    protected void toStringDetailLO (BufferedWriter bw) throws IOException {

        toStringDetail (IdentifierValidator.VALID_TYPE_LEFTOVER, IVDetLOList, bw);
    }

    protected void toStringDetailDep (BufferedWriter bw) throws IOException  {

        toStringDetail (IdentifierValidator.VALID_TYPE_DEPRECATED, IVDetDepList, bw);
    }

    //Helper method.
    private void toStringDetail (String validationType, ArrayList <IVReportDetail>
                             IVDetList, BufferedWriter bw) throws IOException {

        for (int i = 0; i < IVDetList.size (); i++) {
            String tempStr = getSource();
            tempStr += GenUtil.TAB;

            tempStr += getSpeciesName() + " (" +
                       DWUtil.getTaxIDByName (getSpeciesName()) + ")";
            tempStr += GenUtil.TAB;

            if (IdentifierValidator.VALID_TYPE_SHARED.equals (validationType)) {
               tempStr += IVDetList.get (i).toStringShared();
            } else if (IdentifierValidator.VALID_TYPE_LEFTOVER.equals (validationType)) {
               tempStr += IVDetList.get (i).toStringLO();
            } else if (IdentifierValidator.VALID_TYPE_DEPRECATED.equals (validationType)) {
               tempStr += IVDetList.get (i).toStringDep();
            }
            bw.write (tempStr);
            bw.newLine ();
            bw.flush ();
        }
    }
}
