/*
 * JVirus is a PacMan clone, written in Java.
 *
 * Please read "http://jvirus.sourceforge.net/jvirus_licence.txt" for copyrights.
 * 
 * The sourcecode is designed and created with
 * Sun J2SDK 1.3 and Microsoft Visual J++ 6.0
 *
 * JVirus homepage: http://jvirus.sourceforge.net
 *
 * autor: Slawa Weis
 * email: slawaweis@animatronik.net
 *
 */

package org.game.JVirus;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;

import org.game.JVirus.res.*;

/**
 * Main panel. This panel contains the control panel and
 * the DisplayBackPanel. The DisplayBackPanel contain
 * the Display and the message panel.
 *
 * @see     org.game.JVirus.DisplayBackPanel
 */
public class JVirusPanel extends JPanel
{
 /**
  * Image for solved or not solved levels.
  */
 protected BufferedImage redPointImage    = null;
 /**
  * Image for solved or not solved levels.
  */
 protected BufferedImage yellowPointImage = null;
 /**
  * Image for solved or not solved levels.
  */
 protected BufferedImage greenPointImage  = null;

 /**
  * reference to the ActionControl class. ActionControl controls the gameplay.
  */
 protected ActionControl actionControl = null;
 /**
  * Call back Class from ActionControl
  */
 protected GameListener gameListener = new GameListener();
 /**
  * Display of this game.
  */
 protected Display display = null;
 /**
  * DisplayBackPanel of this game.
  */
 protected DisplayBackPanel backPanel = null;
 /**
  * Label for score points
  */
 protected JLabel jl_score = null;
 /**
  * Label for life points
  */
 protected JLabel jl_lifes = null;

 /**
  * reference to the InfoScreen of JVirusFrame
  * 
  * @see     org.game.JVirus.JVirusFrame.JVirusInfoScreen
  */
 protected JVirusFrame.JVirusInfoScreen infoScreen = null;

 /**
  * reference to the JVirusFrame
  * 
  * @see     org.game.JVirus.JVirusFrame
  */
 protected JFrame parent    = null;
// protected JList glist = null;
 /**
  * List with levels
  */
 protected JList level_list = null;
 /**
  * Listener for menu events
  */
 protected MenuActionListener menuActionListener = new MenuActionListener();
 /**
  * Listener for music choose and music on/off events
  */
 protected MusicActionListener musicActionListener = new MusicActionListener();
 /**
  * reference to the music on/off menu
  */
 protected JCheckBoxMenuItem muteMenu = null;
 /**
  * reference to slider of music control
  */
 protected JVSlider jvs_midi = null;
 /**
  * reference to slider of sound control
  */
 protected JVSlider jvs_sound = null;

 /**
  * Message if the user lose the level
  * 
  * @see     org.game.JVirus.DisplayBackPanel
  */
 protected MessagePanel loseMessage = null;
 /**
  * Message if the user win the level
  * 
  * @see     org.game.JVirus.DisplayBackPanel
  */
 protected MessagePanel winMessage = null;
 /**
  * Message if the user lose the whole game
  * 
  * @see     org.game.JVirus.DisplayBackPanel
  */
 protected MessagePanel loseMessage2 = null;
 /**
  * Message if the user win the whole game
  * 
  * @see     org.game.JVirus.DisplayBackPanel
  */
 protected MessagePanel winMessage2 = null;

 /**
  * List of references to music menus (1-9)
  */
 protected JCheckBoxMenuItem sound_menus [] = null;
 /**
  * for Random selection of the background music
  */
 protected Random sound_random = new Random();

 /**
  * the array of avable levels
  * 
  * @see     org.game.JVirus.Levels
  */
 protected Vector vecLevels = null;

 /**
  * Message to choose a level
  * 
  * @see     org.game.JVirus.DisplayBackPanel
  */
 protected ContinueGamePanel continueGamePanel = null;

 /**
  * if the user select help, the help panel is showing in this ScrollPane
  * 
  * @see     org.game.JVirus.JVirusPanel.HelpViewer
  */
 protected JScrollPane helpViewer_scrollPane = null;

 /**
  * Main constructor
  *
  * @param parent     Frame parent
  * @param infoScreen infoscreen reference
  */
 public JVirusPanel(JFrame parent, JVirusFrame.JVirusInfoScreen infoScreen)
  {
  super(new BorderLayout());

  this.parent = parent;
  this.infoScreen = infoScreen;

  // get the levels
  vecLevels = Levels.getLevels();

  // create Images for solved or not solved levels
  redPointImage    = createPointImage(Color.red);
  yellowPointImage = createPointImage(Color.yellow);
  greenPointImage  = createPointImage(Color.green);

  // create many UI components

  display = new Display();
  backPanel = new DisplayBackPanel(display);
  actionControl = new ActionControl(display, parent, gameListener);

  add(BorderLayout.NORTH, createControlPanel());
  add(BorderLayout.CENTER, backPanel);

  loseMessage  = new MessagePanel("You lose :(");
  winMessage   = new MessagePanel("You win :)");
  loseMessage2 = new MessagePanel("You lose all you lifes :(. Start again and don't give up!");
  winMessage2  = new MessagePanel("Congratulation! You solved all levels :)");

  continueGamePanel = new ContinueGamePanel();

  // show the select level message
  backPanel.showDialogPanel(continueGamePanel);
  }

 /**
  * creates the control panel
  */
 protected JPanel createControlPanel()
  {
  JPanel controlPanel = new JPanel(new BorderLayout());
  JPanel leftPanel    = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
  JPanel rightPanel   = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));

  controlPanel.add(BorderLayout.CENTER, leftPanel);
  controlPanel.add(BorderLayout.EAST,   rightPanel);

  controlPanel.setBorder(new LineBorder(SwingTheme.black, 1));

  JMenuBar jmb = new JMenuBar();
  jmb.setBorderPainted(false);

  JMenu jm, jm2 = null;
  JMenuItem jmi = null;

  // first menu

  jm = createJMenu("Game");
  jm.add(createJMenuItem("New Game",   "NEW", KeyEvent.VK_N));
  jm.add(createJMenuItem("Other Level", "LEVEL", KeyEvent.VK_L));
  jm.add(createJMenuItem("Pause Game", "PAUSE", KeyEvent.VK_P));
//  jm.add(createJMenuItem("Reset Game", "RESET"));
  jm.add(createSeparatorVertical());
  jm.add(createJMenuItem("Quit",       "EXIT", KeyEvent.VK_Q));
  jmb.add(jm);

/*
  // second menu

  jm = createJMenu("View", "View");
  jm2 = createJMenu("Size", "View.Size");
  jm2.add(createJMenuItem("640x480",  "R1"));
  jm2.add(createJMenuItem("800x600",  "R2"));
  jm2.add(createJMenuItem("1024x768", "R3"));
  jm2.add(createSeparator20_1());
  jm2.add(createJMenuItem("Fullscreen", "FS"));
  jm.add(jm2);
  jmb.add(jm);
*/

  // third menu, sound menu

  // if -Djvirus.sound=disabled, don't create the menus
  boolean sound_disabled = false;
  String jvirus_sound = System.getProperty("jvirus.sound");
  if(jvirus_sound != null && jvirus_sound.equals("disabled"))
    sound_disabled = true;

  if(!sound_disabled)
    {
    jm = createJMenu("Sound");
    sound_menus = new JCheckBoxMenuItem[Sound.getBackgroundCount()];
    ButtonGroup sound_menu_group = new ButtonGroup();
    for(int i = 0; i < Sound.getBackgroundCount(); i++)
       jm.add(sound_menus[i] = createSoundMenuItem("background " + (i+1), "" + i, false, sound_menu_group, Integer.toString(i+1).charAt(0)));
    jm.add(createSeparatorVertical());
    jm.add(muteMenu = createSoundMenuItem("no sound", "-1", false, null, KeyEvent.VK_S));
    jmb.add(jm);
    }

  // forth menu

  jm = createJMenu("Help");
  jm.add(createJMenuItem("How to Play?", "HELP", KeyEvent.VK_H));
  jm.add(createSeparatorVertical());
  jm.add(createJMenuItem("About",        "ABOUT", KeyEvent.VK_A));
  jmb.add(jm);

  leftPanel.add(jmb);
  leftPanel.add(createSeparatorHorizontal());

  if(!sound_disabled)
    {
    // slider for music volume
    JLabel music = new JLabel("Music:", JLabel.CENTER);
    music.setPreferredSize(new Dimension(40, 20));
    leftPanel.add(music);
    jvs_midi = new JVSlider(0, 100, 50);
    jvs_midi.addChangeListener(musicActionListener);
    leftPanel.add(jvs_midi);
    leftPanel.add(createSeparatorHorizontal());

    // slider for sound volume
    JLabel sound = new JLabel("Sound:", JLabel.CENTER);
    sound.setPreferredSize(new Dimension(40, 20));
    leftPanel.add(sound);
    jvs_sound = new JVSlider(0, 100, 80);
    jvs_sound.addChangeListener(musicActionListener);
    leftPanel.add(jvs_sound);
    leftPanel.add(createSeparatorHorizontal());
    }

  // Score label
  JLabel jl_score_name = new JLabel("Score:", JLabel.CENTER);
  jl_score_name.setPreferredSize(new Dimension(50, 20));
  leftPanel.add(jl_score_name);
  jl_score = new JLabel("0", JLabel.CENTER);
  jl_score.setPreferredSize(new Dimension(80, 20));
  leftPanel.add(jl_score);
  leftPanel.add(createSeparatorHorizontal());

  // Lifes label
  JLabel jl_lifes_name = new JLabel("Lifes:", JLabel.CENTER);
  jl_lifes_name.setPreferredSize(new Dimension(50, 20));
  leftPanel.add(jl_lifes_name);
  jl_lifes = new JLabel("" + actionControl.getAvatar().gameLifes, JLabel.CENTER);
  jl_lifes.setPreferredSize(new Dimension(80, 20));
  leftPanel.add(jl_lifes);
  leftPanel.add(createSeparatorHorizontal());

  // Quit button
  rightPanel.add(createJButton("Quit",       "EXIT"));

  return controlPanel;
  }

 /**
  * ask the user if he want to quit the
  * game. If yes, stop the current game
  * and close the sound system
  */
 public boolean quitGame()
  {
  if(JOptionPane.YES_OPTION == 
     JOptionPane.showConfirmDialog(parent,
                                   "Quit the programm?",
                                   "Quit",
                                   JOptionPane.YES_NO_CANCEL_OPTION,
                                   JOptionPane.QUESTION_MESSAGE)
    )
    {
    stopGame();
    Sound.closeSoundSystem();
    return true;
    }
  return false;
  }

 /**
  * start the game
  *
  * @param level the level to play
  */
 protected void startGame(Matrix level)
  {
  // set level to display
  display.reset(level);
  // start game
  actionControl.startGame(level);

  // if sound on
  if(sound_menus != null)
    {
    // random music from 0-8
    int sound_number = sound_random.nextInt(Sound.getBackgroundCount());
    sound_menus[sound_number].setSelected(true);
    // play music
    Sound.playBackground(sound_number);
    }
  }

 /**
  * stop the game
  */
 protected void stopGame()
  {
  // stop music
  Sound.stopBackground();
  actionControl.stopGame();

  // show the select level message
  backPanel.showDialogPanel(continueGamePanel);
  }

 /**
  * Callback listener for ActionControl
  *
  * @see     org.game.JVirus.ActionControl
  */
 protected class GameListener implements ActionControl.IGameListener
 {
  /**
   * game over
   *
   * @param reason ActionControl.IGameListener.WIN or ActionControl.IGameListener.LOSE
   */
  public void gameOver(int reason)
   {
   Sound.stopBackground();
   actionControl.stopGame();

   Avatar avatar = actionControl.getAvatar();

   jl_score.setText("" + actionControl.getAvatar().gameScore);
   jl_lifes.setText("" + actionControl.getAvatar().gameLifes);

   if(reason == WIN)
     {
     int i;
     // check if all levels solved 
     for(i = 0; i < avatar.solvedLevels.length; i++)
        if(avatar.solvedLevels[i] != Avatar.LEVEL_SOLVED)
          break;

     // if all levels solved, show "win the whole game message"
     if(i == avatar.solvedLevels.length)
       backPanel.showDialogPanel(winMessage2);
     else
       backPanel.showDialogPanel(winMessage);
     }
   else
     {
     // if the avatar lose all his lifes
     if(avatar.gameLifes < 0)
       {
       // reset avatar, start again
       actionControl.resetAvatar();
       actionControl.getAvatar().x = avatar.x;
       actionControl.getAvatar().y = avatar.y;
       jl_lifes.setText("" + actionControl.getAvatar().gameLifes);
       backPanel.showDialogPanel(loseMessage2);
       }
     else
       backPanel.showDialogPanel(loseMessage);
     }
   }
  /**
   * score from avatar changed
   *
   * @param avatar the current avatar
   */
  public void scoreChanged(Avatar avatar)
   {
   // set the value to label
   jl_score.setText("" + (avatar.gameScore + avatar.gameScoreCurrentLevel));
   }
  /**
   * lifes from avatar changed
   *
   * @param avatar the current avatar
   */
  public void lifesChanged(Avatar avatar)
   {
   // set the value to label
   jl_lifes.setText("" + (avatar.gameLifes + avatar.gameLifesCurrentLevel));
   }
 }

 /**
  * menu listener for menu and key events
  */
 protected class MenuActionListener implements ActionListener
 {
  public void actionPerformed(ActionEvent e)
   {
        // new game
        if(e.getActionCommand().equals("NEW"))
          {
          if(JOptionPane.YES_OPTION == 
             JOptionPane.showConfirmDialog(parent,
                                   "New game?",
                                   "New Game",
                                   JOptionPane.YES_NO_CANCEL_OPTION,
                                   JOptionPane.QUESTION_MESSAGE)
            )
            {
            if(actionControl.isRunning())
              stopGame();

            actionControl.resetAvatar();
            jl_score.setText("" + actionControl.getAvatar().gameScore);
            jl_lifes.setText("" + actionControl.getAvatar().gameLifes);
            }
          }
        // other level to play
   else if(e.getActionCommand().equals("LEVEL"))
          {
          if(actionControl.isRunning())
            stopGame();
          }
        // reset the level, not implemented
   else if(e.getActionCommand().equals("RESET"))
          {
          }
        // pause the game
   else if(e.getActionCommand().equals("PAUSE"))
          {
          if(actionControl.isRunning())
            {
            if(!actionControl.isPaused())
              Sound.stopBackground();
            else
              Sound.playLastBackground();

            actionControl.pauseGame(!actionControl.isPaused());
            }
          }
        // play a selected level from level list
   else if(e.getActionCommand().equals("Play"))
          {
          if(actionControl.getAvatar().solvedLevels[level_list.getSelectedIndex()] != Avatar.LEVEL_CAN_NOT_SOLVE)
            {
            backPanel.hideDialogPanel();
            // copy the level matrix
            startGame(new Matrix((Matrix)level_list.getSelectedValue()));
            }
          }
        // for lose or win messages
   else if(e.getActionCommand().equals("OK"))
          {
          backPanel.hideDialogPanel();
          backPanel.showDialogPanel(continueGamePanel);
          }
        // quit the game
   else if(e.getActionCommand().equals("EXIT"))
          {
          if(quitGame())
            {
            parent.setVisible(false);
            parent.dispose();
            System.exit(0);
            }
          }
        // fullscreen mode, not implemented
   else if(e.getActionCommand().equals("FS"))
          {
          }
        // show about dialog
   else if(e.getActionCommand().equals("ABOUT"))
          {
          infoScreen.setVisible(true);
          }
        // show help dialog
   else if(e.getActionCommand().equals("HELP"))
          {
          if(helpViewer_scrollPane == null)
            {
            helpViewer_scrollPane = new JScrollPane(new HelpViewer());
            helpViewer_scrollPane.setPreferredSize(new Dimension(600, 400));
            }

          JOptionPane.showMessageDialog(parent, helpViewer_scrollPane, "Instruction", JOptionPane.OK_OPTION);
          }
   }
 }

 /**
  * menu listener for music menu events (1-9 or music on/of)
  */
 protected class MusicActionListener implements ActionListener, ChangeListener
 {
  public void actionPerformed(ActionEvent e)
   {
        if(e.getActionCommand().equals("-1"))
          Sound.setBackgroundMute(muteMenu.isSelected());
   else if(actionControl.isRunning() && !actionControl.isPaused())
          {
          muteMenu.setSelected(false);
          Sound.playBackground(Integer.parseInt(e.getActionCommand()));
          }
   }

  public void stateChanged(ChangeEvent e)
   {
   if(e.getSource() == jvs_midi)
     Sound.setBackgroundVolume(jvs_midi.getPosition());
   else
     Sound.setFXVolume(jvs_sound.getPosition());
   }
 }
/*
 protected class NewGamePanel extends JPanel
 {
  protected final CompoundBorder border = new CompoundBorder(new EmptyBorder(20, 20, 20, 20), new LineBorder(SwingTheme.black, 1));

  public NewGamePanel()
   {
   super(new GridLayout(1, 2));

   setOpaque(false);

   JPanel left_center = new JPanel(new BorderLayout());
   JLabel left_center_label = new JLabel("Enter Name:");
   left_center_label.setBorder(new EmptyBorder(2, 5, 2, 5));
   left_center.add(BorderLayout.WEST, left_center_label);
   JTextField left_center_jtf = new JTextField("JVirus Game");
   left_center_jtf.setMaximumSize(new Dimension(100, 20)); 
   left_center_jtf.setMinimumSize(new Dimension(100, 20)); 
   left_center_jtf.setPreferredSize(new Dimension(100, 20)); 
   left_center_jtf.setSize(new Dimension(100, 20)); 
   left_center.add(BorderLayout.CENTER, left_center_jtf);

   JPanel left_bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
   JButton jb_new_game = new JButton("New Game");
   jb_new_game.addActionListener(menuActionListener);
   left_bottom.add(jb_new_game);

   JPanel left = new JPanel(new BorderLayout());
   left.setBorder(border);
   left.setOpaque(false);
   left.add(BorderLayout.NORTH, new JLabel("Start New Game", JLabel.CENTER));
   left.add(BorderLayout.CENTER, left_center);
   left.add(BorderLayout.SOUTH, left_bottom);
   add(left);

   String list [] = new String [] { "111", "222", "333", "333", "333", "333", "333", "222", "333", "333", "333", "333", "333", "222", "333", "333", "333", "333", "333", "222", "333", "333", "333", "333", "333" };

   glist = new JList(list);
   JScrollPane glist_jsp = new JScrollPane(glist);
   glist_jsp.setBorder(border);
   glist_jsp.setOpaque(false);
   glist_jsp.getViewport().setOpaque(false);

   JPanel right_bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
   JButton jb_con_game = new JButton("Continue");
   jb_con_game.addActionListener(menuActionListener);
   right_bottom.add(jb_con_game);

   JPanel right = new JPanel(new BorderLayout());
   right.setBorder(border);
   right.setOpaque(false);
   right.add(BorderLayout.NORTH, new JLabel("Continue a existing Game", JLabel.CENTER));
   right.add(BorderLayout.CENTER, glist_jsp);
   right.add(BorderLayout.SOUTH, right_bottom);
   add(right);
   }
 }
*/
 /**
  * the selection of level message
  */
 protected class ContinueGamePanel extends JPanel
 {
  protected final CompoundBorder border = new CompoundBorder(new EmptyBorder(20, 20, 20, 20), new LineBorder(SwingTheme.black, 1));

  /**
   * simply constructor. Left the help HTML side, right the level list.
   */
  public ContinueGamePanel()
   {
   super(new GridLayout(1, 2));

   setOpaque(false);

   JPanel left = new JPanel(new BorderLayout(1, 1));
   left.setBorder(border);
   left.setOpaque(false);
   left.add(BorderLayout.NORTH, createLabel("Help:"));
   left.add(BorderLayout.CENTER, new JScrollPane(new HelpViewer()));
   add(left);

   JPanel right_top = new JPanel(new GridLayout(4, 1));
   right_top.setOpaque(false);
   right_top.add(createLabel("Select the Level:"));
   right_top.add(createLabel("solved", greenPointImage));
   right_top.add(createLabel("you can play this level", yellowPointImage));
   right_top.add(createLabel("you must solve another level first", redPointImage));

   level_list = new JList(vecLevels);
   level_list.setSelectedIndex(0);
   level_list.setCellRenderer(new LevelListRenderer());
   JScrollPane level_list_jsp = new JScrollPane(level_list);
   level_list_jsp.setBorder(border);
   level_list_jsp.setOpaque(false);
   level_list_jsp.getViewport().setOpaque(false);

   JPanel right_bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
   right_bottom.setOpaque(false);
   JButton jb_play_game = new JButton("Play");
   jb_play_game.addActionListener(menuActionListener);
   right_bottom.add(jb_play_game);

   JPanel right = new JPanel(new BorderLayout());
   right.setBorder(border);
   right.setOpaque(false);
   right.add(BorderLayout.NORTH, right_top);
   right.add(BorderLayout.CENTER, level_list_jsp);
   right.add(BorderLayout.SOUTH, right_bottom);
   add(right);
   }

  /**
   * help function
   */
  protected JLabel createLabel(String name)
   {
   JLabel jl = new JLabel(name, JLabel.CENTER);
   return jl;
   }

  /**
   * help function
   */
  protected JLabel createLabel(String name, BufferedImage image)
   {
   JLabel jl = new JLabel(name, new ImageIcon(image), JLabel.LEFT);
   jl.setBorder(new EmptyBorder(0, 20, 0, 0));
   return jl;
   }

  /**
   * JList CellRenderer for level list.
   */
  protected class LevelListRenderer extends JPanel implements ListCellRenderer
  {
   protected JLabel point = null;
   protected JLabel name = null;

   protected ImageIcon rii = new ImageIcon(redPointImage);
   protected ImageIcon yii = new ImageIcon(yellowPointImage);
   protected ImageIcon gii = new ImageIcon(greenPointImage);

   protected Border border_not_focus = new EmptyBorder(1, 1, 1, 1);
   protected Border border_focus = new LineBorder(SwingTheme.black, 1);

   public LevelListRenderer()
    {
    super(new BorderLayout());

    point = new JLabel();
    name = new JLabel();

    add(BorderLayout.WEST, point);
    add(BorderLayout.CENTER, name);

    setBackground(SwingTheme.primary3);
    setOpaque(false);
    }

   public Component getListCellRendererComponent(JList list,
                                                 Object value,
                                                 int index,
                                                 boolean isSelected,
                                                 boolean cellHasFocus)
    {
    Avatar avatar = actionControl.getAvatar();

    name.setText(((Matrix)value).toString());

    switch(avatar.solvedLevels[index])
          {
          case Avatar.LEVEL_CAN_NOT_SOLVE:
               point.setIcon(rii);
               break;
          case Avatar.LEVEL_CAN_SOLVE:
               point.setIcon(yii);
               break;
          case Avatar.LEVEL_SOLVED:
               point.setIcon(gii);
               break;
          }

    if(cellHasFocus)
      setBorder(border_focus);
    else
      setBorder(border_not_focus);

    if(isSelected)
      setOpaque(true);
    else
      setOpaque(false);

    return this;
    }
  }
 }

 /**
  * Message panel for win or lose messages
  */
 protected class MessagePanel extends JPanel// implements ComponentListener
 {
  protected JButton messageBox_OK = null;

  /**
   * simply constructor.
   *
   * @param text message text
   */
  public MessagePanel(String text)
   {
   super(new BorderLayout());

   setOpaque(false);

   setBorder(new EmptyBorder(20, 20, 20, 20));

   JLabel jl = new JLabel(text, JLabel.CENTER);
   jl.setFont(new Font(jl.getFont().getFontName(), Font.PLAIN, 20));
   add(BorderLayout.CENTER, jl);

   JPanel south = new JPanel(new FlowLayout(FlowLayout.CENTER));
   south.setOpaque(false);
   messageBox_OK = new JButton("OK");
   messageBox_OK.addActionListener(menuActionListener);
//   messageBox_OK.requestFocus();
   south.add(messageBox_OK);

   add(BorderLayout.SOUTH, south);
   }
/*
  public void componentHidden(ComponentEvent e)  {}
  public void componentMoved(ComponentEvent e)   {}
  public void componentResized(ComponentEvent e) {}
  public void componentShown(ComponentEvent e)
   {
   System.out.println("1111");
   messageBox_OK.requestFocus();
   }
*/
 }

///////////////////////////////////////////////////////////////////
// help functions

 /**
  * help function. 20x20 pixel image for solved or not solved levels.
  *
  * @param color point color
  */
 protected BufferedImage createPointImage(Color color)
  {
  BufferedImage bi = new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB);
  Graphics2D g2 = bi.createGraphics();
  g2.setBackground(new Color(0, 0, 0, 0));
  g2.clearRect(0, 0, 19, 19);
  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//  g2.setColor(new Color(0, 0, 0, 0));
//  g2.fill(new Rectangle(0, 0, 19, 19));
  g2.setColor(color);
  g2.fillOval(5, 5, 10, 10);
  return bi;
  }

 /**
  * help function. Vertical separator for the menubar
  */
 protected JPanel createSeparatorVertical()
  {
  return createSeparator(new Dimension(20, 1));
  }

 /**
  * help function. Horizontal separator for the menubar
  */
 protected JPanel createSeparatorHorizontal()
  {
  return createSeparator(new Dimension(1, 20));
  }

 /**
  * help function. Separator for the menubar
  */
 protected JPanel createSeparator(Dimension dim)
  {
  JPanel jp = new JPanel(null);
  jp.setBackground(SwingTheme.black);
  jp.setPreferredSize(dim);
  return jp;
  }

 /**
  * help function. Creates a JMenu
  *
  * @param title menu title
  */
 protected JMenu createJMenu(String title)
  {
  JMenu jm = new JMenu(title);
  jm.setBounds(0, 0, 0, 0);
//  jm.setBorderPainted(false);
  jm.setBorder(new EmptyBorder(2, 2, 2, 2));
  return jm;
  }

 /**
  * help function. Creates a JMenuItem
  *
  * @param title   menu title
  * @param ac      action command
  * @param keycode key command
  */
 protected JMenuItem createJMenuItem(String title, String ac, int keycode)
  {
  JMenuItem jmi = new JMenuItem(title);
  jmi.setActionCommand(ac);
  jmi.addActionListener(menuActionListener);
  jmi.setAccelerator(KeyStroke.getKeyStroke(keycode, 0));
  return jmi;
  }

 /**
  * help function. Creates a JCheckBoxMenuItem for music menu
  *
  * @param title    menu title
  * @param ac       action command
  * @param keycode  key command
  * @param selected JCheckBoxMenuItem selected or not
  * @param bg       button group of music menu buttons
  */
 protected JCheckBoxMenuItem createSoundMenuItem(String title, String ac, boolean selected, ButtonGroup bg, int keycode)
  {
  JCheckBoxMenuItem jmi = new JCheckBoxMenuItem(title, selected);
  jmi.setActionCommand(ac);
  jmi.addActionListener(musicActionListener);
  jmi.setAccelerator(KeyStroke.getKeyStroke(keycode, 0));
  if(bg != null) bg.add(jmi);
  return jmi;
  }

 /**
  * help function. Creates a JButton
  *
  * @param title    menu title
  * @param ac       action command
  */
 protected JButton createJButton(String title, String ac)
  {
  JButton jb = new JButton(title);
  jb.setActionCommand(ac);
  jb.addActionListener(menuActionListener);
  jb.setBounds(0, 0, 0, 0);
  jb.setBorder(new EmptyBorder(2, 5, 2, 5));
  return jb;
  }

/*
 protected JLabel createTextLabel()
  {
  JLabel label = new JLabel("TextLabel ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ");
  label.setBorder(new EmptyBorder(0, 10, 0, 10));
  label.setForeground(Color.yellow);
//  textLabel.setSize(800, 30);
//  textLabel.setLocation(0, 532);
  return label;
  }
*/
// help functions
///////////////////////////////////////////////////////////////////

 /**
  * Panel that shows the Help HTML file
  */
 protected class HelpViewer extends JEditorPane
 {
  /**
   * Simply constructor.
   */
  public HelpViewer()
   {
   super();
   setBorder(null);
   setOpaque(true);
   setEditable(false);
   try
      {
      setPage(Resource.class.getResource("help.html"));
      }
   catch(IOException e)
        {
        System.out.println(e);
        }
   }
 }
}