import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Frame;
import java.awt.Image;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
import java.awt.Graphics;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.lang.Thread;
import java.util.Date;
import java.util.Random;
import java.net.URL;

import netscape.javascript.JSObject;

public class dark_log extends Applet implements Runnable
{
	private String name, age, gender, nationality, welcome, proceed, finaly, youareback, good, seeyou, place, inside, press, searching, analyzing, matchfound, name_only, doplay1, doplay2, yes, no;

	private Thread thr = null;
	private int pause = 50;
	private boolean alive = true, default_cursor = true, show_print = true, scanning = false;

	private org_font orgator;

	private static String[] lowCaseArray(String[] s)
	{
		String[] str = new String[s.length];
		for (int i = 0; i < s.length; i++) str[i] = lowCaseString(s[i]);
		return str;
	}

	private static String lowCaseString(String s)
	{
		return s.toLowerCase();
	}

	private Image off_screen, print, prints;
	private int width, height;

	private int back, fore;
	private Color back_col, fore_col;

	private int band_width = 15;

	private Random rand = new Random();
	private int[] pure_pixels, paint_pixels, red_pixels;

	private Rectangle print_rect = new Rectangle (0, 0, 151, 201), scan_rect = new Rectangle (250, 0, 151, 201), yes_rect = new Rectangle (0, 350, 100, 32), no_rect = new Rectangle (400, 350, 100, 32);

	public void init()
	{
		Image font = getImage(getCodeBase(), "org_font.gif");
		prints = getImage(getCodeBase(), "prints.gif");
		MediaTracker mt = new MediaTracker (this);
		mt.addImage(prints, 0);
		mt.addImage(font, 1);

		name=getParameter("name");
		age=getParameter("age");
		gender=getParameter("gender");
		nationality=getParameter("nationality");

		if (name==null) name = " ? ";
		if (age==null) age = " ? ";
		if (gender==null) gender = " ? ";
		if (nationality==null) nationality = " ? ";

		name_only = name;


		name = lowCaseString("name: " + name);
		age = lowCaseString("age: " + age);
		gender = lowCaseString("gender: " + gender);
		nationality = lowCaseString("nationality: " + nationality);
		finaly = lowCaseString("finally...");
		youareback = lowCaseString("you are back");
		good = lowCaseString("it is good");
		seeyou=lowCaseString("to see you again");

		place = lowCaseString("place mouse");
		inside = lowCaseString("on left square");
		press = lowCaseString("press mouse");

		searching = lowCaseString("searching...");
		analyzing = lowCaseString("analyzing...");
		matchfound = lowCaseString("match found");
		doplay1 = lowCaseString("do you");
		doplay2 = lowCaseString("want to play?");
		yes = lowCaseString("yes");
		no = lowCaseString("no");

		back = 0xff000000;
		fore = 0xff990000;
		back_col = new Color (back);
		fore_col = new Color (fore);

		Dimension dim;
		try {dim = getSize();} catch (Throwable t) {dim=size();}
		width = dim.width;
		height = dim.height;

		try {mt.waitForAll();} catch (Throwable t){}
		print = createImage (150, 200);
		Graphics print_g = print.getGraphics();
		print_g.drawImage (prints, -3300, 0, this);
		print_g.dispose();

		off_screen = createImage(width, height);
		Graphics g = off_screen.getGraphics();
		g.setColor (back_col);
		g.fillRect(0, 0, width, height);

		g.setColor (fore_col);

		g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
		g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

		g.dispose();


		orgator = new org_font(font, 30, 0xffff0000, this);

		orgator.drawString(off_screen, 20, new Point (0, 250), place, this);
		orgator.drawString(off_screen, 20, new Point (0, 300), inside, this);

		pure_pixels = new int[150 * 200];
		red_pixels = new int[150 * 200];
		paint_pixels = new int[150 * 200];

		PixelGrabber pg = new PixelGrabber(print, 0, 0, 150, 200, pure_pixels, 0, 150);
		try {pg.grabPixels();} catch (InterruptedException e){}

		for (int i = 0; i < 200; i++)
		for (int j = 0; j < 150; j++)
		{
			int key = pure_pixels[j * 200 + i] & 0x0000ff;
			int key_ = (pure_pixels[j * 200 + i] & 0x00ff00) >> 8;
			if (key_ > key) key = key_;
			if (key > 4) key_ = key - 4;
			pure_pixels [j * 200 + i] = (255 << 24) + (key << 16) + (key << 8) + key;
			paint_pixels [j * 200 + i] = (255 << 24) + (key << 16) + (key << 8) + key;
			red_pixels [j * 200 + i] = (255 << 24) + (key << 16);
		}

	}

	public void paint(Graphics g)
	{
		g.drawImage(off_screen, 0, 0, this);
	}

	public void update(Graphics g)
	{
		paint(g);
	}

	public void run()
	{
		while (alive)
		{
			for (int j = 0; j < 5; j++)
			for (int i = 0; i < 23; i ++)
			{
				try {thr.sleep(10);} catch (Throwable t){}
				Graphics g = off_screen.getGraphics();
				g.clipRect (scan_rect.x + 1, scan_rect.y + 1, scan_rect.width - 1, scan_rect.height - 1);
				g.drawImage (prints, - i * 150 + scan_rect.x, scan_rect.y, this);

				g.dispose();

				paint(getGraphics());
			}


			Graphics g = off_screen.getGraphics();
			g.setColor (back_col);
			g.fillRect(0, 0, width, height);
			g.setColor (fore_col);
			g.drawImage (print, 1,1, this);

			g.drawImage (print, scan_rect.x + 1, scan_rect.y + 1, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

			orgator.drawString(off_screen, 20, new Point (0, 250), analyzing, this);

			g.dispose();

			paint(getGraphics());





for (int num = 0; num < 3; num++)

			for (int k = band_width; k < 200; k++)
			{


				for (int i = 0; i < 150; i++)
				{
					int r = Math.abs(rand.nextInt()) % band_width;
					int r2 = Math.abs (rand.nextInt()) % 5;
					for (int j = r2; j < r; j++)
					{
						if ((rand.nextInt() & 1) > 0)
						paint_pixels [(k - j) * 150 + i] = red_pixels [(k - (rand.nextInt() & 7)) * 150 + i];
						else paint_pixels [(k - j) * 150 + i] = paint_pixels [(k - (rand.nextInt() & 7)) * 150 + i];
					}
				}

				Image im = createImage(new MemoryImageSource(150, 200, paint_pixels, 0, 150));


				g = off_screen.getGraphics();
				g.clipRect (scan_rect.x + 1, scan_rect.y + 1, scan_rect.width - 1, scan_rect.height - 1);
				g.drawImage (im, scan_rect.x, scan_rect.y, this);

				im.flush();

				g.dispose();

				paint(getGraphics());

				try {thr.sleep(10);} catch (Throwable t){}

			}


for (int num = 0; num < 3; num++)

			for (int k = band_width; k < 200; k++)
			{


				for (int i = 0; i < 150; i++)
				{
					int r = Math.abs(rand.nextInt()) % band_width;
					int r2 = Math.abs (rand.nextInt()) % 5;
					for (int j = r2; j < r; j++)
					{
						if ((Math.abs(rand.nextInt()) % (num + 1)) > 0)
						paint_pixels [(k - j) * 150 + i] = red_pixels [(k - j)* 150 + i];
						else paint_pixels [(k - j) * 150 + i] = paint_pixels [(k - (rand.nextInt() & 7)) * 150 + i];
					}
				}

				Image im = createImage(new MemoryImageSource(150, 200, paint_pixels, 0, 150));


				g = off_screen.getGraphics();
				g.clipRect (scan_rect.x + 1, scan_rect.y + 1, scan_rect.width - 1, scan_rect.height - 1);
				g.drawImage (im, scan_rect.x, scan_rect.y, this);

				im.flush();

				g.dispose();

				paint(getGraphics());

				try {thr.sleep(10);} catch (Throwable t){}

			}

			for (int k = band_width; k < 200; k++)
			{


				for (int i = 0; i < 150; i++)
				{
					int r = Math.abs(rand.nextInt()) % band_width;
					int r2 = Math.abs (rand.nextInt()) % 5;
					for (int j = r2; j < r; j++)
					{
						paint_pixels [(k - j) * 150 + i] = red_pixels [(k - j)* 150 + i];
					}
				}

				Image im = createImage(new MemoryImageSource(150, 200, paint_pixels, 0, 150));


				g = off_screen.getGraphics();
				g.clipRect (scan_rect.x + 1, scan_rect.y + 1, scan_rect.width - 1, scan_rect.height - 1);
				g.drawImage (im, scan_rect.x, scan_rect.y, this);

				im.flush();

				g.dispose();

				paint(getGraphics());

				try {thr.sleep(10);} catch (Throwable t){}

			}


			Image im = createImage(new MemoryImageSource(150, 200, paint_pixels, 0, 150));
			g = off_screen.getGraphics();

			g.setColor (back_col);
			g.fillRect(0, 0, width, height);
			g.setColor (fore_col);
			g.drawImage (print, 1,1, this);

			g.drawImage (im, scan_rect.x, scan_rect.y, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

			orgator.drawString(off_screen, 20, new Point (0, 250), matchfound, this);

			paint(getGraphics());



			try {thr.sleep(2000);} catch (Throwable t){}


			g.setColor (back_col);
			g.fillRect(0, 0, width, height);
			g.setColor (fore_col);
			g.drawImage (print, 1,1, this);

			g.drawImage (im, scan_rect.x, scan_rect.y, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

			orgator.drawString(off_screen, 20, new Point (0, 250), name, this);
			orgator.drawString(off_screen, 20, new Point (0, 300), age, this);
			orgator.drawString(off_screen, 20, new Point (0, 350), gender, this);

			paint(getGraphics());



			try {thr.sleep(2000);} catch (Throwable t){}

			g.setColor (back_col);
			g.fillRect(0, 0, width, height);
			g.setColor (fore_col);
			g.drawImage (print, 1,1, this);

			g.drawImage (im, scan_rect.x, scan_rect.y, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

			orgator.drawString(off_screen, 20, new Point (0, 250), good, this);
			orgator.drawString(off_screen, 20, new Point (0, 300), name_only, this);

			orgator.drawString(off_screen, 20, new Point (0, 350), seeyou, this);

			paint(getGraphics());



			try {thr.sleep(2000);} catch (Throwable t){}

			g.setColor (back_col);
			g.fillRect(0, 0, width, height);
			g.setColor (fore_col);
			g.drawImage (print, 1,1, this);

			g.drawImage (im, scan_rect.x, scan_rect.y, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);

			orgator.drawString(off_screen, 20, new Point (0, 250), doplay1, this);
			orgator.drawString(off_screen, 20, new Point (0, 300), doplay2, this);
			orgator.drawString(off_screen, 20, new Point (yes_rect.x, yes_rect.y), yes, this);
			orgator.drawString(off_screen, 20, new Point (no_rect.x, no_rect.y), no, this);

			paint(getGraphics());



			alive = false;


		}
	}

	private int cheat(Color c)
	{
		Image cim = createImage(1,1);
		Graphics cg = cim.getGraphics();
		cg.setColor(c);
		cg.fillRect(0,0,2,2);
		cg.dispose();
		int[] cpx = new int[4];
		try {(new PixelGrabber(cim, 0, 0, 1, 1, cpx, 0, 1)).grabPixels();}
		catch (Throwable t){}
		return cpx[0];
	}

	public void killThread()
	{
		alive = false;
//		jukebox.killThread();
	}

	public boolean mouseMove(Event e, int x, int y)
	{
		if (print_rect.inside(x, y) && default_cursor && alive)
		{
			default_cursor = false;
			try {((Frame)getParent()).setCursor(Frame.CROSSHAIR_CURSOR);} catch (Throwable t){}

			if (show_print)
			{
				Graphics g = off_screen.getGraphics();

				g.setColor (Color.black);//back_col);
				g.fillRect(0, 0, width, height);

				g.setColor (fore_col);

				g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
				g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);
				g.drawImage (print, 1,1, this);
				g.dispose();


				orgator.drawString(off_screen, 20, new Point (0, 250), press, this);

				paint(getGraphics());
				show_print = false;
			}

		}


		else if (!alive && yes_rect.inside(x, y) && default_cursor)
		{
			default_cursor = false;
			try {((Frame)getParent()).setCursor(Frame.CROSSHAIR_CURSOR);} catch (Throwable t){}
		}

		else if (!alive && no_rect.inside(x, y) && default_cursor)
		{
			default_cursor = false;
			try {((Frame)getParent()).setCursor(Frame.CROSSHAIR_CURSOR);} catch (Throwable t){}
		}


		else if (!print_rect.inside(x, y) && !no_rect.inside(x, y) && !yes_rect.inside(x, y) && !default_cursor)
		{
			default_cursor = true;
			try {((Frame)getParent()).setCursor(Frame.DEFAULT_CURSOR);} catch (Throwable t){}
		}


		return true;
	}

	public boolean mouseDown(Event e, int x, int y)
	{
		if (!alive)
		{
			try
			{
				if (yes_rect.inside(x, y)) getAppletContext().showDocument(new URL(getDocumentBase(), "intro.htm"), "_self");
				if (no_rect.inside(x, y)) getAppletContext().showDocument(new URL(getDocumentBase(), "index.htm"), "_top");
			}
			catch (Throwable t){}
		}


		if (print_rect.inside(x, y) && !scanning)
		{
			Graphics g = off_screen.getGraphics();
			g.setColor (back_col);
			g.fillRect(0, 0, width, height);

			g.setColor (fore_col);

			g.drawImage (print, 1,1, this);
			g.drawRect (print_rect.x, print_rect.y, print_rect.width, print_rect.height);
			g.drawRect (scan_rect.x, scan_rect.y, scan_rect.width, scan_rect.height);
//			g.drawImage (print, 1,1, this);
			g.dispose();

			orgator.drawString(off_screen, 20, new Point (0, 250), searching, this);

			paint(getGraphics());
			scanning = true;

			thr = new Thread(this);
			thr.start();

		}
		return true;
	}

}

class juke extends Thread
{
	private AudioClip[] clips;
	private long[] millisecs;
	private boolean living = true;
	private int pause;
	private int num_clips;

	public juke(AudioClip[] ac, int[] secs, int p)
	{
		clips = ac;
		num_clips = clips.length;
		millisecs = new long[num_clips];
		for (int i = 0; i < num_clips; i++) playLoop(i, secs[i]);
		pause = p;
	}

	public void run()
	{
		while (living)
		{
			long d = new Date().getTime();
			for (int i = 0; i < num_clips; i++) if (millisecs[i] < d) clips[i].stop();
			try {sleep (pause);} catch (Throwable t){}
		}
		for (int i = 0; i < num_clips; i++) clips[i].stop();
	}

	public void playSound(int i)
	{
		if (living) clips[i].play();
	}

	public void playLoop(int i, int secs)
	{
		i = i % num_clips;
		if (secs > 0)
		{
			millisecs[i] = new Date().getTime() + secs * 500;
			clips[i].loop();
		}
		else millisecs[i] = 0;
	}

	public void killThread()
	{
		living = false;
	}
}


class org_font
{
	public int num_shades;
	public final static int font_width = 32, font_height = 32, font_space = 7;

	private Image[] font_shades;
	public static final String font_letters = "abcdefghijklmnopqrstuvwxyzĉĝċ0123456789?!.,_: ";

	public static int string_width (String s)
	{
		return (s.length() + 1) * font_width + s.length() * font_space;
	}

	public void drawChar (Image im, int shade, Point p1, char c, ImageObserver imob)
	{
		Point p2 = image_point (c);
		Graphics g = im.getGraphics();
		g.clipRect(p1.x, p1.y, font_width, font_height);
		g.drawImage(font_shades[shade], p1.x - p2.x, p1.y - p2.y, imob);
		g.dispose();
	}

	public void drawString (Image im, int shade, Point p1, String s, ImageObserver imob)
	{
		for (int i = 0; i < s.length(); i++)
		{
			drawChar (im, shade, new Point(p1.x + i * (font_space + font_width), p1.y), s.charAt(i), imob);
		}
	}

	public org_font(Image font, int num, int fore, Component c)
	{
		int w = font.getWidth(null);
		int h = font.getHeight(null);
		num_shades = num;
		int[] col_shade_ints = new int[num_shades];
		for (int i = 0; i < num_shades; i++)
			col_shade_ints [i] = (255 << 24) +
			( (colorComp(fore, "red") * i / (num_shades - 1)) << 16) +
			( (colorComp(fore, "green") * i / (num_shades - 1)) << 8) +
			(colorComp(fore, "blue") * i / (num_shades - 1));

		font_shades = new Image[num_shades];

		int[] pixels = new int[w * h];
		int[][] pix = new int[num_shades][w * h];

		try {(new PixelGrabber(font, 0, 0, w, h, pixels, 0, w)).grabPixels();} catch (InterruptedException e){}

		for (int i = 0; i < w * h; i++)
		{
			if ((colorComp(pixels[i], "green") > 1) ||  (colorComp(pixels[i], "blue") > 1) )
			for (int j = 0; j < num_shades; j++)
			{
				pix[j][i] = col_shade_ints[j];
			}
			else for (int j = 0; j < num_shades; j++)
			{
				pix [j][i] = 0;//back;
			}
		}
		for (int i = 0; i < num_shades; i++) font_shades[i] = c.createImage(new MemoryImageSource(w, h, pix[i], 0, w));
	}

	private Point image_point (char c)
	{
		int i = font_letters.indexOf (c);
		if (i == -1) return new Point(0, - font_height);
		else return new Point(i * font_width, 0);
	}

	private int colorComp(int i, String s)
	{
		if (s == "red") return (i >> 16) & 255;
		if (s == "blue") return (i >> 8) & 255;
		else return i & 255;
	}
}