// =========================================================
// Рисование строки текста по буквам
//
// (C) Фролов А.В, 1997
//
// E-mail: frolov@glas.apc.org
// WWW:    http://www.glasnet.ru/~frolov
//            или
//         http://www.dials.ccas.ru/frolov
// =========================================================
import java.applet.*;
import java.awt.*;

public class HorzScroll extends Applet implements Runnable
{
	// Ссылка на задачу рисования строки текста
  Thread m_HorzScroll = null;

	// Значения параметров по умолчанию
  private String m_Str   = "Hello from Java!";
	private String m_Fnt   = "Helvetica";
	private String m_style = "BOLD";
	private int m_size     = 12;
	private String m_color = "red";
	private int m_delay    = 50;

	// Имена параметров
  private final String PARAM_str   = "str";
	private final String PARAM_font  = "font";
	private final String PARAM_style = "style";
	private final String PARAM_size  = "size";
	private final String PARAM_color = "color";
	private final String PARAM_delay = "delay";

	// -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
	public String getAppletInfo()
	{
		return "Name: HorzScroll\r\n" +
      "Author: Alexandr Frolov\r\n" +
      "E-mail: frolov@glas.apc.org" +
      "WWW:    http://www.glasnet.ru/~frolov" +
      "Created with Microsoft Visual J++ Version 1.0";
	}

	// -------------------------------------------------------
  // getParameterInfo
  // Иинформация о параметрах
  // -------------------------------------------------------
	public String[][] getParameterInfo()
	{
		String[][] info =
		{
			{ PARAM_str,   "String", "String to draw" },
			{ PARAM_font,  "String", "Font name" },
			{ PARAM_style, "String", "Font style" },
			{ PARAM_size,  "String", "Font size" },
			{ PARAM_color, "String", "String color" },
			{ PARAM_delay, "int",    "Output delay" },
		};
		return info;		
	}

	// -------------------------------------------------------
  // init
  // Метод, получающий управление при инициализации аплета
  // -------------------------------------------------------
	public void init()
	{
    // Рабочая строка
    String param;

		// Получение значений параметров
    param = getParameter(PARAM_str);
		if (param != null)
			m_Str = param;

		param = getParameter(PARAM_font);
		if (param != null)
			m_Fnt = param;

		param = getParameter(PARAM_style);
		if (param != null)
			m_style = param;

		param = getParameter(PARAM_size);
		if (param != null)
			m_size = Integer.parseInt(param);

		param = getParameter(PARAM_color);
		if (param != null)
			m_color = param;

		param = getParameter(PARAM_delay);
		if (param != null)
			m_delay = Integer.parseInt(param);
	}

  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование в окне аплета
  // -------------------------------------------------------
	public void paint(Graphics g)
	{
    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();

    // Определяем текущие размеры окна аплета
    dimAppWndDimension = size();
    
    // Выбираем в контекст отображения желтый цвет
    g.setColor(Color.yellow);
    
    // Закрашиваем внутреннюю область окна аплета
    g.fillRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);

    // Выбираем в контекст отображения черный цвет
    g.setColor(Color.black);

    // Рисуем рамку вокруг окна аплета
    g.drawRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);
	}

  // -------------------------------------------------------
  // start
  // Метод вызывается при первом отображении окна аплета
  // -------------------------------------------------------
	public void start()
	{
		if (m_HorzScroll == null)
		{
			m_HorzScroll = new Thread(this);
			m_HorzScroll.start();
		}
	}
	
  // -------------------------------------------------------
  // stop
  // Метод вызывается, когда окно аплета исчезает с экрана
  // -------------------------------------------------------
	public void stop()
	{
		if (m_HorzScroll != null)
		{
			m_HorzScroll.stop();
			m_HorzScroll = null;
		}
	}

	// -------------------------------------------------------
  // run
  // Метод, который работает в рамках отдельной задачи
  // Он выполняет рисование текстовой строки по буквам
  // -------------------------------------------------------
	public void run()
	{
    // Получаем контекст отображения
    Graphics g = getGraphics();

    // Выбираем шрифт в контекст отображения
    if(m_style.equals("BOLD"))
      g.setFont(new Font(m_Fnt, Font.BOLD, m_size));

    else if(m_style.equals("ITALIC"))
      g.setFont(new Font(m_Fnt, Font.ITALIC, m_size));

    else 
      g.setFont(new Font(m_Fnt, Font.PLAIN, m_size));

    // Выбираем цвет в контекст отображения
    if(m_color.equals("red"))
      g.setColor(Color.red);

    else if(m_color.equals("green"))
      g.setColor(Color.green);

    else 
      g.setColor(Color.black);
    
    // Определяем размеры окна аплета
    Dimension dimAppWndDimension = size();

    // Определяем метрики текущего шрифта
    FontMetrics fm = g.getFontMetrics();

    // Номер текущего рисуемого символа строки
    int nCurrentChar = 0;

    // Позиция для рисования по вертикали
    int yPos = fm.getHeight() + 5;

    // Текущая позиция рисования символа по горизонтали
    int nCurrentXPos = 10;

    // Ширина текущего символа в пикселах
    int nCurrentCharWidth;
    
    // Бесконечный цикл рисования
    while (true)
		{
			try
			{
        try
        {
          // Определяем ширину текущего символа
          nCurrentCharWidth = 
            fm.charWidth(m_Str.charAt(nCurrentChar));

          // Массив для преобразования кода символа в сивол
          char[] ch;
    
          // Временная строка
          String s;

          // Создаем массив из одного элемента
          ch = new char[1];

          // Записыаем в него код нажатой клавиши
          ch[0] = m_Str.charAt(nCurrentChar);
    
          // Преобразуем в строку
          s = new String(ch);

          // Рисуем текущий символ в текущей позиции
          g.drawString(s, nCurrentXPos, yPos);

          // Увеличиваем текущую позицию на ширину
          // нарисованного символа
          nCurrentXPos += nCurrentCharWidth;

          // Переходим к следующему символу в строке
          nCurrentChar++;
        }
        // Обработка выхода за пределы строки
        catch (StringIndexOutOfBoundsException e)
        {
          // Сбрасываем номер текущего символа и
          // текущую позицию
          nCurrentChar = 0;
          nCurrentXPos = 10;

          // Перерисовываем окно аплета
          repaint();

          // Задержка после перерисовки окна
          try
          {
            Thread.sleep(500);
          }
          catch (InterruptedException ee)
          {
            stop();
          }
        }

        // Задержка между рисованием отдельных символов        
				Thread.sleep(m_delay);
			}
			catch (InterruptedException e)
			{
				stop();
			}
		}
	}
}
