package org.baderlab.lola;

import org.baderlab.lola.resources.LolaResources;

import java.io.File;

/**
 Copyright 2007 Bader Lab

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

/**
 * Container for all user-provided parameters.
 *
 * User: moyez
 * Date: May 27, 2007
 * Time: 5:04:24 PM
 */
public class LolaParameterSet {

    //parameters
    private File profileFile = null;    //file containing profile or project file pointing to a set of profiles
    private File codonBiasFile = null;  //file containing a codon bias specification
    private boolean uniquePeptides;     //if true, load only unique peptides from profile; else load all peptides
    private double fuzzFactor;          //protein profile fuzz factor used as distance matrix pseudocount value
    private File outputPath = null;     //output directory path in which to save results
    private int logoStartIndex;         //the starting number on the logo graph X-axis
    private int logoHeight;             //the height, in pixels, of the logo
    private double logoTrimPercentage;  //height threshold (in % of max height) of colums on either side of profile
    private String logoImageFormat;     //format of the logo image file
    private String logoColorStyle;      //logo residue colour scheme
    private String treeTitle;           //title for logo tree
    private String treeImageFormat;     //output format of logo tree
    private String treeFilename;      //output file name for logo tree

    /**
     * Create a new parameter set with no values provided
     */
    public LolaParameterSet() {
        profileFile = null;
        codonBiasFile = null;
        uniquePeptides = LolaResources.UNIQUE_PEPTIDES_DEFAULT;
        fuzzFactor = LolaResources.FUZZ_FACTOR_DEFAULT;
        outputPath = null;
        logoStartIndex = LolaResources.LOGO_START_INDEX_DEFAULT;
        logoHeight = LolaResources.LOGO_HEIGHT_DEFAULT;
        logoTrimPercentage = LolaResources.LOGO_TRIM_PERCENTAGE_DEFAULT;
        logoImageFormat = LolaResources.LOGO_IMAGE_FORMAT_DEFAULT;
        logoColorStyle = LolaResources.COLOR_STYLE_DEFAULT;
        treeTitle = LolaResources.TREE_TITLE;
        treeImageFormat = LolaResources.TREE_IMAGE_FORMAT_DEFAULT;
        treeFilename = null;
    }

    /**
     * Create a new parameter set with ALL PARAMETER VALUES provided
     * @param profileFile
     */
    public LolaParameterSet(
            File profileFile,
            File biasFile,
            boolean uniquePeptides,
            double fuzzFactor,
            File outputPath,
            int logoStartIndex,
            int logoHeight,
            double logoTrimPercentage,
            String logoImageFormat,
            String logoColorStyle,
            String treeTitle,
            String treeImageFormat,
            String treeFilename
    ) {
        this.profileFile = profileFile;
        this.codonBiasFile = biasFile;
        this.uniquePeptides = uniquePeptides;
        this.fuzzFactor = fuzzFactor;
        this.outputPath = outputPath;
        this.logoStartIndex = logoStartIndex;
        this.logoHeight = logoHeight;
        this.logoTrimPercentage = logoTrimPercentage;
        this.logoImageFormat = logoImageFormat;
        this.logoColorStyle = logoColorStyle;
        this.treeTitle = treeTitle;
        this.treeImageFormat = treeImageFormat;
        this.treeFilename = treeFilename;
    }

    /**
     * Create a new parameter set with ONLY SEQUENCE LOGO PARAMETERS provided
     * @param profileFile
     */
    public LolaParameterSet(
            File profileFile,
            File biasFile,
            boolean uniquePeptides,
            double fuzzFactor,
            File outputPath,
            int logoStartIndex,
            int logoHeight,
            double logoTrimPercentage,
            String logoImageFormat,
            String logoColorStyle
    ) {
        this.profileFile = profileFile;
        this.codonBiasFile = biasFile;
        this.uniquePeptides = uniquePeptides;
        this.fuzzFactor = fuzzFactor;
        this.outputPath = outputPath;
        this.logoStartIndex = logoStartIndex;
        this.logoHeight = logoHeight;
        this.logoTrimPercentage = logoTrimPercentage;
        this.logoImageFormat = logoImageFormat;
        this.logoColorStyle = logoColorStyle;
    }

    /**
     * Copies a parameter set object
     * @return A copy of the parameter set
     */
    public LolaParameterSet copy() {
        LolaParameterSet newParamSet = new LolaParameterSet(
                this.getProfileFile(),
                this.getCodonBiasFile(),
                this.getUniquePeptides(),
                this.getFuzzFactor(),
                this.getOutputPath(),
                this.getLogoStartIndex(),
                this.getLogoHeight(),
                this.getLogoTrimPercentage(),
                this.getLogoImageFileFormat(),
                this.getLogoColorStyle(),
                this.getTreeTitle(),
                this.getTreeImageFormat(),
                this.getTreeFilename()
        );
        
        return newParamSet;
    }

    /* Paramter setters and getters */

    /**
     * @return The File object for the Profile file
     */
    public File getProfileFile() {
        return profileFile;
    }

    /**
     * Sets the Profile file name. This can be a single peptide file or a project file
     * that links to one ore more peptide files.
     *  
     * @param file A File object for the Profile file to be processed
     */
    public void setProfileFile(File file) {
        this.profileFile = file;
    }

    /**
     * Returns the user-provided codon bias specification file.
     * @return A File object for the codon bias file.
     */
    public File getCodonBiasFile() {
        return codonBiasFile;
    }

    /**
     * Sets the user-provided codon bias specification file.
     * @param file A File object for the codon bias file.
     */
    public void setCodonBiasFile(File file) {
        this.codonBiasFile = file;
    }

    /**
     * Gets the user-selected value of the unique peptides flag; true iff only unique peptides should be loaded
     * from the profile.
     * @return True iff only unique peptides should be loaded from the profile; false otherwise.
     */
    public boolean getUniquePeptides() {
        return uniquePeptides;
    }

    /**
     * Sets the flag that determines whether only unique peptides should be loaded from the profile.
     * @param value The value of the flag.
     */
    public void setUniquePeptides(boolean value) {
        this.uniquePeptides = value;
    }

    /**
     * Gets the user-selected fuzz factor value for protein profiles.
     * @return fuzz factor value
     */
    public double getFuzzFactor() {
        return fuzzFactor;
    }

    /**
     * Sets the protein profile fuzz factor.
     * @param value fuzz factor
     */
    public void setFuzzFactor(double value) {
        this.fuzzFactor = value;
    }

    /**
     * Returns the output directory path in which to save results.
     * @return File object holding the output path
     */
    public File getOutputPath() {
        return outputPath;
    }

    /**
     * Sets the output directory path in which to save results.
     * @param path File object holding the output path
     */
    public void setOutputPath(File path) {
        this.outputPath = path;
    }

    /**
     * Returns the starting number on the logo graph X-axis.
     * @return Integer value for the logo start index
     */
    public int getLogoStartIndex() {
        return logoStartIndex;
    }

    /**
     * Sets the starting number on the logo graph X-axis.
     * @param index Integar value for the logo start index
     */
    public void setLogoStartIndex(int index) {
        this.logoStartIndex = index;
    }

    /**
     * Returns the height, in pixels, of the logo image.
     * @return Integer value for the logo height
     */
    public int getLogoHeight() {
        return logoHeight;
    }

    /**
     * Sets the height, in pixels, of the logo image.
     * @param height Integer value for the logo height
     */
    public void setLogoHeight(int height) {
        this.logoHeight = height;
    }

    /**
     * Returns the height threshold (in % of maximum column height) of columns on either side of profile.
     * Any columns exceeding this threshold are trimmed to the specified percentage.
     * The setting has the effect of highlighting the most informative contiguous region.
     * @return Double value for the logo trim percentage
     */
    public double getLogoTrimPercentage() {
        return logoTrimPercentage;
    }

    /**
     * Sets the height threshold (in % of maximum column height) of columns on either side of profile.
     * Any columns exceeding this threshold are trimmed to the specified percentage.
     * The setting has the effect of highlighting the most informative contiguous region.
     * @param percentage A <b>double</b> value, between 0 and 1, for the logo trim percentage.
     */
    public void setLogoTrimPercentage(double percentage) {
        this.logoTrimPercentage = percentage;
    }

    /**
     * Returns the logo image file format as an ImageFormat enumeration value.
     * @return A String value representing the image format
     */
    public String getLogoImageFileFormat() {
        return logoImageFormat;
    }

    /**
     * Sets the logo image file format as an ImageFormat enumeration value.
     * @param imageFormat An ImageFormat value
     */
    public void setLogoImageFormat(String imageFormat) {
        this.logoImageFormat = imageFormat;
    }

    /**
     * Returns the logo color style.
     * @return A String value representing the color style
     */
    public String getLogoColorStyle() {
        return logoColorStyle;
    }

    /**
     * Sets the logo color style.
     * @param colorStyle An color style value
     */
    public void setLogoColorStyle(String colorStyle) {
        this.logoColorStyle = colorStyle;
    }

    /**
     * Returns the title of the logo tree.
     * @return String
     */
    public String getTreeTitle() {
        return this.treeTitle;
    }

    /**
     * Sets the title of the logo tree.
     * @param treeTitle String
     */
    public void setTreeTitle(String treeTitle) {
        this.treeTitle = treeTitle;
    }

    /**
     * Returns the image format of the logo tree as an ImageFormat enumeration value.
     * @return ImageFormat
     */
    public String getTreeImageFormat() {
        return this.treeImageFormat;
    }

    /**
     * Sets the image format of the logo tree.
     * @param treeImageFormat An ImageFormat enumeration value.
     */
    public void setTreeImageFormat(String treeImageFormat) {
        this.treeImageFormat = treeImageFormat;
    }

    /**
     * Returns the filename of the logo tree. Only returns the name of the file, without the filesystem path.
     * @return String
     */
    public String getTreeFilename() {
        return this.treeFilename;
    }

    /**
     * Sets the filename of the logo tree. THIS VALUE SHOULD NOT INCLUDE THE RELATIVE/ABSOLUTE PATH,
     * ONLY THE NAME OF THE FILE is required.
     * @param treeFilename String
     */
    public void setTreeFilename(String treeFilename) {
        this.treeFilename = treeFilename;
    }

    /**
     * Returns a string representation of the current parameter set.
     * 
     * @return A String that lists the names and values of the parameters.
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        String lineSep = System.getProperty("line.separator");
        sb.append("Profile File: " + profileFile.toString() + lineSep);
        
        return sb.toString();
    }

}
