/* 
 * 画面制御ライブラリ
 */

#ifndef MINATO_CURSES_H
#define MINATO_CURSES_H

#if defined(HAVE_CURSES_H)
#include <curses.h>
#elif defined(HAVE_NCURSES_H)
#include <ncurses.h>
#endif

#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "config.h"
#include "minato_string.h"

#include <wchar.h>

///////////////////////////////////////////////////////////////////////////////
// 変数定義
///////////////////////////////////////////////////////////////////////////////
extern int gKeyEscapeWait;      // エスケープキーの待ち時間

///////////////////////////////////////////////////////////////////////////////
// マクロ定義
///////////////////////////////////////////////////////////////////////////////
#define kCAReverse 0x1          // 文字列の属性
#define kCABold 0x2
#define kCAUnderline 0x4
#define kCABlack 0x8
#define kCARed 0x10
#define kCAGreen 0x20
#define kCAYellow 0x40
#define kCABlue 0x80
#define kCAMagenta 0x100
#define kCACyan 0x200
#define kCAWhite 0x400
#define kCABackBlack 0x800
#define kCABackRed 0x1000
#define kCABackGreen 0x2000
#define kCABackYellow 0x4000
#define kCABackBlue 0x8000
#define kCABackMagenta 0x10000
#define kCABackCyan 0x20000
#define kCABackWhite 0x40000

///////////////////////////////////////////////////////////////////////////////
// 関数定義
///////////////////////////////////////////////////////////////////////////////
void mcurses_init();            // minato_cursesモジュール初期化 プログラム開始時に呼ぶ
void mcurses_final();           // minato_cursesモジュール解放 プログラム終了時に呼ぶ

void minitscr();                // minato_curses初期化 minato_cursesを使う前に呼ぶ
void mendwin();                 // minato_curses解放 minato_cursesを使い終わった後に呼ぶ

#define kKeyMapKeysMax 10
void madd_keymap(int key, char keyes[kKeyMapKeysMax]);      // キーマップにキーを追加

void mclear();                          // メモリ上の画面を消去
void mclear_immediately();              // 直接画面を消去
void mclear_online(int y);              // メモリ上の画面を一行消去

void mmove(int y, int x);                           // メモリ上のカーソルを移動
void mmove_immediately(int y, int x);               // 直接画面上のカーソルを移動
int mmvprintw(int y, int x, char* str, ...);        // メモリ上のカーソルを移動してメモリ上に文字列を書き込む
int mprintw(char* str, ...);                        // メモリ上に文字列を書き込む

void mattron(int attrs);                // 書き込む文字列の属性を設定
void mattroff();                        // 書き込む文字列の属性の設定を解除

void mbox(int y, int x, int width, int height);     // メモリ上にボックスを描写
void mrefresh();                                    // メモリ上の内容を画面に反映

int mgetmaxx();                 // 画面のサイズ(X方向)
int mgetmaxy();                 // 画面のサイズ(Y方向)
int mis_curses();               // 現在カーシスを起動しているかどうか 1以上: true 0:false

int mgetch(int* meta);          // キーボード入力
int mgetch_nonblock(int* meta); // キーボード入力 入力がなかったら-1を返す

int mkbuf_exist(); // キーボードバッファが存在すれば真を返す

/// 漢字関連関数 /////////////////////////////////////////////////////////////
enum eKanjiCode { kEucjp, kSjis, kUtf8, kUtf8Mac, kAscii, kUnknown };          // 漢字コード
extern enum eKanjiCode gKanjiCode;
extern char* gKanjiCodeString[6];

extern char gKanjiCodeName[5][256];                         // 漢字コードの名前

extern int is_kanji(unsigned char c);           // 引数が漢字一バイト目かどうか
extern int is_hankaku(unsigned char c);         // 引数が半角文字一バイト目かどうか

int str_termlen(char* mbs);         // 引数の文字列が画面で何文字か
int str_termlen2(char* mbs, int utfpos);// mbsをUTF文字列と見たときのutfpos文字目までの端末上での文字列数を返す
int wcs_termlen(wchar_t* wcs);      // 引数の文字列が画面で何文字か
int str_utflen(char* mbs);          // 引数の文字列がUTF上で何文字分か

char* str_utfpos2pointer(char* mbs, int pos);       // mbsをUTF文字列と見たときのpos文字目の位置を返す
int str_pointer2utfpos(char* mbs, char* point);     // mbsをUTF文字列と見たときのpointの場所は何文字目かを返す

void str_cut(char* mbs, int termsize, char* dest_mbs, int dest_byte);       
    // mbsから端末上の文字列分(termsize)のみ残して残りを捨てた文字列をdest_mbsに返す dest_byte: dest_mbsのサイズ
void str_cut2(char* mbs, int termsize, char* dest_mbs, int dest_byte);
    // mbsから端末上の文字列分(termsize)のみ残して残りを捨てた文字列をdest_mbsに返す dest_byte: dest_mbsのサイズ
    // 切り捨てた文字列をスペースで埋める
void str_cut3(char* mbs, int termsize, char* dest_mbs, int dest_byte);
    // mbsから端末上の文字列分(termsize)のみ残して残りを捨てた文字列をdest_mbsに返す dest_byte: dest_mbsのサイズ
    // 切り捨てた文字列をスペースで埋める
    // 切り捨てるのは文字列の前から
void str_cut3_nonutf8(char* mbs, int termsize, char* dest_mbs);
    // str_cut3のeucjp,sjis版

#if defined(HAVE_ICONV_H) || defined(HAVE_BICONV_H)

enum eKanjiCode kanji_encode_type(char* buf);
    // 引数の文字列の漢字エンコードを返す

int kanji_convert(char* input_buf, char* output_buf, size_t output_buf_size, enum eKanjiCode input_kanji_encode_type, enum eKanjiCode output_kanji_encode_type);
    // 漢字エンコードの変換。iconvのラッパー
    // output_bufは十分なスペースが割り当てられている必要がある
    // 返り値は-1はエラー 0は成功

int kanji_convert2(string_obj* input_buf, string_obj* output_buf, enum eKanjiCode input_kanji_encode_type, enum eKanjiCode output_kanji_encode_type);

#endif

int is_all_ascii(char* buf);
    // FALSE:漢字まじり TRUE:全部英数字

#endif

