/*******************************************************
                        PFTOOLS
 *******************************************************
  Jan 18, 2011 output.c
 *******************************************************
 (C) 2011 Swiss Institute of Bioinformatics
     Thierry Schuepbach (thierry.schuepbach@isb-sib.ch)
 *******************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "profile.h"

void PrintSimple(const struct Profile * const prf, const char * * const AlignedSequence,
		 const struct Alignment * const alignment, char * const Header,
		 const size_t SequenceLength, const float RAVE, const int N)
{
  char * cptr = Header;
  while ( *cptr != ' ' && *cptr != '\0') ++cptr;
  *cptr = '\0';
  for (int i=0; i<N; ++i) {   
    const float normtest = (RawToNormalizedFunction == 0) ? 0.0f : RawToNormalizedFunction(alignment[i].JALS, SequenceLength, RAVE);   
    fprintf(stdout, "%s %i %f\n%s\n",
	    Header,
	    alignment[i].JALS,
	    normtest,
	    AlignedSequence[i]);
  }
}

// profile_ac start strop raw_score aln_string
void PrintTSV(const struct Profile * const prf, const char * * const AlignedSequence,
		 const struct Alignment * const alignment, char * const Header,
		 const size_t SequenceLength, const float RAVE, const int N)
{
    char * id;
    char * cptr = Header;
    
    while ( *cptr != ' ' && *cptr != '\0') ++cptr;
    *cptr = '\0';
    id = Header; id++;
    
    char * ac  = calloc(strlen(prf->AC_Number),sizeof(char));
    strcpy(ac,prf->AC_Number);
    cptr = ac;
    while ( *cptr != ';' && *cptr != '\0' ) ++cptr;
    *cptr = '\0';

    for (int i=0; i<N; ++i) {   
        const float normtest = (RawToNormalizedFunction == 0) 
                             ? 0.0f 
                             : RawToNormalizedFunction(alignment[i].JALS, SequenceLength, RAVE);   
        
        fprintf(stdout, "%s\t%s\t%i\t%i\t%i\t%f\t%s\n",
                ac,
                id,
                alignment[i].JALB,
                alignment[i].JALE,
                alignment[i].JALS,
                normtest,
                AlignedSequence[i]);
    }
    free(ac);
}

void PrintDefault(const struct Profile * const prf, const char * * const AlignedSequence,
        const struct Alignment * const alignment, char * const Header,
        const size_t SequenceLength, const float RAVE, const int N)
{
    char * id;
    char * des;
    char * cptr = Header;
    
    // Extract ID (id), short ID (cptr) and description (des)
    while ( *cptr != ' ' && *cptr != '\0') ++cptr;
    *cptr = '\0';
    des = ++cptr;
    while ( *cptr != '|' && *cptr != '>' ) --cptr;
    ++cptr; 
    id = Header;
    ++id;
    
    for (unsigned int i=0; i<N; ++i) {   
        const float normtest = (RawToNormalizedFunction == 0) ? 0.0f : RawToNormalizedFunction(alignment[i].JALS, SequenceLength, RAVE);   
        fprintf(stdout, "%7.3f %7i pos. %7i - %7i %s %s\n",
                normtest,
                alignment[i].JALS,
                alignment[i].JALB,
                alignment[i].JALE,
                id,
                des
               );
    }
}

void PrintInterpro(const struct Profile * const prf, const char * * const AlignedSequence,
        const struct Alignment * const alignment, char * const Header,
        const size_t SequenceLength, const float RAVE, const int N)
{
    char * id;
    char * des;
    char * buffer = calloc(OutputPrintWidth+1,sizeof(char));
    char * cptr = Header;
    
    // Extract ID (id), short ID (cptr) and description (des)
    while ( *cptr != ' ' && *cptr != '\0') ++cptr;
    *cptr = '\0';
    des = ++cptr;
    while ( *cptr != '|' && *cptr != '>' ) --cptr;
    ++cptr; 
    id = Header;
    ++id;

    for (unsigned int i=0; i<N; ++i) {   
        const float normtest = (RawToNormalizedFunction == 0) ? 0.0f : RawToNormalizedFunction(alignment[i].JALS, SequenceLength, RAVE);   
        if (N > 1)
        {
            fprintf(stdout, ">%s_%i L=%i %8.3f %6i pos. %8i -%8i [%5i, %5i] %s %s\n",
                cptr,
                i+1,
                SearchLevel,
                normtest,
                alignment[i].JALS,
                alignment[i].JALB,
                alignment[i].JALE,
                alignment[i].IPMB,
                alignment[i].IPME,
                id,
                des 
               );
        }
        else
        {
            fprintf(stdout, ">%s L=%i %8.3f %6i pos. %8i -%8i [%5i, %5i] %s %s\n",
                cptr,
                SearchLevel,
                normtest,
                alignment[i].JALS,
                alignment[i].JALB,
                alignment[i].JALE,
                alignment[i].IPMB,
                alignment[i].IPME,
                id,
                des 
               );
        }

        *buffer = '\0';
        unsigned int offset = 0;
        unsigned int len    = strlen(AlignedSequence[i]);

        while (offset <= len)
        {
            strncpy(buffer,AlignedSequence[i]+offset,OutputPrintWidth);
            if ( '\0' != *buffer )
            {
                fputs(buffer,stdout);
                fputc('\n',stdout);
            }
            offset += OutputPrintWidth;
        }
    }
    free(buffer);
}

void PrintPfscan(const struct Profile * const prf, const char * * const AlignedSequence,
        const struct Alignment * const alignment, char * const Header,
        const size_t SequenceLength, const float RAVE, const int N)
{
    char * buffer = calloc(OutputPrintWidth+1,sizeof(char));
    char * cptr;
    
    // Extract ID (id)
    char * id = calloc(strlen(prf->AC_Number),sizeof(char));
    strcpy(id,prf->Identification);
    cptr = id;
    while ( *cptr != ';' && *cptr != '\0') ++cptr;
    *cptr = '\0';
    
    char * ac  = calloc(strlen(prf->AC_Number),sizeof(char));
    strcpy(ac,prf->AC_Number);
    cptr = ac;
    while ( *cptr != ';' && *cptr != '\0' ) ++cptr;
    *cptr = '\0';
        
    char * des  = prf->Description;

    for (unsigned int i=0; i<N; ++i) {   
        const float normtest = (RawToNormalizedFunction == 0) 
                             ? 0.0f 
                             : RawToNormalizedFunction(alignment[i].JALS, SequenceLength, RAVE);   
        if (N > 1)
        {
            fprintf(stdout, ">%s_%i L=%i %8.3f %6i pos. %8i -%8i [%5i, %5i] %s|%s\n",
                id,    
                i+1,
                SearchLevel,
                normtest,
                alignment[i].JALS,
                alignment[i].JALB,
                alignment[i].JALE,
                alignment[i].IPMB,
                alignment[i].IPME,
                ac,
                des 
               );
        }
        else
        {
            fprintf(stdout, ">%s L=%i %8.3f %6i pos. %8i -%8i [%5i, %5i] %s|%s\n",
                id,
                SearchLevel,
                normtest,
                alignment[i].JALS,
                alignment[i].JALB,
                alignment[i].JALE,
                alignment[i].IPMB,
                alignment[i].IPME,
                ac,
                des 
               );
        }

        *buffer = '\0';
        unsigned int offset = 0;
        unsigned int len    = strlen(AlignedSequence[i]);

        while (offset <= len)
        {
            strncpy(buffer,AlignedSequence[i]+offset,OutputPrintWidth);
            if ( '\0' != *buffer )
            {
                fputs(buffer,stdout);
                fputc('\n',stdout);
            }
            offset += OutputPrintWidth;
        }
    }
    free(buffer);
    free(id);
    free(ac);
}
