//	This source and Permutation Groups method apply to GNU General Public License. 
//			Copyright (C) 2001-2013 Jasenko Dzinleski 

//		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 (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, write to the Free Software Foundation, Inc.,
//	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

//  Permutation Groups 
//	written by Dzinleski Jasenko  November 2013


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

FILE	*f1;

char	infn[256]="fasta_.txt";
int	na[256][256][256][2];	int	nai=0;
int	va[10000][2][50];	int 	vai=0;
int	ga[300000][2][5+3];	int	gai=0;
int	sa[5+1][2];			

int main(int argc,char *argv[])
{

int	a,b,c,d,e;
int	i,j,k,l,m;
int	lc;
int	b1_,b2_,b3_,b4_;

char	nl[256];int nli=0;
int	fbyte;

	if(argv[1]==NULL){return(0);}else{
		strcpy(infn,argv[1]);f1=fopen(infn,"rb");
		if(f1==NULL){return(0);}else{fclose(f1);}
	}

	for(i=0;i<256;++i){for(j=0;j<256;++j){for(k=0;k<256;++k){na[i][j][k][0]=-1;}}}nai=0;
	for(i=0;i<10000;++i){va[i][0][0]=0;for(j=0;j<50;++j){va[i][1][j]=0;}}vai=0;

	f1=fopen(infn,"rb");	

	b1_=getc(f1);
	b2_=getc(f1);
	b3_=getc(f1);

	while(!feof(f1))
	{
		if(na[b1_][b2_][b3_][0]==-1)
		{
			na[b1_][b2_][b3_][0]=nai;
			b4_=getc(f1);while(b4_==10||b4_==13){b4_=getc(f1);}
			if(vai==0)
			{
				va[vai][0][0]=nai;
				va[vai][1][0]=1;
				va[vai][0][va[vai][1][0]]=b4_;
				va[vai][1][va[vai][1][0]]=1;
				++vai;
			}else{
				for(i=0;i<vai;++i)
				{
					if(va[i][0][0]==nai)
					{
						for(j=1;j<=va[i][1][0];++j){if(va[i][0][j]==b4_){++va[i][1][j];break;}}
						if(j==1+va[i][1][0])
						{
						++va[i][1][0];
						va[i][0][va[i][1][0]]=b4_;
						va[i][1][va[i][1][0]]=1;
						}
						break;
					}
				}
				if(i==vai)
				{
				va[vai][0][0]=nai;
				va[vai][1][0]=1;
				va[vai][0][va[vai][1][0]]=b4_;
				va[vai][1][va[vai][1][0]]=1;
				++vai;
				}
			}
			++nai;
			na[b1_][b2_][b3_][1]=1;

		}else{
			++na[b1_][b2_][b3_][1];

			k=na[b1_][b2_][b3_][0];
			b4_=getc(f1);while(b4_==10||b4_==13){b4_=getc(f1);}
			if(vai==0)
			{
				va[vai][0][0]=nai;
				va[vai][1][0]=1;
				va[vai][0][va[vai][1][0]]=b4_;
				va[vai][1][va[vai][1][0]]=1;
				++vai;
			}else{
				for(i=0;i<vai;++i)
				{
					if(va[i][0][0]==k)
					{
						for(j=1;j<=va[i][1][0];++j){if(va[i][0][j]==b4_){++va[i][1][j];break;}}
						if(j==1+va[i][1][0])
						{
						++va[i][1][0];
						va[i][0][va[i][1][0]]=b4_;
						va[i][1][va[i][1][0]]=1;
						}
						break;
					}
				}
				if(i==vai)
				{
				va[vai][0][0]=k;
				va[vai][1][0]=1;
				va[vai][0][va[vai][1][0]]=b4_;
				va[vai][1][va[vai][1][0]]=1;
				++vai;
				}
			}
		}

		b1_=b2_;
		b2_=b3_;
		b3_=b4_;
	
	}
	fclose(f1);

	for(i=0;i<256;++i){for(j=0;j<256;++j){for(k=0;k<256;++k){
		if(na[i][j][k][0]!=-1)
		{
			printf("%c%c%c\t%d\t",i,j,k,na[i][j][k][0]);
			for(l=0;l<vai;++l)
			{
				if(na[i][j][k][0]==va[l][0][0])
				{
					for(m=1;m<=va[l][1][0];++m)
					{
					//printf("%c.%d.",va[l][0][m],va[l][1][m]);
					printf("%c",va[l][0][m]);
					}printf("\n");
					break;
				}
			}
		}
	}}}

	f1=fopen(infn,"rb");
	fbyte=getc(f1);
	while((fbyte!=10)&&(fbyte!=13)){fbyte=getc(f1);}
	if(nli==0){while((fbyte==10)||(fbyte==13)){nl[nli]=fbyte;++nli;fbyte=getc(f1);}}
	fclose(f1);

	f1=fopen(infn,"rb");
	a=0;lc=1;
	while(!feof(f1))
	{
		
		b=0;
		while(b<5)
		{
			c=0;
			while(c<4)
			{
			fbyte=getc(f1);if(feof(f1)){break;}
			if(nl[a]==fbyte){++a;continue;}
			if(!(a<nli)){/*printf("%d\n",lc);*/++lc;a=0;}
			if(c==0){b1_=fbyte;}
			if(c==1){b2_=fbyte;}
			if(c==2){b3_=fbyte;}
			if(c==3){b4_=fbyte;}
			++c;
			}

			if(na[b1_][b2_][b3_][0]!=-1)
			{
				sa[b][0]=na[b1_][b2_][b3_][0];
				for(l=0;l<vai;++l)
				{
					if(na[b1_][b2_][b3_][0]==va[l][0][0])
					{
						for(m=1;m<=va[l][1][0];++m){if(va[l][0][m]==b4_){break;}}
						if(m==1+va[l][1][0]){printf("1.%c.Error...\n",b4_);/*return(0);*/}else{break;}
					}
				}
				sa[b][1]=va[l][1][m];

			}else{printf("2.%c%c%c.Error...\n",b1_,b2_,b3_);/*return(0);*/}

			++b;
		}
		if(gai==0)
		{
			ga[gai][0][0]=sa[0][0];
			ga[gai][0][1]=sa[1][0];
			ga[gai][0][2]=sa[2][0];
			ga[gai][0][3]=sa[3][0];
			ga[gai][0][4]=sa[4][0];

			ga[gai][1][0]=sa[0][1];
			ga[gai][1][1]=sa[1][1];
			ga[gai][1][2]=sa[2][1];
			ga[gai][1][3]=sa[3][1];
			ga[gai][1][4]=sa[4][1];

			ga[gai][0][5]=1;

			++gai;
		}else{
			for(i=0;i<gai;++i)
			{
				c=0;
				if(ga[i][0][0]==sa[0][0]){++c;}
				if(ga[i][0][1]==sa[1][0]){++c;}
				if(ga[i][0][2]==sa[2][0]){++c;}
				if(ga[i][0][3]==sa[3][0]){++c;}
				if(ga[i][0][4]==sa[4][0]){++c;}
			
				if(c>=2){++ga[i][0][5];}

				if(c==5){break;}

			}
			if(i==gai)
			{
			ga[gai][0][0]=sa[0][0];
			ga[gai][0][1]=sa[1][0];
			ga[gai][0][2]=sa[2][0];
			ga[gai][0][3]=sa[3][0];
			ga[gai][0][4]=sa[4][0];

			ga[gai][1][0]=sa[0][1];
			ga[gai][1][1]=sa[1][1];
			ga[gai][1][2]=sa[2][1];
			ga[gai][1][3]=sa[3][1];
			ga[gai][1][4]=sa[4][1];

			ga[gai][0][5]=1;

			++gai;
			}
		}

	}
	fclose(f1);

	for(i=0;i<gai;++i)
	{
		printf("%d\t%d\t%d\t%d\t%d\t%d\n",
		ga[i][0][0],
		ga[i][0][1],
		ga[i][0][2],
		ga[i][0][3],
		ga[i][0][4],
		ga[i][0][5]
		);
	}

	return(0);

}