import java.awt.Image;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.util.Vector;
import java.lang.IndexOutOfBoundsException;
import java.lang.StringBuffer;
import java.util.StringTokenizer;

public class MangaribouPlayerApplet extends java.applet.Applet implements Runnable 
{
  Thread runner = null;
  Image offscreenImg;
  Graphics offscreenG;
  boolean readyToPaint = false;
  boolean compressed = true;
  Color fgColor, bgColor;

  int fontSize = 10;
  Font f = new Font("Courier", Font.BOLD, fontSize);

  int pause;

  DataInputStream d;
  URL url;
  URLConnection conn;

  /* Parametres */
  String urlName;
  int linesNumber;

  Vector mangaribou;
  int index;

  public void init()
    {
      String temp, s;
      StringTokenizer st;
      String rgbDelimiter = ":,.";

      s = getParameter("fgcolor");
      if (s != null)
	{
	  st = new StringTokenizer(s, rgbDelimiter);
	  if (s.equalsIgnoreCase("red"))
	    fgColor = Color.red;
	  else if (s.equalsIgnoreCase("blue"))
	    fgColor = Color.blue;
	  else if (s.equalsIgnoreCase("green"))
	    fgColor = Color.green;
	  else if (s.equalsIgnoreCase("yellow"))
	    fgColor = Color.yellow;
	  else if (s.equalsIgnoreCase("white"))
	    fgColor = Color.white;
	  else if (s.equalsIgnoreCase("orange"))
	    fgColor = Color.orange;
	  else if (s.equalsIgnoreCase("cyan"))
	    fgColor = Color.cyan;
	  else if (s.equalsIgnoreCase("magenta"))
	    fgColor = Color.magenta;
	  else if (st.countTokens() == 3) {
	    Integer r = new Integer(st.nextToken());
	    Integer g = new Integer(st.nextToken());
	    Integer b = new Integer(st.nextToken());
	    fgColor = new Color(r.intValue(), g.intValue(), b.intValue());
	  } else
	    fgColor = Color.white;
	} else
	  fgColor = Color.white;
      
      s = getParameter("bgcolor");
      if (s != null)
	{
	  st = new StringTokenizer(s, rgbDelimiter);
	  if (s.equalsIgnoreCase("red"))
	    bgColor = Color.red;
	  else if (s.equalsIgnoreCase("blue"))
	    bgColor = Color.blue;
	  else if (s.equalsIgnoreCase("green"))
	    bgColor = Color.green;
	  else if (s.equalsIgnoreCase("yellow"))
	    bgColor = Color.yellow;
	  else if (s.equalsIgnoreCase("white"))
	    bgColor = Color.white;
	  else if (s.equalsIgnoreCase("orange"))
	    bgColor = Color.orange;
	  else if (s.equalsIgnoreCase("cyan"))
	    bgColor = Color.cyan;
	  else if (s.equalsIgnoreCase("lightBlue"))
	    bgColor = new Color(200, 200, 255);
	  else if (s.equalsIgnoreCase("magenta"))
	    bgColor = Color.magenta;
	  else if (st.countTokens() == 3) {
	    Integer r = new Integer(st.nextToken());
	    Integer g = new Integer(st.nextToken());
	    Integer b = new Integer(st.nextToken());
	    bgColor = new Color(r.intValue(), g.intValue(), b.intValue());
	  } else
	    bgColor = Color.gray; 
	} else
	  bgColor = Color.gray; 

      offscreenImg = createImage(this.size().width, this.size().height);
      offscreenG   = offscreenImg.getGraphics();
      /**/
      offscreenG.setFont(f);
      offscreenG.setColor(bgColor);
      offscreenG.fill3DRect(0, 0,
			    this.size().width - 1, this.size().height - 1, 
			    true);
      offscreenG.setColor(fgColor);
      offscreenG.drawString("Connecting...", 0, fontSize);
      readyToPaint = true;
      repaint();
      /**/
      temp = getParameter("linesnumber");
      linesNumber = Integer.parseInt(temp);
      temp = getParameter("pause");
      if (temp != null)
	pause = Integer.parseInt(temp);
      else
	pause = 130;
      urlName = getParameter("theurl");

      try 
	{ 
	  url = new URL(urlName);	  
	} 
      catch(MalformedURLException e)
	{
	  System.out.println("Bad URL : " + url);
	}
    }
  
  public void start()
    {
      if (runner == null) 
	{
	  runner = new Thread(this);
	  runner.start();
	}
    }
  
  public void stop()
    {
      if (runner != null)
	{
	  runner.stop();
	  runner = null;
	}
    }

  public void update(Graphics g)
    {
      if (readyToPaint)
	paint(g);
    }

  public void readMangaribou()
    {
      int nbl = 0;
      try 
	{
	  String line;
	  boolean fin = false;

	  conn = url.openConnection();
	  conn.connect();

	  d = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
	  offscreenG.setFont(f);
	  offscreenG.setColor(bgColor);
	  offscreenG.fill3DRect(0, 0,
				this.size().width - 1, this.size().height - 1, 
				true);
	  offscreenG.setColor(fgColor);
	  offscreenG.drawString("Loading file...", 0, fontSize);
	  readyToPaint = true;
	  repaint();
	  do
	    {
	      line = d.readLine();
	      if (line != null)
		if (compressed)
		  {
		    StringBuffer tmp = new StringBuffer(200);
		    int i, j;

		    for(i = 0; i < line.length(); i++)
		      {
			char c = line.charAt(i);
			if (c > 128)
			  {
			    int n = c - 128;
			    i++;
			    c = line.charAt(i);
			    for(j = 0; j < n; j++)
			      tmp.append(c);
			  }
			else
			  tmp.append(c);
		      }
		    String tmpLine = new String(tmp);
		    mangaribou.addElement(tmpLine);		    
		  }
		else
		  mangaribou.addElement(line);
	      else
		fin = true;
	      nbl++;
	    } while(!fin);
	}
      catch (IOException e)
	{
	  System.out.println("IO error :" + e.getMessage());
	}
    }

  public void run()
    {
      mangaribou = new Vector(20000);
      readMangaribou();
      index = 0;
      while (true)
	{
	  repaint();
	  try { Thread.sleep(pause);} catch(InterruptedException e) {}
	  readyToPaint = false;
	  next();
	  readyToPaint = true;
	}      
    }

  public void paint(Graphics g) 
    {
      g.drawImage(offscreenImg, 0, 0, this);
    }

  public void next()
    {
      boolean fin = false;

      if (d != null)
	{
	  int i;
	  
	  offscreenG.setFont(f);
	  offscreenG.setColor(bgColor);
	  offscreenG.fill3DRect(0, 0,
				this.size().width - 1, this.size().height - 1, 
				true);
	  offscreenG.setColor(fgColor);
	  for(i = 0; i < linesNumber; i++)
	    {
	      String line;

              try
		{
		  line = (String)mangaribou.elementAt(index + i);
		  if (line != null)
		    offscreenG.drawString(line, 5, fontSize * i + fontSize);
		  else
		    fin = true;
		}
              catch(IndexOutOfBoundsException e) {}
	    }
	} 
      
      if (index >= mangaribou.size())
	index = 0;
      else
	index += linesNumber;      
    }  
}


