#include "AfgBasWriter.hpp"

unsigned char AfgBasWriter::pacbioQVtoPhredQV(unsigned char pacbio){
    return (unsigned char) floor( 10.0 * log10( 1.0 + pow(10.0, pacbio / 100.0) ) + 0.5 );
}

AfgBasWriter::AfgBasWriter() {
    firstRecord = true;
    recordCount = 1;
    defaultQuality = 5;
}

AfgBasWriter::~AfgBasWriter() {
    firstRecord = true;
    recordCount = 1;
    defaultQuality = 5;
}

void AfgBasWriter::Initialize(std::string _afgFileName){
    afgFileName = _afgFileName;
    CrucialOpen(afgFileName, afgOut);
}

void AfgBasWriter::Close() {
    afgOut.close();
}

void AfgBasWriter::SetDefaultQuality(int _defaultQuality){
    defaultQuality = _defaultQuality;
}

int AfgBasWriter::Write(SMRTSequence &seq) {
    if (firstRecord){
        WriteHeader();
        firstRecord = false;
    }
    WriteOpen(seq);
    WriteIdentifier(seq);
    WriteBases(seq);
    WriteQualities(seq);
    WriteClose();
    return 1;
}

void AfgBasWriter::WriteHeader() {
    afgOut << "{UNV" << std::endl;
    afgOut << "iid:1" << std::endl;
    afgOut << "com:" << std::endl;
    afgOut << "generated by AfgBasWriter" << std::endl;
    afgOut << "Mon Jun 28 14:43:52 2010" << std::endl; // TODO put in real date
    afgOut << "." << std::endl << "}" << std::endl;
    afgOut << "{LIB" << std::endl << "iid:1" << std::endl;
    afgOut << "{DST" << std::endl << "mea:0" << std::endl << "std:0" << std::endl << "}" << std::endl << "}" << std::endl;
}

void AfgBasWriter::WriteOpen(SMRTSequence &seq) {
    afgOut << "{RED" << std::endl;
    afgOut << "frg:" << recordCount + 1 << std::endl;
    afgOut << "iid:" << recordCount << std::endl;
}

void AfgBasWriter::WriteIdentifier(SMRTSequence &seq) {
    afgOut << "clr:0," << seq.length << std::endl;

    afgOut << "eid:";
    std::string fastaTitle;
    seq.GetFASTATitle(fastaTitle);
    afgOut << fastaTitle << std::endl;
}

void AfgBasWriter::WriteClose() {
    recordCount++;
    afgOut << "}" << std::endl;
    afgOut << "{FRG" << std::endl;
    afgOut << "iid:" << recordCount << std::endl;
    afgOut << "lib:1" << std::endl << "typ:I" << std::endl << "}" << std::endl;
    recordCount++;
}

void AfgBasWriter::WriteBases(SMRTSequence &seq) {
    afgOut << "seq:" << std::endl;
    (static_cast<DNASequence*>(&seq))->PrintSeq( afgOut, lineLength );
    afgOut << "." << std::endl;
}

void AfgBasWriter::WriteQualities(SMRTSequence &seq) {
    afgOut << "qlt:" << std::endl;
    int i;
    for (i = 0; i < seq.length; i++ ){
        unsigned char quality =  seq.qual.data ?  seq.qual[i] : defaultQuality;
        quality = quality + charToQuality;
        quality = quality > maxAfgQuality ? maxAfgQuality : quality;
        quality = quality < minAfgQuality ? minAfgQuality : quality;
        afgOut << quality;
        if (i > 0 and (i+1) % lineLength == 0)
            afgOut << std::endl;
    }
    if (i == 0 or i % lineLength != 0) {
        afgOut << std::endl;
    }
    afgOut << "." << std::endl;
}
