/* 
   Oligonucleotide Sequence Generator <super@innu.org>
*/
   
#include<stdio.h>
#include<stdlib.h>

void usage(char*argv[])
{
	printf("usage: %s <file>\n",*argv);

	exit(EXIT_FAILURE);
}

void vexit(const char*f)
{
	perror(f);
	
	exit(EXIT_SUCCESS);
}

int main(int argc,char*argv[])
{
	char*_B="Tcg",*_D="ATg",*_H="ATc",*_K="Tg",*_M="Ac",*_N="AcTg";
	char*_R="Ag",*_S="cg",*_V="Acg",*_W="AT",*_Y="cT";
	char buf[BUFSIZ];
	char**mixes=NULL,**vals=NULL;
	FILE*fp=NULL;
	int cnt_save=0;

	if(argc<2)
		usage(argv);	

	fp=fopen(argv[1],"r");

	if(!fp)
		vexit("fopen");

	while(fgets(buf,sizeof buf,fp))
	{
		register char*p=buf,**pp,**pp2;
		
		int cnt=0;
		
		while(*p)
			switch(*p++)
			{
				case 'B':
				case 'D':
				case 'H':
				case 'K':
				case 'M':
				case 'N':
				case 'R':
				case 'S':
				case 'V':
				case 'W':
				case 'Y':
					cnt++;
			}

		if(cnt>cnt_save)
		{
			mixes=malloc(cnt*sizeof*mixes);
			if(!mixes)
				vexit("malloc");

			vals=malloc(cnt*sizeof*mixes);
			if(!vals)
				vexit("malloc");
		}

		for(pp=mixes,pp2=vals,p=buf;*p;p++)
			switch(*p)
			{
				case 'B':
					*pp++=_B;
					*pp2++=_B;
					break;
				case 'D':
					*pp++=_D;
					*pp2++=_D;
					break;
				case 'H':
					*pp++=_H;
					*pp2++=_H;
					break;
				case 'K':
					*pp++=_K;
					*pp2++=_K;
					break;
				case 'M':
					*pp++=_M;
					*pp2++=_M;
					break;
				case 'N':
					*pp++=_N;
					*pp2++=_N;
					break;
				case 'R':
					*pp++=_R;
					*pp2++=_R;
					break;
				case 'S':
					*pp++=_S;
					*pp2++=_S;
					break;
				case 'V':
					*pp++=_V;
					*pp2++=_V;
					break;
				case 'W':
					*pp++=_W;
					*pp2++=_W;
					break;
				case 'Y':
					*pp++=_Y;
					*pp2++=_Y;
					break;
			}

			*pp=NULL;
	
			for(;*vals[cnt-1];++vals[0])
        		{
				register int j=0;

                		if(!*vals[0])
                		{
                        		j=0;

                        		do
                        		{
                                		vals[j]=mixes[j];
                                		j++;
                                		++vals[j];
                        		} while(j<cnt-1&&!*vals[j]);
                        	
					if(j==cnt-1&&!*vals[cnt-1])
                                		break;
				}
	
				for(j=0,p=buf;*p;p++)
					switch(*p)
					{
						case 'B':
						case 'D':
						case 'H':
						case 'K':
						case 'M':
						case 'N':
						case 'R':
						case 'S':
						case 'V':
						case 'W':
						case 'Y':
							putchar(*vals[j++]);
							break;
						default:
							putchar(*p);
					}
			}
        }

	exit(EXIT_SUCCESS);
}
