#ifndef MFILER3_COMMON_H
#define MFILER3_COMMON_H

#include "config.h"

#if defined(__CYGWIN__)

#define _LARGEFILE64_SOURCE       // サイズが大きいファイルを扱うために必要
#include <sys/stat.h>     // ↑のマクロを使ってコンパイルしないといけない
#define stat64 stat
#define __off64_t long long int
#define lstat64 lstat
#undef _LARGEFILE64_SOURCE

#elif defined(__DARWIN__)

#define _LARGEFILE64_SOURCE       // サイズが大きいファイルを扱うために必要
#include <sys/stat.h>     // ↑のマクロを使ってコンパイルしないといけない
#define __off64_t long long int
#define stat64 stat
#define lstat64 lstat
#undef _LARGEFILE64_SOURCE

#elif defined(__LINUX__)

#define _LARGEFILE64_SOURCE      // サイズが大きいファイルを扱うために必要
#include <sys/stat.h>     // ↑のマクロを使ってコンパイルしないといけない
#include <linux/stat.h>

#endif

#include <unistd.h>

#ifndef	NSIG
# ifdef	_NSIG
# define	NSIG		_NSIG
# else
#  ifdef	DJGPP
#  define	NSIG		301
#  else
#  define	NSIG		64
#  endif
# endif
#endif

#include <limits.h>
#include <signal.h>
#include <sys/wait.h>

#include <saphire_extra.h>             // 自作ライブラリ群
#include <saphire_curses.h>
#include <saphire_vector.h>
#include <saphire_string.h>
#include <saphire_list.h>
#include <saphire_hash.h>
#include <saphire_debug.h>

#include <saphire.h>                // 自作シェルスクリプトライブラリ

#include "filer.h"

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

#if defined(S_ISTXT)
    #define S_ALLPERM (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISTXT)
#elif defined(S_ISVTX)
    #define S_ALLPERM (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISVTX)
#else
    #define S_ALLPERM (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID)
#endif

#define S_IXUGO (S_IXOTH | S_IXGRP | S_IXUSR)

//////////////////////////////////////////////
// main.c
///////////////////////////////////////////////
extern char gHomeDir[PATH_MAX];     // ~/.mfiler3/のパス
extern char gTempDir[PATH_MAX];     // 一時ディレクトリのパス
extern int gMainLoop;               // メインループを回すかどうか -1の間回す。終了時はリターンコードとなる
extern BOOL gExitCode;              // 終了コード

extern void (*gView)();             // 登録描写関数(関数を登録しておけばviewで実行される)

void set_signal_mfiler();

void view(BOOL cmdline_draw);                        // 全体の描写関数

///////////////////////////////////////////////
// menu.c
///////////////////////////////////////////////
typedef struct {
    char* mName;
    int mKey;
    char* mCmd;
} sMenuItem;

typedef struct {
    char mTitle[256];

    int mScrollTop;
    int mCursor;

    vector_obj* mMenuItems; 
} sMenu;

extern hash_obj* gMenu;
extern sMenu* gActiveMenu;

sMenu* sMenu_new(char* title);
void menu_view(sMenu* self);
void menu_input(sMenu* self, int meta, int key);
void menu_append(sMenu* self, char* name, int key, char* cmd);
void menu_init();
void menu_final();
void menu_start(char* menu_name);

///////////////////////////////////////////////////
// isearch.c
///////////////////////////////////////////////////
extern BOOL gISearch;        // インクリメンタルサーチ中かどうか
void isearch_init();         // インクリメンタルサーチ初期化
void isearch_final();        // インクリメンタルサーチ解放

void isearch_input(int meta, int key); // インクリメンタルサーチキー入力
void isearch_view();                  // インクリメンタルサーチ描写

BOOL IsISearchExploreChar(int meta, int key);
BOOL IsISearchNULL();
void ISearchClear();

///////////////////////////////////////////////////
// cmdline
///////////////////////////////////////////////////
extern BOOL gCmdLineActive;
extern string_obj* gCmdLine;
extern int gCmdLineCursor;

#define kCmdLineMax 16000

void cmdline_init();
void cmdline_final();
void cmdline_input(int meta, int key);
void cmdline_view();
void cmdline_convert();

extern int gHistoryScrollTop;
extern int gHistoryCursor;

extern vector_obj* gHCandidate;

void cmdline_history_view();
void cmdline_history_input(int meta, int key);
void cmdline_hcandidate_refresh();
void cmdline_start(char* str, int cursor, BOOL quick, BOOL continue_);
void cmdline_write_history();
void cmdline_read_history();
void add_history(char* str);

///////////////////////////////////////////////////
// cmdline_completion.c
///////////////////////////////////////////////////
extern vector_obj* gCCandidate;

void cmdline_completion_init();
void cmdline_completion_final();

void cmdline_completion_view();
void cmdline_completion_input(int meta, int key);

void cmdline_completion_main();

void cmdline_completion(vector_obj* all_candidate, char* editing, BOOL add_space);

void cmdline_completion_file(char* editing_dir, char* editing_file, char* editing, int editing_position);
void cmdline_completion_program(char* editing_dir, char* editing_file, char* editing, int editing_position);

void cmdline_completion_clear();

///////////////////////////////////////////////////
// gui.c
///////////////////////////////////////////////////
char* choise(char* msg, char* str[], int len, int cancel);
void merr_msg(char* msg, ...);
void msg_nonstop(char* msg, ...);
int select_str(char* msg, char* str[], int len, int cancel);
int select_str2(char* msg, char* str[], int len, int cancel);
int input_box(char* msg, char* result, int result_size, char* def_input, int def_cursor);

///////////////////////////////////////////////////
// commands.c
///////////////////////////////////////////////////
void commands_init();
void commands_final();

///////////////////////////////////////////////////
// file.c
///////////////////////////////////////////////////
enum eCopyOverride { kNone, kYesAll, kNoAll, kCancel, kSelectNewer, kYesAllRemainPermission };
extern enum eCopyOverride gCopyOverride;

enum eWriteProtected { kWPNone, kWPYesAll, kWPNoAll, kWPCancel };
extern enum eWriteProtected gWriteProtected;

BOOL file_copy(char* spath, char* dpath, BOOL move, BOOL preserve);
BOOL file_remove(char* path, BOOL no_ctrl_c, BOOL msg);

#endif

