/* # skkinput (Simple Kana-Kanji Input)
 * skkmarker.c --- simulate marker.
 * This file is part of skkinput.
 * Copyright (C) 1997
 * Takashi SAKAMOTO (sakamoto@yajima.kuis.kyoto-u.ac.jp)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with skkinput; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdio.h>

#include "commondef.h"
#include "buffers.h"

/*
 * マーカーの初期化を行う関数。
 */
void markers_init( struct SKKInputNode *node )
{
  int i ;
  for( i = 0 ; i < MAXMARKERNUM ; i ++ ){
    node->markers[ i ].pos = NULL ;
    node->markers[ i ].cf  = False ;
  }
  node->marker_usage = 0 ;
  return ;
}

/*
 * マーカーを登録する関数。
 */
int make_marker( struct SKKInputNode *node, int *marker, int flag )
{
  int i ;
  /* 現在までの使用されているものの中で空いている場所を捜す。*/
  for( i = 0 ; i < node->marker_usage ; i ++ ){
    if( ( node->markers[ i ] ).pos == NULL ){
      /* マーカーを登録。*/
      ( node->markers[ i ] ).pos = marker ;
      ( node->markers[ i ] ).cf  = flag ;
      return 0 ;
    }
  }
  node->marker_usage ++ ;
  /* マーカーバッファを使い切ってしまっていた場合。*/
  if( node->marker_usage >= MAXMARKERNUM )
    return 1 ;
  /* マーカーを登録。*/
  ( node->markers[ i ] ).pos = marker ;
  ( node->markers[ i ] ).cf  = flag ;
  return 0 ;
}

/*
 * マーカーを消去する関数。
 */
int delete_marker( struct SKKInputNode *node, int *marker )
{
  int i ;
  /* 現在までの使用されているものの中から。*/
  for( i = 0 ; i < node->marker_usage ; i ++ ){
    /* 消去すべきマーカーか？ */
    if( ( node->markers[ i ] ).pos == marker ){
      /* マーカーを抹消。*/
      ( node->markers[ i ] ).pos = NULL ;
      return 0 ;
    }
  }
  /* そんなマーカーは登録されていない。*/
  return 1 ;
}

/*
 * マーカーを移動させる関数。
 *----
 * テキスト内に文字列を挿入することによって、マーカーの移動が生じた場合に
 * 利用する。copy_region などがその利用例であらう。
 *----
 * startpoint より右にあるマーカーは全て影響を受ける。
 */
int move_marker_ByInsert
( struct SKKInputNode *node, int startpoint, int effect )
{
  int i ;
  struct Marker *mks = node->markers ;

  /* 現在までの使用されているものの中から。*/
  for( i = 0 ; i < node->marker_usage ; i ++ ){
    /* 影響を受けるマーカーか？ */
    if( *( mks[ i ].pos ) > ( startpoint - mks[ i ].cf ) ){
      /* マーカーを移動させる。*/
      *( mks[ i ].pos ) += effect ;
      /* マーカーがテキストから飛び出してしまう場合。*/
      if( *( mks[ i ].pos ) >= TEXTMAXLEN )
	*( mks[ i ].pos ) = TEXTMAXLEN ;
    }
  }
  return 0 ;
}

/*
 * マーカーを移動させる関数。
 *----
 * テキスト内から文字列を抜き出すことによって生じるマーカーの移動に
 * 利用する。delete_region などがその利用例であらう。
 *----
 * startpoint より右にあるマーカーは全て影響を受ける。
 */
int move_marker_ByDeleteRegion
( struct SKKInputNode *node, int startpoint, int endpoint )
{
  int i ;
  int diff = endpoint - startpoint ;
  struct Marker *markers = node->markers ;

  /* 現在までの使用されているものの中から。*/
  for( i = 0 ; i < node->marker_usage ; i ++ ){
    /* 影響を受けるマーカーか？ */
    if( *( markers[ i ].pos ) <= startpoint )
      continue ;
    if( *( markers[ i ].pos ) >= endpoint ){
      /* マーカーを移動させる。*/
      *( markers[ i ].pos ) -= diff ;
    } else {
      /* マーカーを移動させる。*/
      *( markers[ i ].pos ) = startpoint ;
    }
  }
  return 0 ;
}

/*
 * マーカーを移動させる関数。
 *----
 * テキストの後の方の文字列が切れてしまった時に、そこを指すマーカーが
 * 生きているとまずいので、移動させるのに使う関数。
 *----
 * startpos より右にあるマーカーは全て影響を受ける。
 */
int set_marker_ByGeqPosition
( struct SKKInputNode *node, int startpos, int setpos )
{
  int i ;
  struct Marker *markers = node->markers ;

  /* 現在までの使用されているものの中から。*/
  for( i = 0 ; i < node->marker_usage ; i ++ ){
    /* 影響を受けるマーカーか？ */
    if( *( markers[ i ].pos ) <= startpos )
      continue ;
    /* マーカーを移動させる。*/
    *( markers[ i ].pos ) = setpos ;
  }
  return 0 ;
}
