#include<stdio.h>
#include<X11/Xlib.h>

#include"xyag.h"

#define MAX_NODE 1024       /* １オブジェクト当たりの点の最大数 */

static XPoint Point[1024];  /* 編集中のオブジェクトの点の座標 */
static int Num_node;        /* 編集中のオブジェクトの点の数   */

static obj_t  *Cur_obj;     /* ページ内の最終オブジェクト */

static int Sx,Sy;           /* 補助線の終端座標         */
static int Xor_state = 0;   /* 補助線を表示しているか？ */


/* 補助線を消す */

void del_xor( void )
{
  if( Xor_state == 0 )
    return;

  XDrawLine( Disp,Scr_p,Gc_xor,
	    Point[Num_node-1].x,Point[Num_node-1].y,Sx,Sy );

  XDrawLine( Disp,Scr_w,Gc_xor,
	    Point[Num_node-1].x,Point[Num_node-1].y,Sx,Sy );

  Xor_state = 0;
}


/* 補助線を描く */

void draw_xor( int x, int y )
{
  if( Xor_state )
    del_xor();

  XDrawLine( Disp,Scr_p,Gc_xor,Point[Num_node-1].x,Point[Num_node-1].y,x,y );
  XDrawLine( Disp,Scr_w,Gc_xor,Point[Num_node-1].x,Point[Num_node-1].y,x,y );

  Sx = x;
  Sy = y;
  Xor_state = 1;
}


/* オブジェクト編集開始 */

void set_point( int x, int y )
{
  Num_node = 1;
  Point[0].x = x;
  Point[0].y = y;
}


/* オブジェクトの経由する点の指定 */

void next_point( int x, int y )
{
  if( Num_node == 1024 )
    return;

  del_xor();

  Point[Num_node].x = x;
  Point[Num_node].y = y;

  Gc = Gc_fg;
  XDrawLine(Disp,Scr_p,Gc,Point[Num_node-1].x,Point[Num_node-1].y,x,y );
  XDrawLine(Disp,Scr_w,Gc,Point[Num_node-1].x,Point[Num_node-1].y,x,y );

  Num_node++;
}


/* オブジェクトの点の消去（実行後のモードを返す） */

int prev_point( void )
{
  del_xor();

  if( Num_node == 1 )
    return 0;

  Num_node--;


  XDrawLine( Disp,Scr_p,Gc_bg,
	    Point[Num_node-1].x,Point[Num_node-1].y,
	    Point[Num_node].x,Point[Num_node].y );

  XDrawLine( Disp,Scr_w,Gc_bg,
	    Point[Num_node-1].x,Point[Num_node-1].y,
	    Point[Num_node].x,Point[Num_node].y );

  Option.changed = True;
  return 1;
}


/* オブジェクトの終点を決める */

void cut_point( void )
{
  obj_t *p;
  XPoint *q;

  q = (XPoint*)XtCalloc( Num_node,sizeof(XPoint) );

  p = (obj_t*)XtMalloc( sizeof(obj_t) );

  del_xor();

  Cur_obj->next = p;
  p->prev = Cur_obj;
  p->next = NULL;

  bcopy( Point,q,sizeof(XPoint) * Num_node );
  p->data = q;
  p->length = Num_node;

  Cur_obj = p;

  Option.changed = True;
}


/* オブジェクト消去 */

void del_obj( void )
{
  obj_t *p;

  if( Cur_obj == &Cur_page->data_head )
    return;

  p = Cur_obj;
  Cur_obj = Cur_obj->prev;
  Cur_obj->next = NULL;
  free( p );

  Option.changed = True;
  change_page();
}


/* ページ切替え */

void change_page( void )
{
  clear_scr();
  Xor_state = 0;

  if( Option.see_next && Cur_page->next != NULL ){
    Gc = Gc_next;
    draw_page( Cur_page->next );
  }

  if( Option.see_prev && Cur_page->prev != &Head_page ){
    Gc = Gc_prev;
    draw_page( Cur_page->prev );
  }

  Gc = Gc_fg;
  draw_page( Cur_page );

  flush_scr();

  Cur_obj = &Cur_page->data_head;

  while( Cur_obj->next != NULL )
    Cur_obj = Cur_obj->next;

  number_page();
}


/* 全オブジェクト消去 */

void clear_page( void )
{
  obj_t *p,*q;

  p = Cur_page->data_head.next;
  while( p != NULL ){
    free( p->data );
    q = p;
    p = p->next;
    free( q );
  }
  Cur_page->data_head.next = NULL;
  change_page();
  Option.changed = True;
}  


/* ページ消去 */

void del_page( void )
{
  page_t *r;

  clear_page();

  if( Cur_page->prev != Cur_page->next ){
    r = Cur_page;

    Cur_page->prev->next = Cur_page->next;
    Cur_page->next->prev = Cur_page->prev;

    if( Cur_page->next != &Head_page )
      Cur_page = Cur_page->next;
    else{
      Cur_page = Cur_page->prev;
      Option.page--;
    }

    free( r );

    Option.page_max--;
    change_page();
    Option.changed = True;
  }else
    Option.changed = False;
}


/* ページ追加（カレントページの前に追加） */

void ins_page(void )
{
  page_t *p;

  p = (page_t*)XtMalloc( sizeof(page_t) );

  p->data_head.next = NULL;

  p->prev = Cur_page->prev;
  p->next = Cur_page;
  Cur_page->prev->next = p;
  Cur_page->prev = p;

  Cur_page = p;

  Option.page_max++;
  change_page();

  Option.changed = True;
}


/* ページ追加（カレントページの後に追加） */

void add_page( void )
{
  page_t *p;

  p = (page_t*)XtMalloc( sizeof(page_t) );

  p->data_head.next = NULL;

  p->next = Cur_page->next;
  p->prev = Cur_page;
  Cur_page->next->prev = p;
  Cur_page->next = p;

  Cur_page = p;

  Option.page++;
  Option.page_max++;

  change_page();

  Option.changed = True;
}


/* 前ページ */

void prev_page( void )
{
  if( Cur_page->prev != &Head_page ){
    Cur_page = Cur_page->prev;
    Option.page--;
    change_page();
  }
}


/* 次ページ */

void next_page( void )
{
  if( Cur_page->next != &Head_page ){
    Cur_page = Cur_page->next;
    Option.page++;
    change_page();
  }
}


/* 初期化 */

void init_page( void )
{
  page_t *p;

  p = (page_t*)XtMalloc( sizeof(page_t) );

  Head_page.next = p;
  Head_page.prev = p;

  Cur_page = p;
  Cur_page->prev = &Head_page;
  Cur_page->next = &Head_page;
  Cur_page->data_head.next = NULL;
  Cur_page->data_head.prev = NULL;

  Option.page = 1;
  Option.page_max = 1;
  Option.changed = False;

  change_page();
}
