#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>

#include <egb.h>
#include <guidbg.h>

#include "ysmacro.h"
#include "ysgui.h"
#include "ysmalloc.h"
#include "ysrename.h"

extern int Ys11Id;


static int CheckNumFiles(void);
static int CheckFileLen(void);
static int CheckFileExist(char *exFile);
static int CheckFileDescription(void);
static int FinalCheck(void);
static int RenameExec(void);

int renameExecFunc()
{
	char exFile[80];
	char *mes[3];

	if(CheckNumFiles()!=YSTRUE)
	{
		YsConfirm(Ys11Id,"まずファイルを選んでください.",NULL);
		return NOERR;
	}

	if(CheckFileLen()!=YSTRUE)
	{
		mes[0]="変更後ファイル名の文字数が長すぎます.";
		mes[1]="条件設定をやりなおしてください.      ";
		mes[2]=NULL;
		YsConfirm3(Ys11Id,mes,NULL);
		return NOERR;
	}

	if(CheckFileExist(exFile)!=YSTRUE)
	{
		mes[0]="次のファイルがかちあっています.";
		mes[1]=exFile;
		mes[2]="別の名前に変更するなどしてください.";
		YsConfirm3(Ys11Id,mes,NULL);
		return NOERR;
	}

	if(CheckFileDescription()!=YSTRUE)
	{
		mes[0]="ファイル数が,アルファベットの文字数で表現";
		mes[1]="できる個数または,指定の桁数の数字で表現で";
		mes[2]="きる個数を越えています.                  ";
		YsConfirm3(Ys11Id,mes,NULL);
		return NOERR;
	}

	if(FinalCheck()!=YSTRUE)
	{
		return NOERR;
	}

	RenameExec();

	return NOERR;
}

static int CheckNumFiles(void)
{
	int nf;
	FlNumFiles(&nf);
	if(nf<=0)
	{
		return YSFALSE;
	}
	return YSTRUE;
}

static int CheckFileLen(void)
{
	char head[32],tail[32];
	int type,nNum;
	int len;

	NfGetHead(head);
	len=strlen(head);

	NfGetTail(tail);
	len+=strlen(tail);

	NfGetType(&type);
	switch(type)
	{
	case NFTYPE_NUMBER:
		NfGetNumColumn(&nNum);
		len+=nNum;
		break;
	case NFTYPE_ALPHA:
		len++;
		break;
	}

	if(1<=len && len<=8)
	{
		return YSTRUE;
	}
	else
	{
		return YSFALSE;
	}
}

static int CheckFileExist(char *exFile)
{
	int i,nf;
	char dst[32],fil[80],*dir;
	FILE *fp;

	FlNumFiles(&nf);

	FlGetCurrentDirPtr(&dir);
	for(i=1; i<=nf; i++)
	{
		FlGetDstFile(dst,i);
		YsPrintSimpleMessage(MMI_GetBaseObj(),"確認中 %s",dst);

		sprintf(fil,"%s%s",dir,dst);
		fp=fopen(fil,"rb");
		if(fp!=NULL)
		{
			fclose(fp);
			strcpy(exFile,dst);
			goto ERREND;
		}
	}

	YsEraseSimpleMessage();
	FREEFUNC(dst);
	return YSTRUE;

ERREND:
	YsEraseSimpleMessage();
	FREEFUNC(dst);
	return YSFALSE;
}

static int Ipow(int a,int b);

static int CheckFileDescription(void)
{
	int nf,sta,stp,type,len;
	int avail;

	FlNumFiles(&nf);
	NfGetStartStep(&sta,&stp);
	NfGetType(&type);
	NfGetNumColumn(&len);

	switch(type)
	{
	case NFTYPE_NUMBER:
		avail = (Ipow(10,len)-sta+1)/stp;
		break;
	case NFTYPE_ALPHA:
		avail = ('Z'-('A'+sta)+1)/stp;
		break;
	}

	if(nf>avail)
	{
		return YSFALSE;
	}
	else
	{
		return YSTRUE;
	}
}

static int Ipow(int a,int b)
{
	int c,i;

	c=1;
	for(i=0; i<b; i++)
	{
		c=c*a;
	}
	return c;
}

static int FinalCheck(void)
{
	int yn;

	yn=YsYesNoQuestion
		(Ys11Id,"最終確認です.ファイル名を変更しますか?","変更する","やめた");

	switch(yn)
	{
	case YSYES:
		return YSTRUE;
	default:
	case YSNO:
		return YSFALSE;
	}
}

static int RenameExec(void)
{
	int i,nf;
	char src[32],dst[32],*dir,fil1[80],fil2[80];

	FlNumFiles(&nf);
	FlGetCurrentDirPtr(&dir);
	for(i=1; i<=nf; i++)
	{
		FlGetSrcFile(src,i);
		FlGetDstFile(dst,i);
		sprintf(fil1,"%s%s",dir,src);
		sprintf(fil2,"%s%s",dir,dst);
		YsPrintSimpleMessage(MMI_GetBaseObj(),"%s → %s",src,dst);
		rename(fil1,fil2);
	}
	YsEraseSimpleMessage();

	LmClearListMenu();
	FlClear();
	LmSetListMenu();
	LmCurrentDir();

	return YSTRUE;
}
