/*
Copyright (c) 2006-2018 Elmar Pruesse <elmar.pruesse@ucdenver.edu>

This file is part of SINA.
SINA 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 3 of the License, or (at your
option) any later version.

SINA 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 SINA.  If not, see <http://www.gnu.org/licenses/>.

Additional permission under GNU GPL version 3 section 7

If you modify SINA, or any covered work, by linking or combining it
with components of ARB (or a modified version of that software),
containing parts covered by the terms of the
ARB-public-library-license, the licensors of SINA grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code
for the parts of ARB used as well as that of the covered work.
*/

#include "pseq.h"

#include <string>

namespace sina {
std::ostream&
operator<<(std::ostream& out, const aligned_base_profile& ab)
{
    std::stringstream tmp;
    tmp <<  ab.getBase().getString() << "(" << ab.getPosition() << ")";
    return out << tmp.str();
}
} // namespace sina

using namespace sina;
pseq::pseq(std::vector<const cseq*>::iterator seqs_it,
           std::vector<const cseq*>::iterator seqs_end)
    : width(0)
{
    if (seqs_it != seqs_end) {
        width = (*seqs_it)->getWidth();
    }
    int height = 0;

    std::vector<cseq::const_iterator> base_iterators, base_ends;
    for (; seqs_it != seqs_end; ++seqs_it) {
        base_iterators.push_back((*seqs_it)->begin());
        base_ends.push_back((*seqs_it)->end());
        ++height;
    }

    bool gap[height];
    for (int i=0; i<height; ++i) {
        gap[i] = true;
    }

    using idx_type = aligned_base::idx_type;

    idx_type current_column = 0;
    while (current_column < width) {
        idx_type next_column = width;
        int A=0, G=0, C=0, T=0;
        int gapOpen=0, gapExtend=0;
        for (int row = 0; row < height; ++row) {
            cseq::const_iterator it = base_iterators[row];
            if (it != base_ends[row] &&
                it->getPosition() == current_column) {
                if (it->ambig_order() > 0) {
                    int points = 12 / it->ambig_order();
                    if (it->has_A()) {
                        A += points;
                    }
                    if (it->has_G()) {
                        G += points;
                    }
                    if (it->has_C()) {
                        C += points;
                    }
                    if (it->has_TU()) {
                        T += points;
                    }
                    gap[row] = false;
                }
                ++base_iterators[row];
            } else {
                if (gap[row]) {
                    ++gapExtend;
                } else {
                    gap[row] = true;
                    ++gapOpen;
                }
            }

            if (base_iterators[row] != base_ends[row]) {
                next_column = std::min(
                    next_column,
                    base_iterators[row]->getPosition()
                    );
            }
        }

        base_profile bp(A, G, C, T, gapOpen*12, gapExtend*12);
        profile.emplace_back(current_column, bp);

        current_column = next_column;
    }
}

void
pseq::print_graphviz(std::ostream& out, const std::string& /*name*/) {
    for (iterator it = begin(); it != end(); ++it) {
        out << it->getBase().getString() << std::endl;
    }
}

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :

