#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>

/*構造体YJの定義*/
typedef struct yj
{
        int num;
	int l;//参照するときに使う添字
	int temp;
	int flag;
        char word[256];
        struct yj *next;
}YJ;


/*領域確保用の関数*/
YJ *newyj()
{
        YJ *p;
        p=(YJ *)malloc(sizeof(YJ));

        if(p==NULL)
        {
                fputs("malloc failedn\n",stderr);
                exit(1);
        }
        else
        {
                return p;
        }
}

//この構造体を配列にしてマージソートに使いたい
typedef struct list
{
        struct YJ *dom;//すでに上で定義した構造体型のポインタ
}LIST;


//ファイルの中身からリストを作るだけの関数
YJ *makelist(char filename[256])
{

        FILE *fp;
        fp=fopen(filename,"r");//ファイル開く
        if(fp==NULL)//エラー処理
        {
                printf("file open failed(%s)\n",filename);
        }

	int c,i=0;
	YJ *top,*now,*new;
	/*入力順にリスト作成開始*/
	new=newyj();
	now=new;
	top=now;

	while((c=fgetc(fp))!=EOF)
	{
		if(c!='\n')
		{
			if(c=='.')
			{
				(now->num)++;
			}
			now->word[i]=c;
			i++;
		}
                else if(c=='\n')
                {
		        now->word[i]='\0';
                        new=newyj();//新しい領域確保
                        now->next=new;//これにより、現在のnowの指す領域のnextは上で確保した領域となる
                        now=new;//次のループに向け、nowを上で確保した領域に再指定

                        /*---------------ここらへんは全部ループのための再設定-------------------*/
                        i=0;
                }

	}
        now->next=NULL;
        fclose(fp);
	return top;
}

//.を探してループに対応した文字列の開始場所を見つける関数
void find(YJ *top,int i)
{
	YJ *now;
	int temp;
	int l,j;
	now=top;
        while(now->next!=NULL)
	{
		temp=(now->num)-i;
		now->temp=temp;
		l=0;
		j=0;
		while(j<temp)
		{
			if(now->word[l]=='.')
			{
				j++;
			}
			l++;
		}	
		now->l=l;
		now=now->next;
	} 

}

//別のラベルの評価に移動するかを判断する関数
int end(YJ *top)
{
	YJ *now;
        now=top;    
	int aaa=10;
        while(now->next!=NULL)
        {
		//printf("flag%d\n",now->flag);
        	if((now->flag)==0)
        	{
        		aaa=20;
			break;
        	}
		now=now->next;
        }
	return aaa;
}

//ソート関数
void sortlist(YJ *top)
{

	YJ *now;
	YJ *pon;
        now=top;
        while(now->next!=NULL)
        {
                printf("%d,%s\n",now->num,now->word);
                now=now->next;
        }

	/*マージソート用のリストを作る*/	
	LIST marge[26];
	YJ *mow[26];//各ノード用の最後尾用のポインタの配列
	int iii;
	for(iii=0;iii<26;iii++)
	{
		marge[iii].dom=NULL;//初期化
	}

        /*ここで.ごとにドメインの中身を分割する*/
	int temp;
	int max=0;

	/*.の個数の特定*/
	now=top;
        while(now->next!=NULL)
	{
		if(max<(now->num))
		{
			max=now->num;
		}
		now=now->next;
	}
	printf("max:%d\n",max);
	
	now=top;

	int i;
	int l,s;
	int little,littlebefo;//マージソート配列につっこむための変数
	int endor;
	for(i=0;i<=max;i++)
	{
		s=0;
		find(top,i);//これで各ノードにこのループの中で、文字列のどの部分から参照するのか確定
		while(1)
		{
			sleep(1);
			now=top;
			while(now->next!=NULL)
			{
				l=(now->l)+s;//各ループでの添字
				/*終了のフラグ。構造体の中にあるフラグを上書きする*/
                             	if(((now->word[l])=='\0')||((now->word[l])=='.'))
                               	{
                               	        now->flag=1;
                                }
				/*ラベルの文字を評価する部分*/
				if((now->flag)==1)
				{
					little='@';
				}
				else if((now->temp)<0)//ラベルの絶対数で現在のラベルを使用するか、それとも入力なし(@)として使用するか
				{
					now->flag=1;
					little='@';
				}//大文字小文字判別
                                else if((65<=(now->word[l]))&&((now->word[l])<=90))
                                {
                                        little=(now->word[l])+32;
                                }
                                else if((97<=(now->word[l]))&&((now->word[l])<=122))
                                {
                                        little=now->word[l];
                                }//とりあえず上記以外の文字は全部@にしておく
				else
				{
					little='@';
				}
				printf("%c",little);

				/***************************************************************************************************************/		
				/*なんか怪しい部分*/
				
				//現在参照してる文字が@なら、順列の関係を崩さないように参照した文字が@でなくなるまで遡る機構を実現する部分
				//@の時はbeforeのもの置き換える
				if(little!='@')
				{
					little=littlebefo;
				}//そうでない時はmarge配列を使用するために、文字コードから97を引く
				else
				{
					little=little-97;
				}

				//marge配列から辿れるノードがNULLの時
				if(marge[little].dom==NULL)
				{
					mow[little]=now;
					now=now->next;
					marge[little].dom=mow[little];
					mow[little]->next=NULL;
				}
				else//既に辿れるノードがある場合
				{
					mow[little]->next=now;
					now=now->next;
					mow[little]=mow[little]->next;
					mow[little]->next=NULL;
				}
				
				//marge配列のノードをすべて連結
				top=marge[0].dom;
				now=top;
				int ii;
				for(ii=0;ii<26;ii++)
				{
					//各配列の最後尾まで辿る
					while(now->next!=NULL)
					{
						now=now->next;
					}

					if((ii<25)&&((marge[ii+1].dom)!=NULL))//次の配列が存在するとき
					{	
						now->next=marge[ii+1].dom;//次の文字の配列と連結
						now=now->next;
					}
					else if((marge[ii+1].dom)==NULL)//
					{
						//何もしない
					}
					else//存在しない場合、最後までたどればNULL
					{
						now->next=NULL;
					}
				}
                                /***************************************************************************************************************/               

				//now=now->next;//上を有効にするときはここを無効に
			}
			printf("\n");
			endor=end(top);
			if(endor==10)
			{
				break;
			}
			s++;
		}
                now=top;
                while(now->next!=NULL)
                {
                	(now->flag)=0;
                	now=now->next;
                }

	}

}


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

	YJ *top,*now;

	top=makelist(argv[1]);

        if(top==NULL)
        {
                return -1;
        }
	
	sortlist(top);

	return 0;
}
