#ifndef MFILER2_COMMON
#define MFILER2_COMMON

extern "C" 
{
#include "ruby.h"

extern VALUE ruby_errinfo;          // eval後のエラーメッセージで必要

#define TAG_RETURN	0x1             // 同上
#define TAG_BREAK	0x2
#define TAG_NEXT	0x3
#define TAG_RETRY	0x4
#define TAG_REDO	0x5
#define TAG_RAISE	0x6
#define TAG_THROW	0x7
#define TAG_FATAL	0x8

#include "config.h"
#include "minato_extra.h"
#include "minato_debug.h"
#include "minato_list.h"
#include "minato_vector.h"
#include "minato_hash.h"
#include "minato_curses.h"

#include <termios.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



///////////////////////////////////////////////////////////////////////////////
// cygwinパッケージ作成時はMYCYGWINCOMPILEは1
///////////////////////////////////////////////////////////////////////////////
//#define MYCYGWINCOMPILE 1

#if defined(MYCYGWINCOMPILE)
    extern char gProgramHome[PATH_MAX];
#endif

extern char gHomeDir[PATH_MAX];
extern char gTempDir[PATH_MAX];

///////////////////////////////////////////////////////////////////////////////
// menu.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
#include "menu.h"

extern cMenu* gActiveMenu;
extern hash_obj* gMenu;
extern void set_signal_clear();
extern void set_signal_mfiler2();

///////////////////////////////////////////////////////////////////////////////
// dirwnd.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
#include "dirwnd.h"

///////////////////////////////////////////////////////////////////////////////
// main.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
extern cDirWnd* gLDir;
extern cDirWnd* gRDir;
extern hash_obj* gKeyCommand[2][KEY_MAX];
extern bool gMainLoop;
extern char gTrashBoxPath[PATH_MAX];        // ごみ箱のディレクトリパス

extern char* gVersion;                  // バージョン文字列

extern void (*gViewSystem)();         // 登録描写関数
extern void (*gView)();               // ユーザー用登録描写関数

void view(bool cmdline);        // 画面描写 cmdlineはコマンドラインを描写するかどうか

extern bool gColor;                 // カラー表示するかどうか
extern bool gIndividualCursor;      // 左右のファイラ画面でカーソル位置が独立しているかどうか
extern bool gCheckDeleteFile;       // ファイルを消す時に確認するかどうか
extern bool gCheckCopyFile;         // ファイルをコピーする時に確認するかどうか
extern bool gCheckExit;             // ファイラを終了する時に確認する稼動
extern bool gGnuScreen;             // GNU screen上で起動しているかどうか
extern bool gAutoRehash;            // コマンドラインオートリハッシュ
extern bool gUnixDomainSocket;      // UnixDomainSocketを使うかどうか
extern bool gRemainCursor;          // カーソル位置を保存するかどうか
extern bool gProcessLine;
extern bool gReadDirHistory;
extern bool gExtensionICase;        // マークファイルの拡張子別実行で大文字小文字を区別するかどうか
extern bool gExecutiveFileBold;
extern enum eKanjiCode gKanjiCodeFileName; // ファイル名の漢字コード kUnknownの場合は自動判別

extern bool gBoldExe;
extern bool gBoldDir;
extern int gColorMark;
extern int gColorDir;
extern int gColorExe;
extern int gColorLink;

extern bool gChangeTerminalTitle;
extern void ruby_nkf(char* input, char* output, enum eKanjiCode code);
extern enum eKanjiCode ruby_kconv_guess(char* input);

///////////////////////////////////////////////////////////////////////////////
// command.cpp
///////////////////////////////////////////////////////////////////////////////
void command_init();
void command_final();

///////////////////////////////////////////////////////////////////////////////
// varibale.cpp
///////////////////////////////////////////////////////////////////////////////
void variable_init();
void variable_final();

///////////////////////////////////////////////////////////////////////////////
// cmdline.cpp
///////////////////////////////////////////////////////////////////////////////
const int kCmdLineMax = 8192;

extern bool gCmdLineActive;        // コマンドラインがアクティブかどうか
extern vector_obj* gCmdLine;       // コマンドライン文字列の配列
extern int gCLCursor;              // コマンドラインヒストリのカーソル
extern int gCursor;                // コマンドラインのカーソル
extern int gCursorBefore;
extern bool gCmdLineEscapeKey;     // コマンドラインでEscapeキーによるコマンドライン終了がが効くかどうか

extern READONLY vector_obj* gCCandidate;
extern READONLY vector_obj* gCExplanation;

extern READONLY vector_obj* gHCandidate;
extern int gHistorySize;            // ヒストリの最大数

extern VALUE gPrograms;             // プログラム名補完候補
extern VALUE gEnvirons;             // 環境変数補完候補

extern bool gDotDirMask;

extern bool gXterm;
extern bool gXtermNext;
extern bool gXterm2;

extern VALUE gXtermPrgName;
extern VALUE gXtermOptTitle;
extern VALUE gXtermOptEval;
extern VALUE gXtermOptExtra;
extern VALUE gXtermType;

extern char gShellName[256];
extern char gShellPath[256];
extern char gShellOptEval[256];

extern enum eKanjiCode gCmdLineEncode;          // コマンドラインの元の漢字エンコード
extern VALUE gCmdAfterCmdlineRun;

void cmdline_init();                            // 初期化
void cmdline_final();                           // 廃棄

void cmdline_input(int meta, int key);          // 入力処理
void cmdline_view();                            // 描写処理

void cmdline_start(char* cmd, int position);    // コマンドラインに入る
void cmdline_run(char* str, char* title);       // コマンドラインを実行
void cmdline_read_history_file();               // .mhistoryを読み込む
void cmdline_rehash();                          // プログラム名補完候補を再読み込み

void cmdline_delete_last_str_if_length_0();     // コマンドラインヒストリの最後の行が空なら消す

///////////////////////////////////////////////////////////////////////////////
// cmdline_completion.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
extern int gCompletionScrollTop;
extern int gCompletionCursor;
extern bool gCompletionMenu;

void cmdline_init_after_reading_rc_file();      // RC file後の初期化

void cmdline_completion(VALUE all_candidate, char* editing, bool add_space);
void cmdline_completion2(VALUE all_candidate, char* editing, bool add_space, int candidate_len);
void cmdline_completion_clear();
void cmdline_completion_view();
void cmdline_completion_menu_input(int meta, int key);
void default_completion(char* editing_dir, char* editing_file, char* editing, int editing_position);
void completion_clear();

void cmdline_parse(char* cmdname, char* editing, char* editing_before, char* editing_dir, char* editing_file, int& editing_position, VALUE& earray, bool& squote, bool& dquote, bool& last_squote, bool& last_dquote);

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

///////////////////////////////////////////////////////////////////////////////
// cmdline_history.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
extern int gHistoryScrollTop;
extern int gHistoryCursor;

void cmdline_history_view();
void cmdline_history_input(int meta, int key);

///////////////////////////////////////////////////////////////////////////////
// cmdline_macro.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
extern ALLOCATED string_obj* extend_macro(char* in, RESULT bool* ruby_mode, RESULT bool* ruby_mode_nonoutput,RESULT bool* output, RESULT bool* quick, RESULT bool* shell_mode, RESULT bool* shell_mode2, RESULT bool* xterm_mode, RESULT bool* reset_marks,  bool flg, bool convert);

///////////////////////////////////////////////////////////////////////////////
// cmdline_alias.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
extern vector_obj* gAlias;          // エイリアス
const int kAliasMax = 65536;

struct sAlias
{
    char mAlias[kAliasMax];
    int mArgNum;
    char mCommand[kAliasMax];
};

void cmdline_alias_add(char* alias, int arg_num, char* cmd);
bool extend_alias(char* cmd, char* aliased_cmd);

///////////////////////////////////////////////////////////////////////////////
// shell.cppで定義されているもの
///////////////////////////////////////////////////////////////////////////////
#include "shell.h"

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

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

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

///////////////////////////////////////////////////////////////////////////////
// help.cpp
///////////////////////////////////////////////////////////////////////////////
extern bool gViewHelp;

void help_start();
void help_view();
void help_input(int meta, int key);

///////////////////////////////////////////////////////////////////////////////
// isearch
///////////////////////////////////////////////////////////////////////////////
#if defined(HAVE_MIGEMO_H)
extern "C"
{
#include "oniguruma.h"
#include "migemo.h"
}

extern migemo* gMigemo;
#endif

extern bool gISearch;           // インクリメンタルサーチ中かどうか
extern bool gISearchPartMatch;  // インクリメンタルサーチパートマッチ中かどうか
extern bool gISearchExplore;           // エキスプローラー風インクリメンタルサーチ
extern bool gNoPartMatchClear;         // ISearchClarでgISearchPartMatchをクリアするかどうか
extern bool gISearchOption1;            // 先頭インクリメンタルサーチが失敗したら部分一致インクリメンタルサーチするオプション

bool IsISearchExploreChar(int meta, int key);  // その文字がエクスプローラー風インクリメンタルサーチで使うものかどうか
void ISearchClear();                // インクリメンタルサーチ文字列初期化
bool IsISearchNULL();               // インクリメンタルサーチの文字列が空

void isearch_init_after_reading_rc_file();            // インクリメンタルサーチ初期化
void isearch_final();                                   // インクリメンタルサーチ解放

void isearch_input(int meta, int key); // インクリメンタルサーチキー入力
void isearch_explore_input(int meta, int key); // エキスプローラー風インクリメンタルサーチキー入力
void isearch_view();                            // インクリメンタルサーチ描写
void isearch_explore_view();                   // エキスプローラー風インクリメンタルサーチ描写

void isearch_reload_migemo_dict();      // エンコードにあわせたmigemoの辞書再ロード
///////////////////////////////////////////////////////////////////////////////
// super isearch
///////////////////////////////////////////////////////////////////////////////
extern bool gSISearch;
extern int gCandiateMaxAscii;
extern int gCandidateMaxMigemo;
extern bool gSISearchMigemo;

void sisearch_init();
void sisearch_final();
void sisearch_get_cache();
void sisearch_view();
void sisearch_input(int meta, int key);
bool sisearch_cache_exist();
void sisearch_start();
void sisearch_check();

///////////////////////////////////////////////////////////////////////////////
// extra
///////////////////////////////////////////////////////////////////////////////
extern bool correct_path(char* current_path, char* path, char* path2); // 相対パスなどを絶対パス表示にする
extern void output_eval_error(int error);          // rubyのeval実行時エラーがあればエラー表示

extern void cut(char* src, char* dest, int len);
extern void cut2(char* src, char* dest, int len);

extern bool gErrMsgCancel;
extern int err_msg(char* msg, ...);        // コマンドライン上にエラーメッセージ表示 gErrMsgCancelをfalseにしておく必要あり

extern void msg(char* msg, ...);           // コマンドライン上にメッセージ表示
extern void msg_nonstop(char* msg, ...);   // コマンドライン上にメッセージ表示（キー入力待ちなし)
extern int select_str(char* msg, char* str[], int len, int cancel);    // 文字列選択
extern int input_box(char* msg, char* result, char* def_input, int def_cursor);        // コマンドライン上で文字列入力

// path2 must have enough space
extern void strtolower(char* result);

extern int msystem(char* line);

#endif

