/*{{{  #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>

#include <local/bool.h>

#define FOLDHELP_C
#define I_DISPLAY_C
#define I_FOLDING_C
#define I_GETMSG_C
#define I_ORIEDT_C
#define I_PROMPT_C
#define I_SCREEN_C

#include "origami.h"
#include "macros.h"
/*}}}  */

/*{{{  to_start*/
public int to_start(int m)
{
  int dist_to_start;
  element *p;

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

  dist_to_end = 0;
  p = current;
  while (p != tail && dist_to_end <= m) {
    dist_to_end++;
    p = p->next;
  }
  return dist_to_end;
}
/*}}}  */
/*{{{  move_down*/
public void move_down(void)
{
  if (current == tail) {
    vmessage(get_msg(M_BOTTOM));
    return;
  }
  current = current->next;
  if (cursor_level > (SCREEN_LEN-2) && screen_end != tail)
    restore_element(SCREEN_LEN/2);
  else {
    cursor_level++;
    if (dirty) restore(1);
  }
}
/*}}}  */
/*{{{  move_up*/
public void move_up(void)
{
  if (current->prec == head) {
    vmessage(get_msg(M_TOP));
    return;
  }
  current = current->prec;
  if (screen_start->prec != head && cursor_level < 3)
    restore_element(SCREEN_LEN/2);
  else {
    cursor_level--;
    if (dirty) restore(1);
  }
}
/*}}}  */
/*{{{  sub_move_up*/
private void sub_move_up(void)
{
  if (current->prec == head) return;
  current = current->prec;
}
/*}}}  */
/*{{{  sub_move_down*/
private void sub_move_down(void)
{
  if (current == tail) return;
  current = current->next;
}
/*}}}  */
/*{{{  top*/
public void top(void)
{
  int dist_to_top, far_;

  far_ = cursor_level + 4;
  dist_to_top = to_start(far_);
  if (dist_to_top < far_) {
    while (current != head->next)
      move_up();
    return;
  }
  if (select_on) {
    while (current != head->next)
      sub_move_up();
  } else
    current = head->next;
  restore_element(4);
}
/*}}}  */
/*{{{  bottom*/
public void bottom(void)
{
  int dist_to_bottom, far_;

  far_ = SCREEN_LEN - cursor_level + 4;
  dist_to_bottom = to_bottom(far_);
  if (dist_to_bottom < far_) {
    while (current != tail)
      move_down();
    return;
  }
  if (select_on) {
    while (current != tail)
      sub_move_down();
  }
  else
    current = tail;
  restore_element(4);
}
/*}}}  */
/*{{{  undelete_before*/
public void undelete_before(element *ptr_to_new)
{
  insert_link_before(ptr_to_new);
  if (screen_end_level == SCREEN_LEN) screen_end = screen_end->prec; else screen_end_level++;
  if (cursor_level < SCREEN_LEN) down_a_bit(cursor_level); else goclreol(1,SCREEN_LEN);
  write_dsp_line(current, cursor_level);
  if (dirty) restore(cursor_level);
}
/*}}}  */
/*{{{  undelete_pick_before*/
public void undelete_pick_before(void)
{
  element *p, *sf, *ef;

  proc_new(&ef);
  join_links(pick_tail, ef);
  p = pick_head->next;
  proc_new(&sf);
  join_links(pick_head, sf);
  join_links(sf, p);
  sf->foldline = START_FOLD;
  sf->fold = sf->next;
  sf->other_end = ef;
  ef->foldline = END_FOLD;
  ef->other_end = sf;
  undelete_before(sf);
  pick_tail = pick_head;
}
/*}}}  */
/*{{{  undelete_after*/
public void undelete_after(element *ptr_to_new)
{
  element *ptr_to_next;


  /*note current<>tail*/
  ptr_to_next = current->next;
  join_links(current, ptr_to_new);
  join_links(ptr_to_new, ptr_to_next);
  if (cursor_level == SCREEN_LEN)
   { screen_end = screen_end->prec;
     whole_screen_up();
   }
  else
   { if (screen_end_level == SCREEN_LEN) screen_end = screen_end->prec;
     else screen_end_level++;
     down_a_bit(cursor_level+1);
     write_dsp_line(ptr_to_new, cursor_level + 1);
   }
  move_down();
}
/*}}}  */
/*{{{  pre_remove_line*/
public void pre_remove_line(element **p)
{
  element *prec_ptr;

  *p = current;
  prec_ptr = current->prec;
  if (screen_start == current)
    screen_start = current->next;
  current = current->next;
  join_links(prec_ptr, current);
}
/*}}}  */
