#pragma ident "@(#) filer.h 1.1.0 2012.12.06,10:11"
#ifndef FILER_H
#define FILER_H FILER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <memory.h>
#include <malloc.h>

#ifdef CYGWIN
#include <ncurses/curses.h>
#include <ncurses/form.h>
#else
#include <curses.h>
#include <form.h>
#endif

#include <locale.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>

#define MAX_FILES 4096
//#define MAX_TREE 8192
#define MAX_TREE 30000
#define ON 1
#define OFF 0
#define MAX_WINDOW 1

#define	iskanjich(c)	((c >= 0x81 && c <= 0x9f || c >= 0xe0 && c<= 0xfc) ? (ON) : (OFF))	
#define	isnumeric(c)	((c >= 0x30 && c <= 0x39 || c == 0x2e || c == 0x2d) ? (FLG_ON) : (FLG_OFF))	

class FilerTool {
private:
	void _splitpath(char *path,char *dir,char *file);
	void cutfspace(char *s);
	void getdirfile(char *pathbuff);
protected:
	//ファイラー、ミニファイラー、ツリーファイラーで共通に使用可能

	// /etc/passwd /etc/group からユーザID、グループIDを格納する
	char username[256][16];
	char userid[256][7];
	char groupname[256][16];
	char groupid[256][7];
	char openbuff[1024][33];

	char dirbuff[256];
	char filebuff[256];
	char depath[256];

	//ブックマーク用
	char bookmarks[256][256];
	int bookline;
	char gwpmenu[256][256];
	int displine;
	int curline;

public:
	//ディレクトリ移動管理
	char homedirname[256];	// 環境変数 HOME に定義されたディレクトリ
	char startdirname[256];	//CWを起動したディレクトリ
	char docbuff[128];		//ブックマークのディレクトリ
	char dirstack[256][512];//チェンジディレクトリの記録を保存する
	int dirlocatey[256];	//カーソル行の履歴
	int dirlocatey_save[256];	//
	int dirlocateyy[256];		//ファイル行の履歴
	int dirlocateyy_save[256];	//ファイル行の履歴保存
	char dirlocate[256][512];	//パス名履歴保存

	//以下はローカルファイラー共通関数
	virtual int bookmarksave(void);
	virtual void bookmark(void);
	virtual void readowner(void);
	virtual void readgroup(void);
	virtual void passread(char *path,int n);
	virtual void groupread(char *path,int n);
	virtual void pathfiled(char *path,int n);
	virtual char *bookmarkmenu(int x,int y,char *buff);

	virtual int popmsg(int x,int y,const std::string Message);

};

class LocalFiler : public FilerTool {
private:
	//ファイル名のソート用
	char fsortbuff[MAX_FILES][512];
	char fsortbuff2[MAX_FILES][512];
	char fil[MAX_FILES];
	int fileindex[MAX_FILES];

	int pathisto;			//ディレクトリ移動数
	int pathcnt;			//移動パス名のカウント

	char buff0[MAX_FILES][64];	// for dtree

protected:
	//ファイラーがTABキーでファイルを複数選択した場合の処理用
	char selcp[256][512];// /bin/cp 用
	int cpflag[256]; 	// /bin/cp 用
	int regline[MAX_FILES];
	int intCPnum;

	//ファイラー表示項目
	struct FileView {
		char buff1[512];	//ファイル名
		char buff2[32];		//ファイルサイズかディレクトリの表示
		char buff3[64];		//作成日付
		char buff4[32];		//パーミッション
		char buff5[32];		//ユーザ名
		char buff6[32];		//グループ名
	} fs[MAX_FILES];

	int fmode;		//ファイルの作成、更新、年表示の切替えフラグ
	int botom;		//ファイラーの最下行
	int dmode;	// 'v'と 'h' .の付いたファイルの表示非表示を切替える
	int file_num;		//カレントディレクトリのファイル数

public:
	//ファイラーウインドウ。現在20ウインドウまで展開可能
	struct ViewBox {
		WINDOW *vs;	//端末ウインドウ
		int col;	//Ｘ軸の長さ（ウインドウの横の幅）
		int line;	//Ｙ軸の長さ（ウインドウの縦の長さ）
		int x;		//表示桁位置
		int y;		//表示行位置
	} pt[20];

	int max_lines;

	LocalFiler() {};
	//FTXとの接続用
	int RemoveTmpDir(void);
	void FTPConnect(void);
	void FTPSelect(void);
	int minifiler(int start,int end);

	int filer(int start,int end);

	//CWローカルファイラー用関数
	void all_cls(int no);
	void tabselectclear(void);
	virtual int popmsg(int x,int y,const std::string Message);
	int popmsg2(int x,int y,const std::string Message);
	int findex(char *s,char *t);
	int resize(void);
	int filemode(uid_t ut,mode_t at, char *filebuff);
	char *cmpuid(uid_t uid);
	char *cmpgid(uid_t gid);
	char *cutspace(char *s);
	char *cutchars(char *s,int c);
	char *Mid1(char *ss, int a, int b);
	char *Mid2(char *ss, int a, int b);
	char *Mid3(char *ss, int a, int b);
	char *Mid4(char *ss, int a, int b);
//	char *left2(char *s,size_t n);
	char *right2(char *s, size_t n);
	void cls_all(int no);
	void vs_cls(int no,int col);
	void line_clear(int no,int x,int y,int sy,int end,int len);
	void datadisp(int no,int x,int y,int sy);
	void vs_print(const std::string Message,WINDOW *vs,int x,int y);
	void set_screen(int no);
	void set_screen_line1(int no);
	void set_screen_line2(int no);
	void initbuff(void);
	void displaymenu1(WINDOW *evs,int flag);
	void displaymenu2(WINDOW *evs);
	void dialogmsg(int x,int y,const std::string Message);
	void dialogmsg2(int x,int y,const std::string Message,const std::string Heder);
	void usermsg(int x,int y,char *buff);
	void sys_errmsg(int x,int y,const std::string Message);
	void fsort(int filenum,int point);
	void dirprint_all(const std::string dname,int type);
	virtual void *input_window(int x,int y,char *buff,const std::string Message);
	virtual void *input_window(int x,int y,char *buff,char *buff2,const std::string Message);
	void rectang(int no);
	void attrview(int at,char *attrbuff);
	void checkhisto(void);
	void Mid(char *ds, char *ss, int a, int b);
	void dirlocateclear(void);
	void dirlocateofset(char mode);

	void right3(char *ds, char *ss, int a);
	~LocalFiler() {};

	//ローカルファイラーの共通コマンド
	void command00(int no);	//CMSメニューの起動
	void command01(int no, int y, int yy);	//Hiddenファイル・ディレクトリ表示／非表示
	int command02(int no,int y, int yy);	//ブックマークのディレクトリに移動する。(コピー機能有り)
	void command03(int no);	//ファイル・ディレクトリを作成した日付と時間で表示
	void command04(int no);	//ファイル・ディレクトリを最新アクセスした日付で表示
	void command05(int no);	//ファイル・ディレクトリを作成した日付で表示
	void command06(int no, int y, int yy);	//ファイルの選択（マーク）
	int command07(int no);	//複数選択表示（less）
	int command08(int no);	//複数ファイルの選択削除
	int command09(int no, int y, int yy);	//tar -xzf fine-name を実行
	int command10(int no, int y, int yy);	//tar -czf fine-name を実行
	int command11(int no, int y, int yy);	//ファイルの属性（モード）を変更
	int command12(int no);	//起動したディレクトリに戻る
	int command13(int no);//環境変数 HOME に定義されたディレクトリに移動
	int command14(int y, int yy);//ファイルのコードをＥＵＣコードに変換する
	int command15(int y, int yy);//ファイルのコードをUTF-8コードに変換する
	int command16(int y, int yy);//ファイルのコードをシフトJISコードに変換する
	int command17(int no, int y, int yy);	//ディレクトリの削除
	void command18(int no);	//ファイル指定なしでｖｉエディタを起動する
	int command19(int no, int y, int yy);//ファイル指定でｖｉエディタを起動する
	int command20(int no, int y, int yy);//ファイル指定でWindows版vimエディタを起動する
	int command21(int no, int y, int yy);//ディレクトリ移動の履歴を遡る
	int command22(int no, int y, int yy);//ディレクトリ移動の履歴を戻る
	int command23(int no, int y, int yy);	//使用不可
	int command24(int no, int y, int yy);	//使用不可
	int command25(int no, int y, int yy);	//ファイルビューアを起動する
	int command26(int no, int y, int yy);	//ファイルを削除する
	int command27(int no, int y, int yy);	//ファイルを移動または名前を変更する
	int command28(int y, int yy);	//ファイルをコピーする
	int command29(int no, int y, int yy);	//複数選択移動
	int command30(int no, int y, int yy);	//複数選択コピー
	int command31(int no, int y, int yy);	//複数ファイルの tar -czf
	void command32(int no);	//シェルモードへ移行(ksh)
	int command33(int no);	//ディレクトリを作成する
	int command34(int no);	//入力でディレクトリを移動する
	void command35(int no);	//コマンド入力でプログラムの実行
	int command36(int no, int y, int yy);	//ファイルを実行する（fork()実行）
	int command37(int no, int y, int yy);	//シンボリックリンクの作成
	void command38(int no, int y, int yy);	//ＭＡＫＥコマンドを実行
	void command39(int no, int y, int yy);	//ＭＡＫＥコマンドを実行（引数付き）

};


class LocalTree : public LocalFiler {
private:
	char selcp[256][512];// /bin/cp 用
	int cpflag[256]; 	// /bin/cp 用
	int regline[MAX_TREE];
	int intCPnum;

	int pmode;				//.ファイルを表示するかどうかのフラグ
	int dtree_fmode;		//ファイルの作成、更新、年表示の切替えフラグ
	int dtree_max_lines;	//現在ツリーの最大行
	int dtree_file_num;		//カレントディレクトリのファイル数
	int dtree_botom;		//ファイラーの最下行
	int dtree_pathisto;		//ディレクトリを移動した履歴数
	int dtree_pathcnt;		//dirstack[]に入れる移動履歴のカウント
	int dtree_jump;			//
	char retdirname[128][256];//チェンジディレクトリしたディレクトリ名を保存する

	struct TreeView {
		char buff1[256];	//ファイル名
		char buff3[64];		//作成日付
		char buff5[32];		//ユーザ名
		char buff6[32];		//グループ名

		char dtree1[128];	//ツリー表示
		char dtree2[128];	//絶対パス表示

		char buff10[256];	//ディレクトリ名
	} ts[MAX_TREE];

public:
	LocalTree() {};
	void line_clear2(int no,int x,int y,int sy,int end,int len);
	void vs_cls2(int no,int col);
	void set_screen2(void);
	void dtree_clear(void);
	void filer_clear(void);
	void dtree_all_cls(int no);
	void dtree_datadisp(int no,int x,int y,int sy);
	void dtree_set_screen(void);
	void dtree_initbuff(void);
	void dtree_displaymenu1(WINDOW *evs,int flag);
	void fileprint(const std::string Dname);
	void dtree_dirprint(void);
	char *basename(char *s);
	int pathcount(char *p);
	int tree(int start,int end);
	int get_dtree(void);
	int dtree(void);
	~LocalTree() {};
};

class AseEditor : public LocalFiler {
private:
	struct cell {
		int no;
		int x;
		int y;
		int c;
		int len;
		int attr;
		int mode;
		int action;
		char s[256];
		char p[256];
		WINDOW * cell;
	} cp[256][80];

	char copybuff[256][80][256];

	char tmpbuff1[256];
	char tmpbuff2[256];

	struct ViewBox {
		WINDOW *vs;	//端末ウインドウ
		int col;	//Ｘ軸の長さ（ウインドウの横の幅）
		int line;	//Ｙ軸の長さ（ウインドウの縦の長さ）
		int x;		//表示桁位置
		int y;		//表示行位置
	} pt2[256][80];

	struct ecpg {
		int cell_length;
		char cell_fieldtype[15];
		char cell_skipstep[12];
	//	char cell_title[138];
		char cell_title[256];
		int keyflg;
	} pgc[512];

public:
	AseEditor() {};
	int ase(int xcol,int xrow,char *f,int command);
	~AseEditor() {};

	int convlabel(WINDOW *vs,int xcol, int xrow, char *f);
	int convtextbox(WINDOW *vs,int xcol, int xrow, char *f);
	int convgrid(WINDOW *vs,int xcol, int xrow, char *f);
	int putecpg(WINDOW *vs,int xcol, int xrow, char *f);
	int putecpgKey(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgKey2(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgHeader(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgINSERT(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgUPDATE(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgUPDATE2(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgDELETE(WINDOW *vs,int xcol, int xrow, char *f, char *sf);
	int putecpgInterFace(char *f, char *sf);
	int putecpgInterFace2(char *f, char *sf);
	int putecpgInterFace_New(char *f, char *sf);
	int putecpgInterFaceMenu(char *f, char *sf);
	int putecpgResult(char *f, char *sf);
	int putecpgMain1(char *f);
	int putecpgMain2(char *f,char *sf);
	int putecpgMenu(char *f);
	int putecpgMain2_INSERT(char *f);
	int putecpgMain2_UPDATE(char *f);
	int putecpgMain2_DELETE(char *f);
	int putecpgMain3(char *f);
	int putCreateSQL(WINDOW *vs,int xcol, int xrow, char *f, int nline);
	int rightcell(int xcol, int xrow);
	int freads(int xcol, int xrow, char *f);
	int fwrites(int xcol, int xrow, char *f);

	int convlabel2(WINDOW *vs,int xcol, int xrow, char *f);
	int convtextbox2(WINDOW *vs,int xcol, int xrow, char *f);
	int convgrid2(WINDOW *vs,int xcol, int xrow, char *f);

	//HTML用の関数を生成する
	int convlabel3(WINDOW *vs,int xcol, int xrow, char *f);
	int convtextbox3(WINDOW *vs,int xcol, int xrow, char *f);
	int convgrid3(WINDOW *vs,int xcol, int xrow, char *f, char *sf);

	char *vs_ieee_c(WINDOW *vs,int x,int y,char *p,int N)
	{
		if(mvwgetstr(vs,y,x,p) != (int)0)
		{
			*p = '\0';
			return((char *)p);
		}
		return((char *)NULL);
	}
};

class CMSLocalFiler : public LocalFiler {
private:
//cmsfiler.cc のファイルソート用バッファ。現在LocalFiler のを借用。

	int pathisto;			//ディレクトリ移動数
	int pathcnt;			//移動パス名のカウント

//cmsfiler.cc のファイルウインドウ用構造体。現在LocalFiler の fs[]を借用。
	char fusrdir[256];
	char lockdir[256];
	char mrdir[256];
	char trdir[256];
	
	int N;
	int N2;
	int M2;

	char cmstablefile[256];
	char cmshomefilename[256][256];
	int cms_file_num;
	
	char cmsuserhomedir[256];
	char cmspathname[256];
	char table_filename[256];
	char table_buff[128][64];
	char filebuff[1024];
	char depath[256];
	char revisionbuff[256];
	char mr_revisionfile[256];
	char mr_editfile[256];
	char tr_revisionfile[256];
	char tr_editfile[256];
	char sysname[64];
	char tabfile[64];
	char editor[9];
	char cmseditor[64];
	char filename2[64];
	char username[64];
	char version[12];
	char systembuff[256];
	char list[100][256];		//ファイル名のリスト用
	char list2[100][12];	//リビジョン番号のリスト用
	char mrlist[1000][64];	//ＭＲのリスト用
	char mrlist2[1000][12];	//ＭＲ番号のリスト用

protected:

public:

	char *popmenu2(int x,int y,const std::string Title,int xwidth,int ylen);
	char *popmenu3(int x,int y,const std::string Title,int xwidth,int ylen);
	char *popmenu4(int x,int y,const std::string Title,int xwidth,int ylen);
	char *popmenu5(int x,int y,const std::string Title,int xwidth,int ylen);
	int popmsg(int x,int y,const std::string  Message);
	void input_window3(int x,int y,char *buff,const std::string Message);

	void update_revision(void);
	void update_mr(void);
	void cleanbuff(void);
	void tabopen(void);
	void envset(void);
	void envset2(void);
	void tabclean(void);
	void tabedit(void);
	
	void cmsset(void);
	int make(char *filename);
	int showget(char *filename);
	int showput(char *filename);
	int compile(char *filename);
	int get(int x, int y);
	int put(char *filename);
	int submit(char *filename);
	int cms_editor(char *filename);
	int unget(char *filename);
	int vget(int x, int y);
	int putlog(int x,int y,char *filename);
	int mredit(int x, int y);
	int tredit(int x, int y);
	int rejectmr(int x, int y);
	int mr(int x, int y);
	int tr(int x, int y);
	int mrcsvout(void);
	int trcsvout(void);
	int mrreport(int x, int y);
	int newfile(int x,int y);
	int reject(int x, int y,char *filename);

	void initcmsbuff(void);
	virtual char *basename(char *s);
	char *getCMSFile(char *filename);
	int chkCMSTree(void);
	int cmsfile(char *cwdpath,char *filename);
	int readcmstab(void);

	//CMSローカルファイラー用関数
	CMSLocalFiler() {};
	int cms(void);
	int cmsfiler(int start,int end);
	virtual void errmsg(char *buff);
	void dirprint_cms(const std::string Dname,int type);
	~CMSLocalFiler() {};
};

//libsubform.a に含まれる関数だが、本ライブラリにも同じ関数を転用した。
extern int jmvwgetnstr(WINDOW *win, int y, int x, unsigned char *str, int n, int wmode, int cmode);

#endif
