import java.awt.*;
import java.util.*;

public class book extends java.applet.Applet implements Runnable {
 Image offscreenImage, pageContents;
 Graphics offscreen;
 Thread runner;
 Color bgColor, bdColor, pgColor, txColor, hdColor;
 Color[] color = new Color[10];
 Font[] font = new Font[10];
 FontMetrics[] metrics = new FontMetrics[10];
 String head;
 int pgwidth, pgheight, bdwidth, x0, y0, ax, ay, ax0, ay0, pgnumber, curr, targ, press;

 public void init() {
  String param;

  param = getParameter("pgnumber");
  pgnumber = (param == null) ? 20 : Integer.parseInt(param);
  if(pgnumber < 1) pgnumber = 20;
  pgnumber += pgnumber%2;

  param = getParameter("startpg");
  curr = (param == null) ? 2 : Integer.parseInt(param);
  if(curr < 1 || curr > pgnumber) curr = 2;
  curr += curr%2;

  param = getParameter("pgwidth");
  pgwidth = (param == null) ? 200 : Integer.parseInt(param);
  if(pgwidth < 1) pgwidth = 200;

  param = getParameter("pgheight");
  pgheight = (param == null) ? 300 : Integer.parseInt(param);
  if(pgheight < 1) pgheight = 300;

  param = getParameter("bdwidth");
  bdwidth = (param == null) ? 2 : Integer.parseInt(param);
  if(bdwidth < 0) bdwidth = 2;

  param = getParameter("bgcolor");
  if(param==null) param="255,255,255";
  int red = Integer.parseInt(getParam(0,param));
  int green = Integer.parseInt(getParam(1,param));
  int blue = Integer.parseInt(getParam(2,param));
  bgColor = new Color(red,green,blue);

  param = getParameter("bdcolor");
  if(param==null) param="0,0,0";
  red = Integer.parseInt(getParam(0,param));
  green = Integer.parseInt(getParam(1,param));
  blue = Integer.parseInt(getParam(2,param));
  bdColor = new Color(red,green,blue);

  param = getParameter("pgcolor");
  if(param==null) param="255,255,255";
  red = Integer.parseInt(getParam(0,param));
  green = Integer.parseInt(getParam(1,param));
  blue = Integer.parseInt(getParam(2,param));
  pgColor = new Color(red,green,blue);

  for(int i = 0; i < 10; i++) {
   param = getParameter("c" + i);
   if(param==null) param="0,0,0";
   red = Integer.parseInt(getParam(0,param));
   green = Integer.parseInt(getParam(1,param));
   blue = Integer.parseInt(getParam(2,param));
   color[i] = new Color(red,green,blue);
  }

  for(int i = 0; i < 10; i++) {
   param = getParameter("f" + i);
   if(param==null) param="TimesRoman,plain,12";
   String Style = getParam(1, param);
   int style = Style.equalsIgnoreCase("bold") ? Font.BOLD :
    (Style.equalsIgnoreCase("italic") ? Font.ITALIC : Font.PLAIN);
   font[i] = new Font(getParam(0, param), style, Integer.parseInt(getParam(2, param)));
   metrics[i] = getFontMetrics(font[i]);
  }

  head = getParameter("head");
  if(head==null) head = "Use arrow keys, enter page number or click page numbers.";

  offscreenImage = createImage(size().width, size().height);
  offscreen = offscreenImage.getGraphics();

  requestFocus();

 }

 public void start() {
  if (runner == null) {
   runner = new Thread(this);
   runner.start();
  }
 }

 public void stop() {
  if (runner != null) {
   runner = null;
  }
 }

 public void run() {

  x0 = (size().width - pgnumber*bdwidth - 2*pgwidth)/2;
  y0 = (size().height - pgheight - (pgnumber - 1)*bdwidth)/2;
  press = 0;
  targ = 0;

  repaint();

  Thread thisThread = Thread.currentThread();
  while (runner == thisThread) {

   if(press == 1004) {
    curr = pgnumber;
    head = "";
    repaint();
    targ = 0;
    press = 0;
   }

   if(press == 1005) {
    curr = 2;
    head = "";
    repaint();
    targ = 0;
    press = 0;
   }

   if((press == -1 || press == 1006) && curr > 2) {
    curr -= 2;
    head = "";
    repaint();
    targ = 0;
    press = 0;
   }

   if((press == 1 || press == 1007) && curr < pgnumber) {
    curr += 2;
    head = "";
    repaint();
    targ = 0;
    press = 0;
   }

   if(press > 47 && press < 58) {
    if(targ == 0) targ = (press - 48);
    else targ = targ*10 + (press - 48);
    if(targ > pgnumber) targ = 0;
    head = "";
    repaint();
    press = 0;
   }

   if(press == 10) {
    if(targ >= 1 && targ <= pgnumber)  curr = targ + targ%2;
    head = "";
    repaint();
    targ = 0;
    press = 0;
   }

  }

 }

 public boolean keyDown(Event evt, int key) {
  if(key == 10) press = key;
  if(key > 47 && key < 58) press = key;
  if(key > 1003 && key < 1008) press = key;
  return true;
 }

 public boolean mouseDown(Event evt, int x, int y) {
  if(y > size().height - y0 && y < size().height - y0 + metrics[0].getHeight()) {
   if(x > x0 && x < x0 + pgwidth) {
    press = -1;
   }
   if(x > x0 + pgwidth + (pgnumber - 1)*bdwidth && x < x0 + 2*pgwidth + (pgnumber - 1)*bdwidth) {
    press = 1;
   }
  }
  return true;
 }

 public String getParam(int arg, String param) {
  int num=1, i, start=0, end=0;

  for(i=0;i<param.length();i++) if(param.charAt(i)==',') num++; //number of arguments

  for(i=0; i<arg; i++) start = param.indexOf(',', start)+1;     //start is the index after                                                                     comma # argument
  if(arg!=num-1) end = param.indexOf(',', start);               //end is the index of comma                                                                    # argument+1
  else end = param.length();                                    //end is the last index for                                                                    the last argument
  return param.substring(start, end);                           //returns string between                                                                       commas
 }

 public Image drawPage(int i) {
  int delta, x1, x2, a;

  if(i%2 == 0) {
   delta = (pgnumber - i)*bdwidth;
   x1 = 0;
   x2 = 0;
   a = 90;
  }
  else {
   delta = (i - 1)*bdwidth;
   x1 = (pgwidth - delta);
   x2 = (pgwidth - 2*delta);
   a = 0;
  }

  Image offscreenPage = createImage(pgwidth, pgheight + delta);
  Graphics page = offscreenPage.getGraphics();

  page.setColor(pgColor);
  page.fillRect(0, 0, pgwidth, pgheight + delta);
  page.setColor(bdColor);
  page.fillRect(0, 0, pgwidth, pgheight);
  page.setColor(pgColor);
  page.fillRect(bdwidth, bdwidth, pgwidth - 2*bdwidth, pgheight - 2*bdwidth);

  page.setColor(bgColor);
  page.fillRect(x1, 0, delta, delta);
  page.setColor(bdColor);
  page.fillArc(x2, 0, 2*delta, 2*delta, a, 90);
  page.setColor(pgColor);
  page.fillArc(x2 + bdwidth, bdwidth, 2*(delta - bdwidth), 2*(delta - bdwidth), a, 90);

  page.setColor(bdColor);
  page.fillRect(x1, pgheight - bdwidth, delta, delta);
  page.setColor(pgColor);
  page.fillRect(x1 + bdwidth, pgheight - 2*bdwidth, delta - 2*bdwidth, delta - 2*bdwidth);
  page.setColor(bdColor);
  page.fillArc(x2, pgheight - bdwidth, 2*delta, 2*delta, a, 90);
  page.setColor(pgColor);
  page.fillArc(x2 + bdwidth, pgheight, 2*(delta - bdwidth), 2*(delta - bdwidth), a, 90);

  String name = getParameter("img" + i);
  if(name != null && load(name)) {
   int width = pageContents.getWidth(this);
   int height = pageContents.getHeight(this);
   if(width/(pgwidth - (pgnumber + 2)*bdwidth) > height/(pgheight - 4*bdwidth)) {
    height = height*(pgwidth - (pgnumber + 2)*bdwidth)/width;
    width = (pgwidth - (pgnumber + 2)*bdwidth);
   }
   else {
    width = width*(pgheight - 4*bdwidth)/height;
    height = pgheight - 4*bdwidth;
   }
   if(i%2 == 0){
    page.drawImage(pageContents, pgwidth - width - 2*bdwidth, 2*bdwidth, width, height, this);
   }
   else {
    page.drawImage(pageContents, 2*bdwidth, 2*bdwidth, width, height, this);
   }
  }

  String text = getParameter("text" + i);
  if(text != null) {
   page.setFont(font[0]);
   page.setColor(color[0]);
   int width = pgwidth - (pgnumber + 2)*bdwidth;
   int height = pgheight - 4*bdwidth;
   int j, k, f = 0;
   int tx, ty;
   if(i%2 == 0) tx = pgwidth - width - 2*bdwidth;
   else tx = 2*bdwidth;
   if(text.startsWith("<f")) ty = 0;
   else ty = 2*bdwidth + metrics[0].getHeight();
   String line = "";
   for(j=0; j < text.length(); j++) {
    if(j < text.length() - 4) {
     if(text.substring(j,text.length()).startsWith("<f") &&
        Character.isDigit(text.charAt(j+2))) {
      page.drawString(line, tx, ty);
      f = (int)(text.charAt(j+2)) - 48;
      page.setFont(font[f]);
      if(j < text.length() - 6) {
       if(text.charAt(j+3) == 'c' && Character.isDigit(text.charAt(j+4))) {
        page.setColor(color[(int)(text.charAt(j+4)) - 48]);
        j += 2;
       }
      }
      j += 4;
      ty += metrics[f].getHeight();
      line = "";
     }
    }
    line += text.charAt(j);
    if(metrics[f].stringWidth(line) > width) {
     if(line.lastIndexOf(' ') != -1) {
      j = text.substring(0, j + 1).lastIndexOf(' ');
      line = line.substring(0, line.lastIndexOf(' '));
     }
     page.drawString(line, tx, ty);
     line = "";
     ty += metrics[f].getHeight();
    }
   }
   page.drawString(line, tx, ty);
  }

  return offscreenPage;
 }

 public boolean load(String name) {
  pageContents = getImage(getDocumentBase(),name);
  MediaTracker tracker = new MediaTracker(this);
  tracker.addImage(pageContents,0);
  try {
   tracker.waitForID(0);
  } catch (InterruptedException e) {}
  return !(tracker.isErrorID(0));
 }

 public void update(Graphics screen) {
  paint(screen);
 }

 public void paint(Graphics screen) {

  int i, x, y, w, h, delta;

  offscreen.setColor(bgColor);
  offscreen.fillRect(0,0,size().width,size().height);

  i = curr - 1;
  x = (i - 1)*bdwidth + x0;
  y = size().height - (i - 1)*bdwidth - pgheight - y0;
  w = pgwidth;
  h = pgheight + (i - 1)*bdwidth;
  if(i > 0) offscreen.drawImage(drawPage(i), x, y, w, h, this);

  i = curr;
  x = (i - 1)*bdwidth + pgwidth + x0;
  y = size().height - (pgnumber - i)*bdwidth - pgheight - y0;
  w = pgwidth;
  h = pgheight + (pgnumber - i)*bdwidth;
  if(i <= pgnumber) offscreen.drawImage(drawPage(i), x, y, w, h, this);

  for(i = curr - 3; i > 0; i -= 2) {
   offscreen.setColor(bdColor);
   delta = (i - 1)*bdwidth;
   offscreen.fillRect(i*bdwidth + x0, size().height - delta - pgheight - y0, bdwidth, bdwidth);
   offscreen.fillRect(delta + x0, size().height - delta - pgheight - y0, bdwidth, pgheight);
   offscreen.fillRect(delta + x0, size().height - i*bdwidth - y0, pgwidth - delta, bdwidth);
   offscreen.fillArc(pgwidth + x0 - delta, size().height - i*bdwidth - y0, 2*delta, 2*delta, 0, 90);
   offscreen.setColor(pgColor);
   delta = (i + 1)*bdwidth;
   offscreen.fillRect(delta + x0, size().height - delta - y0, pgwidth - delta, bdwidth);
   delta = (i - 2)*bdwidth;
   offscreen.fillRect(i*bdwidth + x0, size().height - delta - pgheight - y0, bdwidth, pgheight - 2*bdwidth);
   offscreen.fillArc(pgwidth + x0 - delta, size().height - (i - 1)*bdwidth - y0, 2*delta, 2*delta, 0, 90);
  }

  for(i = curr + 2; i <= pgnumber; i += 2) {
   offscreen.setColor(bdColor);
   delta = (pgnumber - i)*bdwidth;
   offscreen.fillRect((i - 3)*bdwidth + 2*pgwidth + x0, size().height - delta - pgheight - y0, bdwidth, bdwidth);
   offscreen.fillRect((i - 2)*bdwidth + 2*pgwidth + x0, size().height - delta - pgheight - y0, bdwidth, pgheight);
   offscreen.fillRect((i - 1)*bdwidth + pgwidth + delta + x0, size().height - delta - bdwidth - y0, pgwidth - delta, bdwidth);
   offscreen.fillArc((i - 1)*bdwidth + pgwidth + x0, size().height - delta - bdwidth - y0, 2*delta, 2*delta, 90, 90);
   offscreen.setColor(pgColor);
   delta = (pgnumber - i + 1)*bdwidth;
   offscreen.fillRect((pgnumber - 1)*bdwidth + pgwidth + x0, size().height - delta - bdwidth - y0, pgwidth - delta, bdwidth);
   delta = (pgnumber - i - 1)*bdwidth;
   offscreen.fillRect((i - 3)*bdwidth + 2*pgwidth + x0, size().height - delta - pgheight - y0, bdwidth, pgheight - 2*bdwidth);
   offscreen.fillArc(i*bdwidth + pgwidth + x0, size().height - delta - bdwidth - y0, 2*delta, 2*delta, 90, 90);
  }

  offscreen.setColor(bdColor);
  offscreen.fillRect(x0 + pgwidth, size().height - y0 - bdwidth, (pgnumber - 1)*bdwidth, bdwidth);
  offscreen.fillRect(x0 + pgwidth + (curr - 2)*bdwidth, size().height - y0 - pgheight, bdwidth, pgheight);

  offscreen.setColor(color[0]);
  offscreen.setFont(font[0]);
  offscreen.drawString(head, x0 + (2*pgwidth + (pgnumber - 1)*bdwidth - metrics[0].stringWidth(head))/2, y0 - metrics[0].getHeight()/2);
  String number = "" + (curr - 1);
  offscreen.drawString(number, x0, size().height - y0 + metrics[0].getHeight());
  if(targ!= 0) {
   number = "" + targ;
   offscreen.drawString(number, x0 + (2*pgwidth + (pgnumber - 1)*bdwidth - metrics[0].stringWidth(number))/2, size().height - y0 + metrics[0].getHeight());
  }
  number = "" + curr;
  offscreen.drawString(number, x0 + 2*pgwidth + (pgnumber - 1)*bdwidth - metrics[0].stringWidth(number), size().height - y0 + metrics[0].getHeight());

  screen.drawImage(offscreenImage, 0, 0, this);

 }

}