/*
 * TransSeg.cc
 *
 * Copyright (C) 2012 Björn Voß

 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

 * Authors: Thorsten Bischler and Björn Voß
 *
 */

#include <iostream>
#include <cstdlib>
#include "Segmentation.h"
#include "DataStorage.h"
#include <boost/program_options.hpp>

namespace po = boost::program_options;

using namespace std;

unsigned threads = 1;

int main (int argc, char **argv) {
	int kmax;
	int cpmax;
    int zmax;
    int zfrac;
	int prim_window;
	double read_cutoff;
	double read_cutoff2;
	double pvalue_cutoff;
	double mean_cov_cutoff;
    double non_transcript_cov_cutoff;
	int start_pos, end_pos;
	char strand;
	string grp_file;
	int output_format;
	string gff_file, score_file;
	int kmin;
    bool verbose;
    double ratio;


	po::options_description desc("Allowed options");
	desc.add_options()
	    ("help,h", "produce help message")
	    ("threads,t", po::value<unsigned>(&threads)->default_value(1), "Set number of threads for the calculation")
	    ("kmax,k", po::value<int>(&kmax)->default_value(10000), "Set maximum segment length")
        ("kmin,m", po::value<int>(&kmin)->default_value(0), "Set minimum segment length")
	    ("cpmax,c", po::value<int>(&cpmax)->default_value(1000), "Set maximum number of change points")
	    ("prim_window,w)", po::value<int>(&prim_window)->default_value(0), "Set window for the maximum primary start distance")
	    ("read_cutoff,r", po::value<double>(&read_cutoff)->default_value(-1.0), "Specify primary read cutoff for transcript segments with tata-box p-value >= pvalue_cutoff")
	    ("read_cutoff2,R", po::value<double>(&read_cutoff2)->default_value(0), "Specify primary read cutoff for transcript segments without need for tata-box")
	    ("pvalue_cutoff,p", po::value<double>(&pvalue_cutoff)->default_value(1.0), "Specify pvalue_cutoff for transcript segments")
	    ("mean_cov_cutoff,a",po::value<double>(&mean_cov_cutoff)->default_value(0.0), "Specify mean secondary read coverage cutoff for transcript segments")
        ("non_transcript_cov_cutoff,u",po::value<double>(&non_transcript_cov_cutoff)->default_value(numeric_limits<double>::max()), "Specify maximum mean secondary coverage cutoff for NON-transcript segments")
	    ("start_pos,s", po::value<int>(&start_pos)->default_value(1), "Set start position in the genome")
	    ("end_pos,e", po::value<int>(&end_pos)->default_value(0), "Set end position in the genome")
	    ("strand", po::value<char>(&strand)->default_value('+'), "Set strand to forward(+) or reverse(-)")
	    ("grp_file,f", po::value<string>(&grp_file)->default_value(""), "Specify input file")
	    //("output_format,o", po::value<int>(&output_format)->default_value(0), "Specify output format: segmentations for every number of change points with score file (0), merged output file (1)")
	    ("gff_file", po::value<string>(&gff_file)->default_value(""), "Specify gff output file")
	    ("score_file", po::value<string>(&score_file)->default_value(""), "Specify score output file")
        ("verbose,v", po::value<bool>(&verbose)->default_value(false),"Activate verbose output")
        ("ratio,l", po::value<double>(&ratio)->default_value(0.0),"Minimum ratio between primary starts and primary coverage")
        ("zero_stretch,z",po::value<int>(&zmax)->default_value(numeric_limits<int>::max()), "Set maximum length of a stretch of zeros within a transcript segment")
        ("Zero_frac,Z",po::value<int>(&zfrac)->default_value(100), "Set maximum fraction of zeros within a transcript segment")
		 ;

	po::positional_options_description p;
	po::variables_map vm;

	try{
		po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
		po::notify(vm);
	}
	catch ( const boost::program_options::error& e ) {
	        std::cerr << e.what() << std::endl;
    }

	if (vm.count("help")) {
		std::cout << "Usage: options_description [options]\n";
	    std::cout << desc;
	    return 0;
	}

    if (read_cutoff == -1.0) {
        read_cutoff = read_cutoff2;
    }
    
	DataStorage data(strand, grp_file, start_pos, end_pos);
	cout << "Starting segmentation..." << endl;
	Segmentation s(data, kmax, cpmax, prim_window, read_cutoff, read_cutoff2, pvalue_cutoff, mean_cov_cutoff, gff_file, score_file, kmin,verbose,ratio,non_transcript_cov_cutoff,zmax,zfrac);

	s.computeSegments();

	return 0;
}
