/*{{{}}}*/
/*{{{  #includes*/
#ifdef CONFIG_H
#   include "config.h"
#endif

#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define FOLDHELP_C
#define I_LOOP_C
#define I_DISPLAY_C
#define I_FINDS_C
#define I_FOLDING_C
#define I_GETMSG_C
#define I_GETTK_C
#define I_ORIEDT_C
#define I_PROMPT_C
#define I_SCREEN_C

#include "origami.h"
#include <lib/ori_add_lib.h>
/*}}}  */

/*{{{  check_fold*/
public void check_fold(element * const p)
{ bd.f.Start_of_fold=p;
  bd.f.End_of_fold = bd.f.Start_of_fold->x.fold.other_end;
  bd.f.Line_after_fold = bd.f.Start_of_fold->next;
  bd.f.End_of_fold->next = bd.f.Line_after_fold;
}
/*}}}  */
/*{{{  to_start*/
public int to_start(int const m)
{
  int dist_to_start;
  element const *p;

  dist_to_start = 1;
  p = bd.f.current;
  while (p != bd.f.head->next && dist_to_start <= m)
   { dist_to_start++;
     p = p->prec;
   }
  return dist_to_start;
}
/*}}}  */
/*{{{  to_bottom*/
public int to_bottom(int const m)
{
  int dist_to_end;
  element const *p;

  dist_to_end = 0;
  p = bd.f.current;
  while (p != bd.f.tail && dist_to_end <= m)
   { dist_to_end++;
     p = p->next;
   }
  return dist_to_end;
}
/*}}}  */
/*{{{  move_down*/
public void move_down(void)
{
  boolean do_highlight;

  if (bd.f.current == bd.f.tail)
   /*{{{  complain and return*/
   { verbose_msg_message(M_BOTTOM);
     return;
   }
   /*}}}  */
  /*{{{  move, count lines and handle status line*/
  ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  title_op((bd.f.cur_line_typ&(START_FOLD|START_FILED))?CHGXY:INCY);
  bd.f.current = bd.f.current->next;
  bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  do_highlight=   (bd.m.select_mode!=no_selection)
               && upd_highlight(bd.f.real_head,bd.f.real_tail,False);
  if (!(bd.f.cur_line_typ&NOT_FOLD) && bd.f.count_comment_line)
     title_op(CHGXY);
  /*}}}  */
 /*{{{  update screen*/
 /*{{{  scroll or redraw*/
  if (bd.scr.cursor.h > (bd.scr.txt_size.h-2) && bd.scr.end != bd.f.tail)
     if (!(al && dl))
      { restore_element(bd.scr.txt_size.h/2);
        return;
      }
     else
        for
         ( bd.scr.cursor.h++
         ; bd.scr.cursor.h>bd.scr.txt_size.h/2
         ;
         )
         { int y;

           y=bd.scr.cursor.h;
           whole_screen_up();
           if (y==bd.scr.cursor.h)
              break;
         }
 else
    bd.scr.cursor.h++;
 /*}}}  */
 if (do_highlight)
  /*{{{  correct highlighting of changed line*/
  { write_dsp_line(bd.f.current->prec,bd.scr.cursor.h-1);
    write_dsp_line(bd.f.current,bd.scr.cursor.h);
  }
  /*}}}  */
 /*}}}  */
}
/*}}}  */
/*{{{  move_up*/
public void move_up(void)
{
  boolean do_highlight;

  if (bd.f.current->prec == bd.f.head)
   /*{{{  complain and return*/
   { verbose_msg_message(M_TOP);
     return;
   }
   /*}}}  */
  /*{{{  go up, count lines and show status line*/
  ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  if (bd.f.count_comment_line && !(bd.f.cur_line_typ&NOT_FOLD))
     title_op(CHGXY);
  bd.f.current = bd.f.current->prec;
  bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  do_highlight=   (bd.m.select_mode!=no_selection)
               && upd_highlight(bd.f.real_head,bd.f.real_tail,False);
  title_op((bd.f.cur_line_typ&(START_FOLD|START_FILED))?CHGXY:DECY);
  /*}}}  */
  /*{{{  update screen*/
  /*{{{  scroll or redraw*/
  if (bd.scr.start->prec != bd.f.head && bd.scr.cursor.h < 3)
     if (!(al && dl))
      { restore_element(bd.scr.txt_size.h/2);
        return;
      }
     else
      /*{{{  scroll screen*/
        for
         ( bd.scr.cursor.h--
         ; bd.scr.cursor.h<bd.scr.txt_size.h/2
         ;
         )
         { int y;
        
           y=bd.scr.cursor.h;
           whole_screen_down();
           if (y==bd.scr.cursor.h)
              break;
         }
      /*}}}  */
  else
     bd.scr.cursor.h--;
  /*}}}  */
  if (do_highlight)
   /*{{{  correct changed line*/
   { write_dsp_line(bd.f.current->next,bd.scr.cursor.h+1);
     write_dsp_line(bd.f.current,bd.scr.cursor.h);
   }
   /*}}}  */
  /*}}}  */
}
/*}}}  */
/*{{{  skip_to*/
public void skip_to(element * const line)
{
  int level;

  if ((level=on_screen(line)))
   { void (*op)();

     op=(level>bd.scr.cursor.h)?move_down:move_up;
     while (bd.f.current!=line)
        op();
   }
  else
   { bd.f.cur_line_typ=get_linetyp(*(bd.f.current=line));
     title_op(CHGXY);
     if (bd.m.select_mode)
        upd_highlight(bd.f.real_head,bd.f.real_tail,True);
     restore_element(DEF_CURSOR_LINE);
   }
  ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
}
/*}}}  */
/*{{{  undel_before*/
public void undel_before(element * const ptr_to_new)
{
  insert_link_before(ptr_to_new);
  if (bd.scr.end_level == bd.scr.txt_size.h)
     bd.scr.end = bd.scr.end->prec;
  else
     bd.scr.end_level++;
  if (bd.scr.cursor.h < bd.scr.txt_size.h)
     down_a_bit(bd.scr.cursor.h);
  else
     clrbuffline(bd.scr.txt_size.h,1);
  write_dsp_line(bd.f.current, bd.scr.cursor.h);
}
/*}}}  */
/*{{{  undel_pick_before*/
public void undel_pick_before(void)
{
  element *p, *sf, *ef;

  ef=proc_new_element();
  join_links(pick_tail, ef);
  p = pick_head->next;
  sf=proc_new_element();
  join_links(pick_head, sf);
  join_links(sf, p);
  set_linetyp(*sf,START_FOLD);
  sf->x.fold.data = sf->next;
  sf->x.fold.other_end = ef;
  set_linetyp(*ef,END_FOLD);
  ef->x.fold.other_end = sf;
  undel_before(sf);
  pick_tail = pick_head;
  ocl_var[var_kill_count].v--;
}
/*}}}  */
/*{{{  append_to_pick*/
public void append_to_pick(element * const pick_ptr)
 {
   if (pick_ptr)
    { join_links(pick_tail,pick_ptr);
      pick_ptr->indent = 0;
      pick_tail=pick_ptr;
      ocl_var[var_kill_count].v++;
    }
 }
/*}}}  */
/*{{{  undel_after*/
public void undel_after(element * const ptr_to_new)
{
  element *ptr_to_next;

  /*note bd.f.current<>bd.f.tail*/
  ptr_to_next = bd.f.current->next;
  join_links(bd.f.current, ptr_to_new);
  join_links(ptr_to_new, ptr_to_next);
  if (bd.scr.cursor.h == bd.scr.txt_size.h)
   { bd.scr.end = bd.scr.end->prec;
     whole_screen_up();
   }
  else
   { if (bd.scr.end_level == bd.scr.txt_size.h)
        bd.scr.end = bd.scr.end->prec;
     else
        bd.scr.end_level++;
     down_a_bit(bd.scr.cursor.h+1);
     write_dsp_line(ptr_to_new, bd.scr.cursor.h + 1);
   }
  move_down();
}
/*}}}  */
/*{{{  pre_remove_line*/
public void pre_remove_line(element ** const p)
{
  element *prec_ptr;

  *p = bd.f.current;
  prec_ptr = bd.f.current->prec;
  if (bd.scr.start == bd.f.current)
     bd.scr.start = bd.f.current->next;
  bd.f.current = bd.f.current->next;
  join_links(prec_ptr, bd.f.current);
}
/*}}}  */
