Message "[Including <pan>]";
System_file;
! Better comments before routines will be added when this is official, but
! both work fine. However, note that even with scroll (which is mainly
! intended for graphic text), the picture should be wider than the window.

! Programming is the same as discussed in unglklib. In HandleGlkEvent() have:

! if (effect_counter == NULL) StopGlkTimer();
! else effect_counter = Pan(gg_mywin, effect_counter, my_pic, 0, 0, 10);

! I only use two effect counters in Vistas, since most routines are stopped
! before another is started. I also do the tedious job of having big_pic
! also declared (or small_pic for the small window) just in case the player
! undoes/restarts/restores. Using global variables to keep track of what is
! the current picture in each window is really the only way to keep things
! current for undo/restart/restore (yes, an array could be used too, but I
! think that adds an unneeded level of complexity.) Because the counter is
! set to NULL to stop the timer, big_pic and counter cannot be the same,
! plus, pic == 0 could/should have different actions.

! if (effect_counter == NULL) StopGlkTimer();
! else
! { big_pic = my_pic;
!   effect_counter = Pan(gg_mywin, effect_counter, my_pic, 0, 0, 10);
! }

! I discovered in Windows Glulxe that changing the default font for the main
! text window (one of the interpreter's menu selections), forces a graphic
! redraw, so it's an easy way to test if the current pic *is* current.

! As mentioned before, this is the basic draw graphic procedure that
! one should have in HandleGlkEvent() and IdentifyGlkObject() for redraws.

! [ DrawMyGraphics;
!
!  if (big_pic)
!     DrawWinGraphic(gg_bigwin, big_pic);
!  else ClearWindow(gg_bigwin);
!  if (small_pic)
!     DrawWinGraphic(gg_smallwin, small_pic);
!  else ClearWindow(gg_smallwin);
!];

! Now the code.

[ Pan  win count pic dir topleft portion
       pic_width pic_height win_width win_height diff_width diff_height x y;
! win     = window to use         {global variable}
! count   = count of current pass {global variable}
! pic     = picture to pan
! dir     = direction to pan
!           0 = left to right
!           1 = right to left
!           2 = top to bottom
!           3 = bottom to top
! topleft = which side of picture to use
!           (for normal left to right or top to bottom pan, leave 0)
!           0 = top or left side of pic
!           1 = bottom or right side of pic
!           (used in conjunction with direction)
!
!    topleft     0 = top or left               1 = bot or right
!    dir       ------------------------------------------------------------
!    0 = left  | pan top of pic left         | pan bot of pic left        |
!              |----------------------------------------------------------|
!    1 = right | pan top of pic right        | pan bot of pic right       |
!              |-----------------------------------------------------------
!    2 = down  | pan left side of pic down   | pan right side of pic down |
!              |-----------------------------------------------------------
!    3 = up    | pan left side of pic up     | pan right side of pic up   |
!              ------------------------------------------------------------

! portion = number of times to divide window for pan, i.e. portion of window
!           to use for pan (even number is best, such as:  4, 8, 16;
!           4 = 1/4, 8 = 1/8, 16 = 1/16)

  if (win == 0) return NULL;
  if (~~(IsWinGraphic(win))) return NULL;
  if (~~(SupportsGlkTimer())) return NULL;
  if (pic == 0) return NULL;
  if (count == NULL) return NULL;

  ClearWindow(win);
  GetGraphicInfo(pic, gg_arguments, gg_arguments+WORDSIZE);
  pic_width   = gg_arguments-->0;
  pic_height  = gg_arguments-->1;
  GetWindowSize(win, gg_arguments, gg_arguments+WORDSIZE);
  win_width   = gg_arguments-->0;
  win_height  = gg_arguments-->1;
  diff_width  = pic_width  - win_width;
  diff_height = pic_height - win_height;

  ! Uses minus numbers to essentially draw pic outside of window -- this
  ! is the way it can pan.

  switch(dir)
  { 0, 1 : if (dir == 0)
           { if (count == 1) x = 0;
             else x = -((diff_width / portion) * (count-1));
           } else
           { if (count == 1) x = -diff_width;
             else x = (-diff_width) + ((diff_width / portion) * (count-1));
           }
           if (topleft == 0) y = 0; else y = -diff_height;
    2, 3 : if (dir == 2)
           { if (count == 1) y = 0;
             else y = -((diff_height / portion) * (count-1));
           } else
           { if (count == 1) y = -diff_height;
             else y = (-diff_height) + ((diff_height / portion) * (count-1));
           }
           if (topleft == 0) x = 0; else x = -diff_width;
  }

  DrawGraphic(win, pic, x, y);

  count++;
  if (count > portion) return NULL;
  return count;

];

[ Scroll  win count pic dir portion
          pic_width pic_height win_width win_height center_width diff_height x y;
! win     = window to use         {global variable}
! count   = count of current pass {global variable}
! pic     = picture to pan
! dir     = direction to pan (picture is centered in window)
!           0 = top to bottom
!           1 = bottom to top
! portion = number of times to divide window for scroll, i.e. portion of window
!           to use for scroll (even number is best, such as:  4, 8, 16;
!           4 = 1/4, 8 = 1/8, 16 = 1/16)

  if (win == 0) return NULL;
  if (~~(IsWinGraphic(win))) return NULL;
  if (~~(SupportsGlkTimer())) return NULL;
  if (pic == 0) return NULL;
  if (count == NULL) return NULL;

  ClearWindow(win);
  GetGraphicInfo(pic, gg_arguments, gg_arguments+WORDSIZE);
  pic_width    = gg_arguments-->0;
  pic_height   = gg_arguments-->1;
  GetWindowSize(win, gg_arguments, gg_arguments+WORDSIZE);
  win_width    = gg_arguments-->0;
  win_height   = gg_arguments-->1;
  center_width = (pic_width  - win_width) / 2;
  diff_height  = pic_height - win_height;

  x = -center_width;
  switch(dir)
  { 0 : if (count == 1) y = 0;
        else y = -((diff_height / portion) * (count-1));
    1 : if (count == 1) y = -diff_height;
        else y = (-diff_height) + ((diff_height / portion) * (count-1));
  }

  DrawGraphic(win, pic, x, y);

  count++;
  if (count > portion) return NULL;
  return count;

];

! You also need these wrappers which I have already added to unglklib.

! --- GetGraphicInfo(pic, widthptr, heightptr); **

! Gets information about a graphic. Note the ptr suffix on arguments -- this
! means the size, width & height, are actually passed to the global array,
! gg_arguments.

[ GetGraphicInfo pic widthptr heightptr;
! pic        = graphic to get size of
! widthptr   = width of window
! heightptr  = height of window

  return glk_image_get_info(pic, widthptr, heightptr);
];

! --- DrawGraphic(win, pic, x, y); *

! Draw a graphic in a graphic or text buffer window. (Although this is going
! to have some added comments.)

[ DrawGraphic win pic x y;
! win    = window to use   {global variable}
! pic    = current picture {global variable}
! x      = x pos at which to draw pic
! y      = y pos at which to draw pic

  return glk_image_draw(win, pic, x, y);
];

