import java.awt.*;
import java.applet.*;
import java.util.*;
import java.net.*;

public class WRAnimator extends Applet implements Runnable {
Date Datum;
Thread Zeit;

int Laenge;
private Graphics    dbuffer;
private Image       offscreen;

private final static int countOfPositions = 12;
private final static String CLASSIC  = "CLASSIC";
private final static String ORDINARY = "ORDINARY";

private boolean     isClassic;
private ScreenShoot screenShoot;
private String      kindOfDisplay;

private String   statusMsg;

private Image    images[];
private Image    initPic;
private URL      urlLinks[];
private String   target;  // TBS TBS if you would use this applet in a Frame

private ImagePos imagePos[];
private int      countOfImages;
private int      centerX;
private int      centerY;

private int xTotal;
private int x1;
private int x2;
private int x3;

private int yTotal;
private int y1;
private int y2;
private int y3;

private OneShoot szene[];
private int      picProSzene;
private int      szenenCursor;
private int      repeatTime;

private int sleepTime;  // Mili-Seconds

public void init() {
	System.out.println("init is called!!");
	Datum = new Date();
	offscreen = createImage(size().width,size().height);
	dbuffer   = offscreen.getGraphics();
	// goffScreen.translate(centerX,centerY);



    sleepTime     = Integer.valueOf(getParameter("DelayTime")).intValue();
    statusMsg     = getParameter("StatusLineMsg");
    kindOfDisplay = getParameter("KindOfDisplay");

    if (kindOfDisplay.compareTo(CLASSIC) == 0) {
        isClassic = true;
	    x1  = Integer.valueOf(getParameter("X1")).intValue();
	    x2  = Integer.valueOf(getParameter("X2")).intValue();
	    x3  = Integer.valueOf(getParameter("X3")).intValue();

	    y1  = Integer.valueOf(getParameter("Y1")).intValue();
	    y2  = Integer.valueOf(getParameter("Y2")).intValue();
	    y3  = Integer.valueOf(getParameter("Y3")).intValue();
        xTotal  = 2*x1;
        yTotal  = 2*y1;

	    centerX = x1;
	    centerY = y1;

	    // Calculate Positions
	    imagePos     = new ImagePos[countOfPositions];
	    imagePos[0]  = new ImagePos(centerX-x3,centerY-y3,x3,y3);
	    imagePos[1]  = new ImagePos(centerX   ,centerY-y3,x3,y3);
	    imagePos[2]  = new ImagePos(centerX-x3,centerY   ,x3,y3);
	    imagePos[3]  = new ImagePos(centerX   ,centerY   ,x3,y3);

	    imagePos[4]  = new ImagePos(centerX-x2,centerY-y2,x2,y2);
	    imagePos[5]  = new ImagePos(centerX   ,centerY-y2,x2,y2);
	    imagePos[6]  = new ImagePos(centerX-x2,centerY   ,x2,y2);
	    imagePos[7]  = new ImagePos(centerX   ,centerY   ,x2,y2);

	    imagePos[8]  = new ImagePos(centerX-x1,centerY-y1,x1,y1);
	    imagePos[9]  = new ImagePos(centerX   ,centerY-y1,x1,y1);
	    imagePos[10] = new ImagePos(centerX-x1,centerY   ,x1,y1);
	    imagePos[11] = new ImagePos(centerX   ,centerY   ,x1,y1);
    } else if (kindOfDisplay.compareTo(ORDINARY) == 0) {
        isClassic = false;
	    x3  = Integer.valueOf(getParameter("X3")).intValue();
	    y3  = Integer.valueOf(getParameter("Y3")).intValue();
	    xTotal  = 4*x3;
        yTotal  = 3*y3;
	    imagePos     = new ImagePos[countOfPositions];
	    imagePos[0]  = new ImagePos(0,   0,x3,y3);
	    imagePos[1]  = new ImagePos(x3,  0,x3,y3);
	    imagePos[2]  = new ImagePos(2*x3,0,x3,y3);
	    imagePos[3]  = new ImagePos(3*x3,0,x3,y3);

	    imagePos[4]  = new ImagePos(0,   y3,x3,y3);
	    imagePos[5]  = new ImagePos(x3,  y3,x3,y3);
	    imagePos[6]  = new ImagePos(2*x3,y3,x3,y3);
	    imagePos[7]  = new ImagePos(3*x3,y3,x3,y3);

	    imagePos[8]  = new ImagePos(0,   2*y3,x3,y3);
	    imagePos[9]  = new ImagePos(x3,  2*y3,x3,y3);
	    imagePos[10] = new ImagePos(2*x3,2*y3,x3,y3);
	    imagePos[11] = new ImagePos(3*x3,2*y3,x3,y3);

    } else {
        System.err.println("No valid KindOfDisplay: " + kindOfDisplay);
    }



    screenShoot = new ScreenShoot(countOfPositions);

    // Load Pictures
	String pictureSource = getParameter("PictureSource");
	String initPicStr    = getParameter("Pictures_Init");
	if (pictureSource.compareTo("DocumentBase") == 0) {
	        initPic  = getImage(getDocumentBase(),initPicStr);
	   } else {
	      try {
	        initPic  = getImage(new URL(initPicStr));
	      } catch (Exception e) {
            System.err.println("Error fetching initPic!");
          }
       }



	countOfImages = Integer.valueOf(getParameter("CountOfPictures")).intValue();
	System.out.println("Count of Images: " + countOfImages);
	images     = new Image[countOfImages];
	for (int i=0; i<countOfImages; i++) {
	   String urlStr = getParameter("PicturesURL_" + i);
	   System.out.println("Load Picture " + i + ": " + urlStr);
	   if (pictureSource.compareTo("DocumentBase") == 0) {
	        images[i]  = getImage(getDocumentBase(),urlStr);
	   } else {
	      try {
	        images[i]  = getImage(new URL(urlStr));
	      } catch (Exception e) {
            System.err.println("Error fetching image (" + i + ")!");
          }
       }

	}

    // Load links
	urlLinks   = new URL[countOfImages];
	for (int i=0; i<countOfImages; i++) {
	   String urlStr = getParameter("LinkURL_" + i);
	   System.out.println("Link for Pic: " + i + ": " + urlStr);
	   try {
	      urlLinks[i]  = new URL(urlStr);
	   } catch (Exception e) {
          System.err.println("Error fetching Link (" + i + ")!");
          urlLinks[i] = null;
       }
	}

    // Szenen Definition
    picProSzene   = Integer.valueOf(getParameter("ScenesProFilm")).intValue();
    System.out.println("PicturesProScene: " + picProSzene);
    if (initPic == null) {
        szenenCursor = 0;
    } else {
        szenenCursor = -1;
    }
    szene         = new OneShoot[picProSzene];
    for (int i=0; i<picProSzene; i++) {
	    String picPosStr = getParameter("Scene_" + i);
	    System.out.println("Load PicPos " + i + ": " + picPosStr);
        szene[i]      = new OneShoot(picPosStr);
	}

    repeatTime    = Integer.valueOf(getParameter("RepeatTime")).intValue();   // for ever = -1

	target = null;   // TBS TBS only for frames

}

public void start() {
	System.out.println("start is called!!");
	if (Zeit== null) {
		Zeit = new Thread(this);
		Zeit.start();
	}
}

public void stop() {
	if (Zeit!= null) {
		Zeit.stop();
		Zeit = null;
	}
}

public void run() {
    System.out.println("run is called!!");
	while(1==1) {
		Datum = new Date();
		repaint();
		try {
			Zeit.sleep(sleepTime);
		} catch (InterruptedException e) {
			System.out.print("Thread_interrupted");
		}
	}
}

public void update(Graphics g) {
    System.out.println("update is called!!");
    paint(g);
}

public void paint (Graphics g) {
    System.out.println("paint is called!!");
	if ((repeatTime > 0) || (repeatTime == -1)) {

            if (szenenCursor < picProSzene) {
                if (szenenCursor == -1) {
                    if (initPic == null) {
                        System.out.println("Trying to load initPic!!!   But not loaded yet!!");
                    } else {
                        System.out.println("Trying to load initPic!!!");
                    }
                    dbuffer.drawImage(initPic,0,0,xTotal,yTotal,this);
                } else {
                    for (int i=0; i<szene[szenenCursor].countOfPicPosParts(); i++) {
                        screenShoot.setPic(szene[szenenCursor].getPicNo(i),szene[szenenCursor].getPosNo(i),isClassic);
                        paintImage(dbuffer,szene[szenenCursor].getPicNo(i),szene[szenenCursor].getPosNo(i));
                    } // for
                }
                szenenCursor++;
            } else {
                if (initPic == null) {
                    szenenCursor = 0;
                } else {
                    szenenCursor = -1;
                }
                if (repeatTime > 0) {
                    repeatTime--;
                    System.out.println("RepeatTime is: " + repeatTime);
                }
            }
        }
        else {
            // System.out.println("Play is in Hold!!!");
            sleepTime = 5000;
        }
    g.drawImage(offscreen,0,0,this);
}

public void paintImage(Graphics g,int ImgNr, int ImgPos) {
    if (images[ImgNr] == null) {
        System.out.println("paintImage is called for drawing Img[" + ImgNr + "]!!!   But not loaded yet!!");
    } else {
        System.out.println("paintImage is called for drawing Img[" + ImgNr + "]!!!");
    }
    g.drawImage(images[ImgNr],imagePos[ImgPos].getX(),
                              imagePos[ImgPos].getY(),
                              imagePos[ImgPos].getWidth(),
                              imagePos[ImgPos].getHight(),this);

}

public void drawAllImage(Graphics g) {
    for (int i=11; i>=0; i--) {
      paintImage(g,i,i);
    }
}

public int whichAera(int x, int y) {
    // System.out.println("whichAera: " + x + "   " + y);
    if ((x >= 0) && (x < x3) && (y >= 0) && (y < y3))
        return 0;
    else if ((x < x2) && (y < y2))
        return 4;
    else if ((x < x1) && (y < y1))
        return 8;
    else
        return -1; // never happen!!!! (I hope it!!!)
}


//////////////////////////////////////////////////////////////////
// Trap for a mouse click on the applet to check to see if they
// want to go to another page.
public boolean mouseDown(java.awt.Event evt, int x, int y) {
    // System.out.println("Mouse klick: " + x + "  " + y);
    // Calculate which link you should go

    int posNo = 0;   // 0..11
    if (isClassic) {
        if ((x >= 0) && (x <= x1)) {
            // right half
            if ((y >= 0) && (y <= y1)) {
                // upper half
                posNo = whichAera(centerX-x,centerY-y);
                System.out.println("Click on (8): " + posNo);
            } else if ((y > y1) && (y <= 2*y1)) {
                // lower half
                posNo = whichAera(centerX-x,y-centerY)+2;
                System.out.println("Click on (10): " + posNo);
            } else {
                System.err.println("y ist out ouf Range: " + y);
            }
        } else if ((x > x1) && (x <= 2*x1)) {
            // left half
            if ((y >= 0) && (y <= y1)) {
                // upper half
                posNo = whichAera(x-centerX,centerY-y)+1;
                System.out.println("Click on (9): " + posNo);
            } else if ((y > y1) && (y <= 2*y1)) {
                // lower half
                posNo = whichAera(x-centerX,y-centerY)+3;
                System.out.println("Click on (11): " + posNo);

            } else {
                System.err.println("y ist out ouf Range: " + y);
            }
        } else {
            System.err.println("x ist out ouf Range: " + x);
        }
    } else {
        if (x > 3*x3) {
            posNo = 3;
        } else if (x > 2*x3) {
            posNo = 2;
        } else if (x > x3) {
            posNo = 1;
        } else {
            posNo = 0;
        }

        if (y > 2*y3) {
            posNo = posNo + 8;
        } else if (y > y3) {
            posNo = posNo + 4;
        }
    }

    int linkNo = screenShoot.getPicNo(posNo);
    // Jump to that link
    showStatus("Mouse klick: " + x + "  " + y + "  Go: " + urlLinks[linkNo].toString());
    if (urlLinks[linkNo] != null) {
         if(target != null) { // They have specified a target
            getAppletContext().showDocument(urlLinks[linkNo],target);
         }
         else {
            getAppletContext().showDocument(urlLinks[linkNo]);
         }
    }
    return true;
}



//////////////////////////////////////////////////////////////////
// If the mouse cursor enters the applet, then display something
// in the status bar of the browser.
public boolean mouseEnter(java.awt.Event evt, int x, int y) {
   showStatus(statusMsg);
   return true;
}

//////////////////////////////////////////////////////////////////
// If the mouse cursor exits the applet, then clear the status
// bar.
public boolean mouseExit(java.awt.Event evt, int x, int y) {
   showStatus(" ");
   return true;
}


} // end of WRAnimator




class ImagePos {
    private int x;
    private int y;
    private int hight;
    private int width;

    public ImagePos(int x, int y, int width, int hight) {
        this.x = x;
        this.y = y;
        this.hight = hight;
        this.width = width;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getHight() {
        return hight;
    }

    public int getWidth() {
        return width;
    }

} // end of ImagePos

class OneShoot {
    private int picNo[];
    private int posNo[];
    private int countOfPicPosParts;


   public OneShoot(String picPos) {
        StringTokenizer picPosPart = new StringTokenizer(picPos,",");
        countOfPicPosParts = picPosPart.countTokens() / 2;
        // System.out.println(picPos + " : " + countOfPicPosParts);
        picNo = new int[countOfPicPosParts];
        posNo = new int[countOfPicPosParts];
        for (int i=0; i<countOfPicPosParts; i++) {
            String picStr = picPosPart.nextToken();
            String posStr = picPosPart.nextToken();
            this.picNo[i] = Integer.valueOf(picStr).intValue();
            this.posNo[i] = Integer.valueOf(posStr).intValue();
        } // for
    }

    public int getPicNo(int no) {
        return picNo[no];
    }

    public int getPosNo(int no) {
        return posNo[no];
    }

    public int countOfPicPosParts() {
        return countOfPicPosParts;
    }

} // end of OneShoot

class ScreenShoot {
    private int countOfPos;
    private int picNo[];

    public ScreenShoot(int countOfPos) {
        this.countOfPos = countOfPos;
        picNo = new int[countOfPos];
        for (int i=0; i<countOfPos; i++) {
            picNo[i]=0;
        }
    }

    public int getPicNo(int onPos) {
        return picNo[onPos];
    }

    public void setPic(int picNom, int picPos, boolean isClassic) {
        picNo[picPos]=picNom;
        if (isClassic) {
            if (picPos > 3) {
                setPic(picNom,picPos-4,isClassic);
            }
        }
    }
} // end of ScreenShoot