/*
 * シェルスクリプトエンジン
 * 湊大典(c) 2009-2010
 */

#ifndef KITUTUKI_H
#define KITUTUKI_H

#include "kitutuki_vector.h"
#include "kitutuki_list.h"
#include "kitutuki_string.h"
#include "kitutuki_kanji.h"
#include "kitutuki_curses.h"
#include "kitutuki_hash.h"
#include "kitutuki_debug.h"
#include "kitutuki_extra.h"

/*
    使い方のサンプルはmain.cを参考にしてください
*/

extern enum eKanjiCode gKanjiCode;
    // kitutukiが使うデフォルトの漢字コード
    // 初期値はUTF8
    // (端末の漢字コードとは別でかまわない)
enum eLineField { kLF, kCRLF, kCR };
extern enum eLineField gScriptLineField;
    // スクリプトファイルの改行コードの種類
enum eAppType { kATOptC, kATXApp, kATCursesApp, kATConsoleApp };
    // アプリケーションの種類
    //
    // kATOptC コマンドラインから使う場合
    // kATXApp Xを使っているアプリ
    // kATCursesApp 端末制御ライブラリを使っているコンソールアプリ
    // kATConsoleApp 端末制御ライブラリを使わないコンソールアプリ

enum eRuntimeScript { kRSNoRead, kRSSource, kRSObject };
    // ランタイムスクリプトをどうするのかの設定

    // kRSNoRead 読み込まない
    // kRSSource ソースファイルを読み込む
    // kRSObject オブジェクトファイルを読み込む

void kitutuki_init(enum eAppType app_type, BOOL job_control, enum eRuntimeScript runtime_script);
    // 初期化。kitutuki_shellなどを実行する前に必ず必要
    // アプリケーションの種別とジョブコントロールの有無とランタイムスクリプトをどうするかを読み込むかを設定してください
    // あと、必要な初期化は端末制御ライブラリkitutuki_curses.h
    // のmcurses_init()です。
void kitutuki_final();
    // 終了化。終了時に必要
void kitutuki_set_signal();
    // kitutukiを実行中に使うシグナルの設定を設定する。
    // kitutuki_shell, saphie_shell3などのkitutukiのコードを実行する前
    // に必ず呼んでください。
    // 呼ばれないと正しくコマンドは実行されません。

    // 処理しているのは
    // SIGCHLD, SIGINT, SIGCONT, SIGWINCH, SIGUSR1
    // 無視しているのは
    // SIGTTOU, SIGTTIN, SIGTSTP, SIGQUIT, SIGPIPE
void kitutuki_restore_signal_default();
    // シグナルを初期値に戻す
extern void (*kitutuki_set_signal_other)();
    // もし関数ポインタが代入されていたら
    // kitutuki_set_signalで実行される
extern string_obj* gErrMsg;
    // エラーが起こった時はこの配列にメッセージ入っているので出力してください
int kitutuki_shell(char* command, char* title, int pipeout, int pipein, int pipeerr, BOOL verbose);
    // 文字列を読み込んで実行
    // commandは実行するコマンドの文字列。titleはタイトル
    // pipeoutは出力先。pipeinは入力先
    // pipeerrはエラー先（ファイルディスクリプタ)
    // 戻り値はプログラムの終了コードだが、0以下だと
    // kitutuki内でエラーが起こっているのでgErrMsgをどこかに
    // 出力してください。
    // verboseは実行しているコマンド名を表示するかどうか
int kitutuki_shell3(string_obj* result, char* command, char* title, BOOL verbose);
    // 文字列を読み込んで実行。コマンドの出力はresult
    // (kitutuki_string.hで定義されているstring_obj*文字列型)に入る
    // 戻り値はプログラムの終了コードだが、0以下だとkitutuki内でエラーが
    // 起こっている
    // のでgErrMsgをどこかに出力してください。
    // resultはstring_newで領域を確保しておかないといけない
    // verboseは実行しているコマンド名を表示するかどうか
int kitutuki_load(char* fname, int pipeout, int pipein, int pipeerr, BOOL verbose);
    // スクリプトファイルを読み込んで実行
    // pipeoutは出力先。pipeinは入力先
    // pipeerrはエラー先（ファイルディスクリプタ)
    // 戻り値はプログラムの終了コードだが、0以下だとkitutuki内で
    // エラーが起こっている
    // のでgErrMsgをどこかに出力してください。
    // verboseは実行しているコマンド名を表示するかどうか
BOOL kitutuki_compile(char* fname, char* out_fname);
    // fnameのファイルをコンパイルしてout_fnameに保存
int kitutuki_load_obj(char* fname, int pipeout, int pipein, int pipeerr,BOOL verbose);
    // コンパイル済みのファイルfnameを実行
    // pipeoutは出力先。pipeinは入力先
    // pipeerrはエラー先（ファイルディスクリプタ)
    // 戻り値はプログラムの終了コードだが、0以下だとkitutuki内で
    // エラーが起こっている
    // のでgErrMsgをどこかに出力してください。
    // verboseは実行しているコマンド名を表示するかどうか
void kitutuki_wait_background_job();
    // バックグランドジョブの状態のチェック
    // ジョブ管理をする場合メインループ中に定期的に実行してください
void kitutuki_sweep();
    // kitutukiで作られる一時的なファイルを削除する
    // メインループ中に定期的に実行してください
    // 書かなくてもkitutuki_finalで全て削除されますが
    // プロセス置換を行うごとにどんどんファイルが増えていきます。
extern void (*kitutuki_job_done)(int job_num, char* job_title);
    // ジョブ管理しているときにジョブが終わったら実行する処理
    // job_numに終わったジョブの番号が入いれて呼ばれる。
    // job_titleに終わったジョブのタイトルを入れて呼ばれる
int kitutuki_job_num();
    // 現在のジョブの数を返す
char* kitutuki_job_title(int num);
    // num番号のジョブのタイトルを返す。
void kitutuki_kill_job(int num);
    // num番号のジョブを消す
void kitutuki_kill_all_jobs();
    // 全てのジョブを強制消去
    // アプリケーションを終了する前に実行してください
    // ただし大抵のジョブは終わっていないと問題が起こると
    // 思われるのでkitutuki_job_numで終わっていないジョブがあると
    // アプリケーションを終われないようにしとくほうがいいかもしれません。

extern vector_obj* gPrograms;               // 補完候補

void kitutuki_rehash();
    // プログラム補完候補の一覧の再読み込み
    // $PATHから読み込む
    // gPrograms(動的配列型vector_obj*)に文字列型(string_obj*)として入る

extern BOOL gKitutukiExit;
        // exit内部コマンドが呼ばれたらTRUEが入る
        // メインループでTRUEが入っていたらプログラムを
        // 終了してください。
extern void kitutuki_get_quoted_fname(char* fname
                    , string_obj* quoted_fname);
        // kitutukiシェルで使われる特殊な文字をクォートした文字列を返す
        // &,|,>など

typedef BOOL (*fInnerCommand)(int* rcode, vector_obj* argv, int nextout, int nextin, int nexterr, char* title, BOOL input);
        // 内部コマンドの実行コード
        // 戻り値は実行に成功したらTRUE, 実行に失敗したらFALSEを返してください。
        // rcodeはリターンコード. 何も入力しなかったら最初は1が入っている
        // コマンドが成功したら*rcode = 0などとしてコマンドの成功を
        // 示してください。
        // argvはstring_obj*（文字列）のvector_obj*(動的配列)。
        // コマンドライン引数が入っている。(0番目はコマンド名)
        // nextoutは出力先 (パイプやファイルや端末など適切に処理される)
        // nextinは入力元
        // nexterrはエラー出力先
        // titleはコマンドのタイトルが入っている
        // inputはパイプ処理を行う場合はTRUEになっている
        // ls | command などのcommand
        // | command (グローバルパイプ)とかのcommandの場合はTRUE
        // command | lessのcommandだとFALSE

void kitutuki_add_inner_command(char* name, fInnerCommand fun);
       // 内部コマンドの追加。上のfInnerCommandを実装して第二引数に
       // 関数ポインタを入力。第一引数はコマンド名

extern volatile BOOL gKitutukiSigInt;  // CTRL-Cが押されたらTRUE

char* kitutuki_get_local_var(char* name);
    // 現在のスタックフレームでのローカル変数を返す
    // 無ければNULLが返る

void kitutuki_set_local_var(char* name, char* value);
    // 現在のスタックフレームにローカル変数を追加する
void kitutuki_delete_local_var(char* name);
    // 現在のスタックフレームのローカル変数を削除する

char* kitutuki_get_global_var(char* name);
    // グローバル変数を返す
    // 無ければNULLが返る

vector_obj* kitutuki_get_array(char* name);
    // 配列を返す string_obj*(文字列型)が入ったvector_obj*(動的配列)
    // 無ければNULLが返る

hash_obj* kitutuki_get_hash(char* name);
    // ハッシュを返す string_obj*(文字列型)が入ったhash_obj*(ハッシュ)
    // 無ければNULLが返す

typedef struct 
{
    vector_obj* mStatments;
} sStatments;

sStatments* sStatments_new();
void sStatments_delete(sStatments* self);
int kitutuki_run(sStatments* statments, char* title, int pipeout, int pipein, int pipeerr, BOOL verbose);
    // kitutuki_compile2でコンパイルしたコンパイル結果を実行する。
    // verboseは実行する前に実行するコマンド名を表示するかどうか
BOOL kitutuki_compile2(char* cmdline, char* fname, sStatments* statments);
    // cmdlineのソースをコンパイルして結果をstatmentsに格納する。
    // コンパイル結果のstatmentsはkitutuki_runによって実行できる。
    // statmentsはsStatments_newによって初期化されないといけない。
    // また必要でなくなったらsStatments_deleteによって開放しないといけない。
    // 終了時にできればsStatments_deleteしたほうがよい。

    // サンプル
    /*

    sStatments statments = sStatments_new();

    kitutuki_compile2("ls -al | less; pwd", "title", statments);

    kitutuki_run(statments, "run", STDOUT_FILENO, STDIN_FILENO, STDERR_FILENO, FALSE);

    sStatments_delete(statments);

    */


#endif

