/*
 * --------------------------------------------------------------------
 * class Fortune
 *      Gibt verschiedene Meldungen aus
 * -----------------------------------------------------------------------
 * Copyright 1999, 2005 Martin Kompf
 * -----------------------------------------------------------------------
 * Hinweise:
 * Dieses Programm wurde zur privaten Benutzung in unkritischen Umgebungen
 * entworfen.
 * Es wird der Allgemeinheit zur freien Nutzung zur Verfügung gestellt
 * und darf ohne Einschränkungen vervielfältigt und verändert werden,
 * sofern dieser Hinweis und das Copyright nicht verändert werden.
 * DAS PROGRAMM IST NICHT ZUM VERKAUF BESTIMMT.
 * ES WIRD KEINERLEI FUNKTION DES PROGRAMMES GARANTIERT.
 * DIE BENUTZUNG ERFOLGT AUF EIGENE GEFAHR.
 * -----------------------------------------------------------------------
*/

import java.awt.*;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.URL;

public class Fortune extends java.applet.Applet implements Runnable {

    private int flags;
    private final int RANDOM = 1;
    private final int ORDERED = 2;
    private final int ROTATED = 4;

    private Random rand;
    private Vector data = new Vector(5);
    private Thread fortuneThread;

    public void run() {
        int version;
        int numstr;
        int longlen;
        int shortlen;
        byte[] delim = new byte[4];

        try {
            // display a "busy" message to the user
            data.removeAllElements();
            data.addElement("");
            data.addElement("Lade Zitat vom Server ...");
            repaint(10);

            // get fortune
            String fortune = "";
            Vector fortunes = new Vector(5);
            StringTokenizer st = new StringTokenizer(getParameter("FORTUNES"));
            while (st.hasMoreTokens()) {
                fortunes.addElement( st.nextToken());
            }
            Double n = new Double(Math.floor(fortunes.size() * rand.nextDouble()));
            fortune = (String)fortunes.elementAt(n.intValue());

            // read zip file
            URL url = new URL( getCodeBase(), fortune + ".zip");
            ZipInputStream zip = new ZipInputStream( url.openStream());

            // extract dat file
            ZipEntry datfile = zip.getNextEntry();
            if (! datfile.getName().equals( fortune + ".dat")) {
                System.err.println( "datfile not found in zipfile");
                return;
            }
            DataInputStream in = new DataInputStream( zip);
            // header
            version = in.readInt();
            if (version != 1) {
                System.err.println( "Wrong version of dat file");
                return;
            }
            numstr = in.readInt();
            longlen= in.readInt();
            shortlen = in.readInt();
            flags = in.readInt();
            in.readFully( delim);
            // offset
            Double datOffset = new Double(Math.floor(numstr * rand.nextDouble()));
            for (int i = 0; i < datOffset.intValue(); ++i) in.readInt();
            int fileOffset = in.readInt();
            // System.out.println("FileOffset = " + String.valueOf(fileOffset));
            // fortuneThread.sleep(2000);

            // extract text file
            ZipEntry textfile = zip.getNextEntry();
            if (! textfile.getName().equals( fortune)) {
                System.err.println( "textfile not found in zipfile");
                return;
            }

            data.removeAllElements();
            DataInputStream tin = new DataInputStream( zip);
            for (int i = 0; i < fileOffset; ++i) tin.readByte();
            String line = "";
            String end = new String( delim, 0, 1);
            while (! line.equals(end)) {
                data.addElement( line);
                line = tin.readLine();
                line = line.replace( '\t', ' ');
            }

            // display fortune
            repaint();
        }
        catch (Exception e) {
            System.err.println( e);
            e.printStackTrace();
            return;
        }
    }


    public void init() {
        // init random
        rand = new Random();
        // set font
        int size = 14;
        try {
            size = Integer.parseInt(getParameter("SIZE"), 10);
        }
        catch (NumberFormatException e) {
        }

        Font font = new java.awt.Font("Arial", Font.BOLD, size);
        setFont(font);

        setBackground( new Color(0x5cacee));

        // get fortune
        fortuneThread = new Thread(this);
        fortuneThread.start();
    }


    public void paint( Graphics g) {
        if (data.size() > 1) {
            int x = 5;
            int h = g.getFont().getSize();
            g.setColor(Color.white);

            for (int i = 1, y = h+5; i < data.size(); ++i, y+=h) {
                g.drawString( (String)data.elementAt(i), x, y);
            }
        }
    }

    public boolean mouseDown( Event e, int x, int y) {
        // get new fortune
        if (! fortuneThread.isAlive()) {
            fortuneThread = new Thread(this);
            fortuneThread.start();
        }
        return true;
    }
}