
#include <stdio.h>
#include <fmc.h>

/*
    mode=0-3: テキスト・グラフィック画面消去
    mode=4  : テキスト画面消去
    mode=5  : グラフィック画面消去
*/
void cls(int mode)
{
        if ((0 <= mode) && (mode <= 3)) printf("\x16");
        if (mode == 4) printf("\x1b[2J");
        if (mode == 5) printf("\x15");
}

/*
   cn: 桁数      ln:行数
*/
void width(int cn, int ln)
{
        char *ps;

        if      ((cn == 40) && (ln == 25))  ps = "0";
        else if ((cn == 40) && (ln == 20))  ps = "1";
        else if ((cn == 80) && (ln == 25))  ps = "2";
        else if ((cn == 80) && (ln == 20))  ps = "3";
        else return;

        printf("\x1b[=%sh", ps);
}

/*
  x, y: 表示位置    sw: カーソルON,OFF  0=OFF,1=ON, 2=NOP
*/
void locate(int x, int y, int sw)
{
        printf("\x1b=");
        putchar(y+' ');
        putchar(x+' ');

        if     (sw == 0) sw = 1;
        else if(sw == 1) sw = 0;
        else return;

        printf("\x1b[");
        putchar(sw+'0');
        printf("v");
}

void cuon()
{
        printf("\x1b[0v");
}

void cuoff()
{
        printf("\x1b[1v");
}

/*
    cl: カラー    bc: バックカラー
*/
void color(int cl, int bc)
{
        if ((cl < 0) || (7< cl)) return;
        if ((bc < 0) || (7< bc)) return;
        
        if      (cl == 1) cl = 4;
        else if (cl == 2) cl = 1;
        else if (cl == 3) cl = 5;
        else if (cl == 4) cl = 2;
        else if (cl == 5) cl = 6;
        else if (cl == 6) cl = 3;

        if      (bc == 1) bc = 4;
        else if (bc == 2) bc = 1;
        else if (bc == 3) bc = 5;
        else if (bc == 4) bc = 2;
        else if (bc == 5) bc = 6;
        else if (bc == 6) bc = 3;

        printf("\x1b[3");
        putchar(cl+'0');
        printf(";4");
        putchar(bc+'0');
        printf("m");
}

void vattr(unsigned int attr)
{
   if (attr > 8) attr = 8;
   printf("\x01b[");
   putchar(attr+'0');
   putchar('m');
}


GraphData GDS_data;
/*
    グラフィック処理 初期設定
*/
void gopen()
{       unsigned worksize=2048, size=500, pattern=0xffff;
        char style=10;
        unsigned char mode=1;
        int ret;

        if ((GDS_open(worksize) < 0) || (GDS_initData(&GDS_data, size) < 0)) {
                printf("メモリー不足\n");
        }
        /* GDS_reset(); */
        ret = GDS_linePattern(&GDS_data, style, pattern);
        ret = GDS_lineStyle(&GDS_data, style);
        ret = GDS_textMode(&GDS_data, mode); /* 文字 */
}

/*
    グラフィック処理 再度初期設定
*/
void greset()
{       unsigned size=500, pattern=0xffff;
        char style=10;
        unsigned char mode=1;
        int ret;

        GDS_reset();
        ret = GDS_linePattern(&GDS_data, style, pattern);
        ret = GDS_lineStyle(&GDS_data, style);
        ret = GDS_textMode(&GDS_data, mode); /* 文字 */
}

/*
    グラフィック処理 終了
*/
void gclose()
{
        int ret;
        
        ret = GDS_close();
}

/*
   グラフィック出力
*/
void gout()
{
    unsigned n, offset;
    int ret;
        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}


void drmode(unsigned mode)
{       int ret;

        ret = GDS_drawMode(&GDS_data, mode);
}



void pset(int x, int y, unsigned cl, unsigned mode)
{
        unsigned n, offset;
        int ret;

        ret = GDS_pointColor(&GDS_data, cl);
        ret = GDS_pointFirst(&GDS_data, x, y);

        ret = GDS_drawMode(&GDS_data, mode);
        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}

/* bf = 0:direct,  1:box,  2:box and paint, 3:box and tile, 4:box and hatch  */
void line(int x1, int y1, int x2, int y2, unsigned mode, unsigned cl, unsigned bf, unsigned ls)
{
        char style=10;
        unsigned int style2=0;
        unsigned n, offset;
        int ret;

        ret = GDS_drawMode(&GDS_data, mode);
        ret = GDS_linePattern(&GDS_data, style, ls);
        ret = GDS_lineColor(&GDS_data, cl);
        
        if (bf == 0) {
                ret = GDS_chainFirst(&GDS_data, x1, y1, x2, y2);
        } else if (bf > 0) {
                style2=bf - 1;
                ret = GDS_fillStyle(&GDS_data, style2);
                ret = GDS_borderColor(&GDS_data, cl);
                ret = GDS_borderStyle(&GDS_data, style);
                ret = GDS_fillColor(&GDS_data, cl);
                ret = GDS_box(&GDS_data, x1, y1, x2, y2);
        }

        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}

/*
     paint
     x, y   : ペイント開始点
     style  : 面塗りモード
              0 : 塗らない
              1 : 塗りつぶし
              2 : タイル塗り
              3 : ハッチング塗り
                                   
     pcl    : 面塗り(塗りつぶし/ハッチング)の色識別番号を指定します｡
     bcn    : 境界色数
     *bcl   : 境界色を格納する配列
*/
void paint(int x, int y, unsigned style, unsigned pcl, unsigned bcn, unsigned *bcl)
{
        unsigned n, offset;
        int ret;

        if (style == 0) return;
        ret = GDS_fillColor(&GDS_data, pcl);
        ret = GDS_fillStyle(&GDS_data, style);
        ret = GDS_paint(&GDS_data, x, y, bcn, bcl);

        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}

void hatch(unsigned style)
{
        int ret;

        ret = GDS_hatchStyle(&GDS_data, style);
}

void tile(unsigned style)
{
        int ret;

        ret = GDS_tileStyle(&GDS_data, style);
}


/*
   symbol
       x , y : 位置        *str : 文字列
       wm    : 横倍率      hm   : 縦倍率   （８ドット）
       cl    : パレットコード
       ac    : 角度コード
       mode  : 機能
*/
void symbol(int x, int y, char *str, int wm, int hm, unsigned cl, unsigned ac, unsigned mode)
{
        int hx, hy, wx, wy, hi;
        unsigned n, offset;
        int ret;
        
        wm *= 2;
        hi = hm * 8;
        

        ret = GDS_drawMode(&GDS_data, mode);
        ret = GDS_textColor(&GDS_data, cl);
        ret = GDS_characterWidth(&GDS_data, wm, hm);
        ret = GDS_characterHeight(&GDS_data, hi);
        
        if (ac == 0) {
                hx = 0; hy = -1;
                wx = 1; wy = 0;
                y += hi;
        } else if (ac == 1) {
                hx = -1; hy = 0;
                wx =  0; wy = -1;
                x += hi;
        } else if (ac == 2) {
                hx =  0; hy = 1;
                wx = -1; wy = 0;
                y -= hi;
        } else if (ac == 3) {
                hx =  1; hy = 0;
                wx =  0; wy = 1;
                x -= hi;
        } else return;
        
        ret = GDS_characterVector(&GDS_data, hx, hy, wx, wy);
        ret = GDS_textPoint(&GDS_data, x, y);
        ret = GDS_text(&GDS_data, str, strlen(str));

        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}


/*
   symbol_
       x , y : 位置        *str : 文字列
       wm    : 横倍率      hm   : 縦倍率   （１６ドット）
       cl    : パレットコード
       ac    : 角度コード
       mode  : 機能
*/
void symbol_(int x, int y, char *str, int wm, int hm, unsigned cl, unsigned ac, unsigned mode)
{
        int hx, hy, wx, wy, hi;
        unsigned n, offset;
        int ret;

        /* wm *= 2; */
        hi = hm * 16;

        ret = GDS_drawMode(&GDS_data, mode);
        ret = GDS_textColor(&GDS_data, cl);
        ret = GDS_characterWidth(&GDS_data, wm, hm);
        ret = GDS_characterHeight(&GDS_data, hi);

        if (ac == 0) {
                hx = 0; hy = -1;
                wx = 1; wy = 0;
                y += hi;
        } else if (ac == 1) {
                hx = -1; hy = 0;
                wx =  0; wy = -1;
                x += hi;
        } else if (ac == 2) {
                hx =  0; hy = 1;
                wx = -1; wy = 0;
                y -= hi;
        } else if (ac == 3) {
                hx =  1; hy = 0;
                wx =  0; wy = 1;
                x -= hi;
        } else return;

        ret = GDS_characterVector(&GDS_data, hx, hy, wx, wy);
        ret = GDS_textPoint(&GDS_data, x, y);
        ret = GDS_text(&GDS_data, str, strlen(str));

        ret = GDS_outputGraph(&GDS_data, &n, &offset);
        ret = GDS_resetData(&GDS_data);
}

