import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.util.Vector;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;
import java.awt.image.MemoryImageSource;

public class MemoryApplet extends Applet
{
  MemorySettingsPanel memorySettingsPanel;
  MemoryPlayPanel memoryPlayPanel;

  public void init()
  {
    setLayout(new BorderLayout());
    MemorySettings memorySettings = new MemorySettings(2,20);

    memorySettingsPanel = new MemorySettingsPanel(memorySettings);
    memoryPlayPanel = new MemoryPlayPanel(memorySettings);
    memorySettingsPanel.sendMemoryPlayPanel(memoryPlayPanel);
    memoryPlayPanel.sendMemorySettingsPanel(memorySettingsPanel);
    memoryPlayPanel.sendSoundType(MemorySound.NEGATIVE_FEEDBACK);

    add(memorySettingsPanel,BorderLayout.EAST);
    add(memoryPlayPanel,BorderLayout.CENTER);

    MemorySound.badRange = getAudioClip(getDocumentBase(),"badrange.wav");
    MemorySound.goodRange = getAudioClip(getDocumentBase(),"goodrange.wav");
    MemorySound.badMatch = getAudioClip(getDocumentBase(),"badmatch.wav");
    MemorySound.goodMatch = getAudioClip(getDocumentBase(),"goodmatch.wav");
  }
}

class MemorySettingsPanel extends Panel implements ActionListener, ItemListener
{
  private TextField matchesText;
  private TextField groupsText;
  private TextField squaresText;
  private TextField scoreText;
  private Checkbox  badSounds;
  private Checkbox  goodSounds;
  private Button    incMatches;
  private Button    decMatches;
  private Button    incGroups;
  private Button    decGroups;
  private Button    restartButton;
  private int matches;
  private int groups;
  private int score;
  private int sounds;
  private MemorySettings memorySettings;
  private MemoryPlayPanel memoryPlayPanel;

  public MemorySettingsPanel(MemorySettings mem)
  {
    memorySettings = mem;
    matches = mem.matches;
    groups = mem.groups;

    setLayout(new BorderLayout());
    setBackground(MemoryPlayPanel.BACKGROUND_COLOR);

    Panel p = new Panel(new GridLayout(15,1));

    p.add(new Label("Number of matches"));
    Panel p12 = new Panel(new BorderLayout());
    decMatches = new Button("<");
    incMatches = new Button(">");
    decMatches.addActionListener(this);
    incMatches.addActionListener(this);
    p12.add(decMatches,BorderLayout.WEST);
    p12.add(incMatches,BorderLayout.EAST);
    matchesText = new TextField(Integer.toString(memorySettings.matches),3);
    matchesText.setEditable(false);
    p12.add(matchesText,BorderLayout.CENTER);
    p.add(p12);
    p.add(new Label(""));

    p.add(new Label("Number of groups"));
    Panel p22 = new Panel(new BorderLayout());
    decGroups = new Button("<");
    incGroups = new Button(">");
    decGroups.addActionListener(this);
    incGroups.addActionListener(this);
    p22.add(decGroups,BorderLayout.WEST);
    p22.add(incGroups,BorderLayout.EAST);
    groupsText = new TextField(Integer.toString(memorySettings.groups),3);
    groupsText.setEditable(false);
    p22.add(groupsText,BorderLayout.CENTER);
    p.add(p22);
    p.add(new Label(""));

    p.add(new Label("Number of squares"));
    squaresText = new TextField(Integer.toString(memorySettings.squares),3);
    squaresText.setEditable(false);
    p.add(squaresText);
    p.add(new Label(""));

    p.add(new Label("Score"));
    scoreText = new TextField(0);
    scoreText.setEditable(false);
    p.add(scoreText);
    p.add(new Label(""));

    CheckboxGroup soundsGroup = new CheckboxGroup();
    badSounds = new Checkbox("Negative Sounds",true,soundsGroup);
    goodSounds = new Checkbox("Positive Sounds",false,soundsGroup);
    p.add(new Label("Audible Feedback"));
    p.add(badSounds);
    p.add(goodSounds);
    badSounds.addItemListener(this);
    goodSounds.addItemListener(this);
    sounds = MemorySound.NEGATIVE_FEEDBACK;

    restartButton = new Button("Restart");
    restartButton.addActionListener(this);

    add(p,BorderLayout.NORTH);
    add(restartButton,BorderLayout.SOUTH);
  }

  public void sendMemoryPlayPanel(MemoryPlayPanel memoryPlayPanel)
  {
    this.memoryPlayPanel = memoryPlayPanel;
  }

  public void sendScore(int score)
  {
    scoreText.setText(Integer.toString(score));
  }

  public void actionPerformed(ActionEvent ae)
  {
    boolean recomputeSquares = false;
    Object source = ae.getSource();

    if (source == incMatches) {
      if (matches < 20) {
        MemorySound.playSound(sounds,MemorySound.GOOD_RANGE);
        matches++;
        matchesText.setText(Integer.toString(matches));
        recomputeSquares = true;
      } else {
        MemorySound.playSound(sounds,MemorySound.BAD_RANGE);
      }
    }

    if (source == decMatches) {
      if (matches > 2) {
        MemorySound.playSound(sounds,MemorySound.GOOD_RANGE);
        matches--;
        matchesText.setText(Integer.toString(matches));
        recomputeSquares = true;
      } else {
        MemorySound.playSound(sounds,MemorySound.BAD_RANGE);
      }
    }

    if (source == incGroups) {
      if (groups < 20) {
        MemorySound.playSound(sounds,MemorySound.GOOD_RANGE);
        groups++;
        groupsText.setText(Integer.toString(groups));
        recomputeSquares = true;
      } else {
        MemorySound.playSound(sounds,MemorySound.BAD_RANGE);
      }
    }

    if (source == decGroups) {
      if (groups > 2) {
        MemorySound.playSound(sounds,MemorySound.GOOD_RANGE);
        groups--;
        groupsText.setText(Integer.toString(groups));
        recomputeSquares = true;
      } else {
        MemorySound.playSound(sounds,MemorySound.BAD_RANGE);
      }
    }

    if (recomputeSquares) {
        memorySettings.resetValues(matches,groups);
        squaresText.setText(Integer.toString(memorySettings.squares));
    }

    if (source == restartButton) {
      memoryPlayPanel.sendNewSettings(memorySettings);
    }
  }


  public void itemStateChanged(ItemEvent ie)
  {
    Object source = ie.getSource();

    if (source == badSounds) {
      sounds = MemorySound.NEGATIVE_FEEDBACK;
      memoryPlayPanel.sendSoundType(sounds);
    }

    if (source == goodSounds) {
      sounds = MemorySound.POSITIVE_FEEDBACK;
      memoryPlayPanel.sendSoundType(sounds);
    }
  }

}

class MemoryPlayPanel extends Panel implements MouseListener
{
  // Vector v will hold the status of each piece
  // The value of a piece at (x,y) is elementAt(y*mem.height+x)
  private Graphics g;
  private MemorySettings mem;
  private MemorySettingsPanel memorySettingsPanel;
  private Vector v;
  private Vector selectionCoords = new Vector();
  private int offsetX,offsetY;
  private int selectedX, selectedY;
  private Image hiddenImage;
  private int score;
  private int sounds;

  public MemoryPlayPanel(MemorySettings memorySettings)
  {
    setBounds(10,10,300,400);
    setBackground(BACKGROUND_COLOR);

    mem = new MemorySettings(memorySettings);
    addMouseListener(this);

    setupNewGame();
  }

  public void setupNewGame()
  {
    // First, create a vector with all possible images
    MemoryImageGenerator mig = new MemoryImageGenerator();
    hiddenImage = mig.createImage(-1);

    Vector imageVector = new Vector(MemoryImageGenerator.IMAGES);
    for (int i=0; i < MemoryImageGenerator.IMAGES; i++) {
      imageVector.addElement(mig.createImage(i));
    }

    // Next, create a vector with all of the pieces
    Vector pieceVector = new Vector(mem.squares);
    for (int i=0; i < mem.groups; i++) {

      // Get an image for this group
      int imageIndex = (int)(Math.random()*imageVector.size());
      Object image = imageVector.elementAt(imageIndex);
      imageVector.removeElementAt(imageIndex);

      for (int u=0; u < mem.matches; u++) {
        pieceVector.addElement(new Triplet((Object)HIDDEN,image,new Integer(i)));
      }
    }

    // Now place the pieces randomly on the board
    v = new Vector(mem.squares);
    for (int i=0; i < mem.squares; i++) {
      int pieceIndex = (int)(Math.random()*pieceVector.size());
      Object piece = pieceVector.elementAt(pieceIndex);
      pieceVector.removeElementAt(pieceIndex);
      v.addElement(piece);
    }

    score = 0;
    selectionCoords.removeAllElements();

    // Make sure all of this gets drawn
    repaint();
  }

  public void paint(Graphics g)
  {
    // size() is from Applet... I would much rather use Dimension, but
    // that came into existance in Java 1.2, which is not what most
    // browsers use.
    offsetX = (int)((size().width - (mem.width*SQUARE_DIMEN))/2);
    offsetY = (int)((size().height - (mem.height*SQUARE_DIMEN))/2);

    for (int i=0; i < mem.width; i++) {
      for (int u=0; u < mem.height; u++) {
        drawSquare(g,i,u,(Triplet)v.elementAt(i*mem.height+u));
      }
    }
  }

  public void drawSquare(Graphics g, int x, int y, Triplet triplet)
  {
    String which = (String)triplet.getFirst();
    if (which.equals(HIDDEN)) {
      g.drawImage(hiddenImage,offsetX+x*SQUARE_DIMEN,offsetY+y*SQUARE_DIMEN,null);
    } else
    if (which.equals(UNCOVERED)) {
      g.drawImage((Image)triplet.getSecond(),offsetX+x*SQUARE_DIMEN,offsetY+y*SQUARE_DIMEN,null);
    } else
    if (which.equals(MATCHED)) {
      g.setColor(BACKGROUND_COLOR);
      g.fillRect(offsetX+x*SQUARE_DIMEN,offsetY+y*SQUARE_DIMEN,SQUARE_DIMEN,SQUARE_DIMEN);
    }
  }

  public void sendMemorySettingsPanel(MemorySettingsPanel memorySettingsPanel)
  {
    this.memorySettingsPanel = memorySettingsPanel;
  }

  public void sendNewSettings(MemorySettings settings)
  {
    mem = new MemorySettings(settings);
    setupNewGame();
  }

  public void sendSoundType(int sounds)
  {
    this.sounds = sounds;
  }

  public void mouseClicked(MouseEvent me) { }
  public void mouseEntered(MouseEvent me) { }
  public void mouseExited(MouseEvent me)  { }

  public void mousePressed(MouseEvent me)
  {
    selectedX = (int)(Math.floor((me.getX()-offsetX)/SQUARE_DIMEN));
    selectedY = (int)(Math.floor((me.getY()-offsetY)/SQUARE_DIMEN));
  }

  public void mouseReleased(MouseEvent me)
  {
    Triplet coordTriplet;
    int tempx,tempy;
    int x = (int)(Math.floor((me.getX()-offsetX)/SQUARE_DIMEN));
    int y = (int)(Math.floor((me.getY()-offsetY)/SQUARE_DIMEN));

    if ((selectedX == x) && (selectedY == y) &&
        (x < mem.width) && (y < mem.height)) {

      if (g == null) {
        g = getGraphics();
      }

      // If the player has already selected the most number of matches
      // at a time, reset those squares
      if (selectionCoords.size() == mem.matches) {
        for (int i=0; i < selectionCoords.size(); i++) {
          coordTriplet = (Triplet)selectionCoords.elementAt(i);
          tempx = Integer.parseInt((String)coordTriplet.getFirst());
          tempy = Integer.parseInt((String)coordTriplet.getSecond());
          int position = tempx*mem.height+tempy;
          Triplet temptriplet = (Triplet)v.elementAt(position); // ***
          temptriplet.setFirst((Object)HIDDEN);
          v.setElementAt(temptriplet,position);
          drawSquare(g,tempx,tempy,temptriplet);
        }
        selectionCoords.removeAllElements();
      }

      Triplet triplet = (Triplet)v.elementAt(x*mem.height+y); // ***
      if (((String)triplet.getFirst()).equals(HIDDEN)) {
        triplet.setFirst((Object)UNCOVERED);
        selectionCoords.addElement(new Triplet((Object)Integer.toString(x),(Object)Integer.toString(y),null));
        drawSquare(g,x,y,triplet);
      }

      // Check to see if the selected squares all match
      int counter = 1;
      if (selectionCoords.size() == mem.matches) {
        // Get one of the selected squares' value
        coordTriplet = (Triplet)selectionCoords.elementAt(0);
        tempx = Integer.parseInt((String)coordTriplet.getFirst());
        tempy = Integer.parseInt((String)coordTriplet.getSecond());
        int id = ((Integer)((Triplet)v.elementAt(tempx*mem.height+tempy)).getThird()).intValue();

        // See if the other selected squares have the same value
        for (int i=1; i < selectionCoords.size(); i++) {
          coordTriplet = (Triplet)selectionCoords.elementAt(i);
          tempx = Integer.parseInt((String)coordTriplet.getFirst());
          tempy = Integer.parseInt((String)coordTriplet.getSecond());
          if (id == ((Integer)((Triplet)v.elementAt(tempx*mem.height+tempy)).getThird()).intValue()) counter++;
        }

        if (counter == mem.matches) {
          MemorySound.playSound(sounds,MemorySound.GOOD_MATCH);
          score += mem.squares;
        } else {
          MemorySound.playSound(sounds,MemorySound.BAD_MATCH);
          score -= 1;
        }

        // Give a nice little pause.
        try {
          Thread.sleep(600);
        } catch (Exception e) {
        }

        // Either re-cover the selected pieces, or remove them if they've been matched
        for (int i=0; i < selectionCoords.size(); i++) {
          coordTriplet = (Triplet)selectionCoords.elementAt(i);
          tempx = Integer.parseInt((String)coordTriplet.getFirst());
          tempy = Integer.parseInt((String)coordTriplet.getSecond());
          Triplet temptriplet = (Triplet)v.elementAt(tempx*mem.height+tempy); // ***
          if (counter == mem.matches) {
            temptriplet.setFirst((Object)MATCHED);
          } else {
            temptriplet.setFirst((Object)HIDDEN);
          }
          v.setElementAt(temptriplet,tempx*mem.height+tempy);
          drawSquare(g,tempx,tempy,temptriplet);
        }
        selectionCoords.removeAllElements();
        memorySettingsPanel.sendScore(score);
      }
    }
  }

  public static final Color BACKGROUND_COLOR = new Color(240,240,180);
  public static final String HIDDEN = "hidden";
  public static final String UNCOVERED = "uncovered";
  public static final String MATCHED = "matched";
  public static final int SQUARE_DIMEN = 20;
}

class MemorySettings
{
  public int matches;
  public int groups;
  public int width;
  public int height;
  public int squares;

  public MemorySettings(int matches, int groups)
  {
    resetValues(matches,groups);
  }

  public MemorySettings(MemorySettings ms)
  {
    this.matches = ms.matches;
    this.groups = ms.groups;
    this.width = ms.width;
    this.height = ms.height;
    this.squares = ms.squares;
  }

  public void resetValues(int matches, int groups)
  {
    this.matches = matches;
    this.groups = groups;
    this.squares = matches*groups;

    double ratio=0.0;
    double bestRatio=0.0;
    int bestWidth=0;
    int bestHeight=0;

    for (int i=1; i <= squares; i++) {
      // Get a ratio
      ratio = i/(squares/i);

      // If the ratio is over 1.0, we've already seen
      // these values in reverse, so the best dimensions
      // have already been found.
      if (ratio > 1.0) {
        this.width = bestWidth;
        this.height = bestHeight;
        return;
      }

      // If there is no remainder,
      if (squares%i == 0) {
        if ((ratio > bestRatio) || (bestRatio == 0.0)) {
          bestRatio = ratio;
          bestWidth = i;
          bestHeight = squares/i;
        }
      }
    }
  }
}

class Triplet
{
  Object first;
  Object second;
  Object third;

  public Triplet(Object first, Object second, Object third)
  {
    this.first = first;
    this.second = second;
    this.third = third;
  }

  public void setFirst(Object first)
  {
    this.first = first;
  }

  public Object getFirst()
  {
    return first;
  }

  public void setSecond(Object second)
  {
    this.second = second;
  }

  public Object getSecond()
  {
    return second;
  }

  public void setThird(Object third)
  {
    this.third = third;
  }

  public Object getThird()
  {
    return third;
  }
}

class MemorySound extends Applet
{
  public static AudioClip badRange;
  public static AudioClip goodRange;
  public static AudioClip badMatch;
  public static AudioClip goodMatch;

  public static void playSound(int type, int which)
  {
    if ((type == NEGATIVE_FEEDBACK) && (which == BAD_RANGE)) {
      badRange.play();
    }
    if ((type == NEGATIVE_FEEDBACK) && (which == BAD_MATCH)) {
      badMatch.play();
    }
    if ((type == POSITIVE_FEEDBACK) && (which == GOOD_RANGE)) {
      goodRange.play();
    }
    if ((type == POSITIVE_FEEDBACK) && (which == GOOD_MATCH)) {
      goodMatch.play();
    }
  }

  public static final int NEGATIVE_FEEDBACK = 1;
  public static final int POSITIVE_FEEDBACK = 2;
  public static final int BAD_RANGE = 1;
  public static final int GOOD_RANGE = 2;
  public static final int BAD_MATCH = 3;
  public static final int GOOD_MATCH = 4;
}

class MemoryImageProducer
{
  private int[] pixels;
  private int width;
  private int height;
  private int[] colors = new int[COLORS];
  private static final int COLORS = 256;
  private int lastLine;

  public void clearColors()
  {
    for(int i = 0; i < COLORS; i++) {
      colors[i]=0;
    }
  }

  public void clearImage()
  {
    lastLine = 0;
    pixels = new int[width * height];
  }

  public void setSize(int width, int height)
  {
    this.width = width;
    this.height = height;
    pixels = new int[width * height];
  }

  public void setColor(char c, int color)
  {
    colors[c] = color;
  }

  public void setPixels(String p)
  {
    char[] pix = p.toCharArray();

    int lineStart = lastLine * width;

    for(int i = 0; i < pix.length; i++) {
      pixels[lineStart++] = colors[pix[i] & 255];
    }
    lastLine++;
  }

  public Image createImage()
  {
    return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width,height,pixels,0,width));
  }
}

class MemoryImageGenerator
{
  MemoryImageProducer mip;

  public MemoryImageGenerator()
  {
    mip = new MemoryImageProducer();
    mip.clearColors();
    mip.setSize(20,20);
    mip.setColor('.',0xFFC0C0C0); // Background
    mip.setColor('K',0xFF000000); // Black
    mip.setColor('R',0xFFFF0000); // Red
    mip.setColor('G',0xFF00FF00); // Green
    mip.setColor('B',0xFF0000FF); // Blue
    mip.setColor('C',0xFF00FFFF); // Cyan
    mip.setColor('M',0xFFFF00FF); // Magenta
    mip.setColor('Y',0xFFFFFF00); // Yellow
    mip.setColor('W',0xFFFFFFFF); // White

    mip.setColor('D',0xFF505050); // Dark Gray 1 (darker)
    mip.setColor('d',0xFFA0A0A0); // Dark Gray 2 (lighter)
    mip.setColor('N',0x00ff0000); // Brown
    mip.setColor('A',0x00000000); // Tan
    mip.setColor('P',0xFFFFA0A0); // Pink
    mip.setColor('g',0x0000ff00); // Light Green
    mip.setColor('b',0x0000ff00); // Light Blue
    mip.setColor('T',0x0000ff00); // Teal
    mip.setColor('O',0x0000ff00); // Orange
    mip.setColor('~',0x0000ff00); // Cream
  }

  public Image createImage(int index)
  {

    switch (index) {
      case -1: // Hidden
        mip.clearImage();
        mip.setPixels("...................D");
        mip.setPixels("..................DD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels("..ddddddddddddddddDD");
        mip.setPixels(".DDDDDDDDDDDDDDDDDDD");
        mip.setPixels("DDDDDDDDDDDDDDDDDDDD");
        break;

      case 0: // Barber Pole
        mip.clearImage();
        mip.setPixels("........ddDd........");
        mip.setPixels("........dDDd........");
        mip.setPixels(".....dDDDDDDDDd.....");
        mip.setPixels("....dDRRWWWWWRDd....");
        mip.setPixels("....dDRRRWWWWWDd....");
        mip.setPixels("....dDWRRRWWWWDd....");
        mip.setPixels("....dDWWRRRWWWDd....");
        mip.setPixels("....dDWWWRRRWWDd....");
        mip.setPixels("....dDWWWWRRRWDd....");
        mip.setPixels("....dDWWWWWRRRDd....");
        mip.setPixels("....dDRWWWWWRRDd....");
        mip.setPixels("....dDRRWWWWWRDd....");
        mip.setPixels("....dDRRRWWWWWDd....");
        mip.setPixels("....dDWRRRWWWWDd....");
        mip.setPixels("....dDWWRRRWWWDd....");
        mip.setPixels("....dDWWWRRRWWDd....");
        mip.setPixels("....dDWWWWRRRWDd....");
        mip.setPixels(".....dDDDDDDDDd.....");
        mip.setPixels(".......dDDDDd.......");
        mip.setPixels("....................");
        break;

      case 1: // Flower
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".....YY..YY..YY.....");
        mip.setPixels(".....OYOYOYOYOY.....");
        mip.setPixels(".....YOYOYOYOYO.....");
        mip.setPixels(".....YYYYYYYYYY.....");
        mip.setPixels(".....YYYYYYYYYY.....");
        mip.setPixels("......YYYYYYYY......");
        mip.setPixels("........YYYY........");
        mip.setPixels(".........GG.........");
        mip.setPixels("..........GG.....G..");
        mip.setPixels("...G......GG...GGG..");
        mip.setPixels("...GG....GG...GGG...");
        mip.setPixels("..GGG...GG..GGGG....");
        mip.setPixels("..GGGG..GG.GGG......");
        mip.setPixels("...GGG.GG.GGG.......");
        mip.setPixels(".....GGGGGG.........");
        mip.setPixels("........GG..........");
        mip.setPixels("........GG..........");
        mip.setPixels(".........GG.........");
        break;

      case 2: // Smiley
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......PPPPPP.......");
        mip.setPixels(".....PPPPPPPPPP.....");
        mip.setPixels("...PPPPPPPPPPPPPP...");
        mip.setPixels("..PPPPKKPPPPKKPPPP..");
        mip.setPixels(".PPPPPKKPPPPKKPPPPP.");
        mip.setPixels(".PPPPPPPPPPPPPPPPPP.");
        mip.setPixels(".PPPPPPPPPPPPPPPPPP.");
        mip.setPixels(".PPPPKKPPPPPPKKPPPP.");
        mip.setPixels("..PPPPKKPPPPKKPPPP..");
        mip.setPixels("...PPPPPKKKKPPPPP...");
        mip.setPixels(".....PPPPPPPPPP.....");
        mip.setPixels(".......PPPPPP.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 3: // Frowny
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......GGGGGG.......");
        mip.setPixels(".....GGGGGGGGGG.....");
        mip.setPixels("...GGGGGGGGGGGGGG...");
        mip.setPixels("..GGGGKKGGGGKKGGGG..");
        mip.setPixels(".GGGGGKKGGGGKKGGGGG.");
        mip.setPixels(".GGGGGGGGGGGGGGGGGG.");
        mip.setPixels(".GGGGGGGGGGGGGGGGGG.");
        mip.setPixels(".GGGGGGGGGGGGGGGGGG.");
        mip.setPixels(".GGGGGGGKKKKGGGGGGG.");
        mip.setPixels("..GGGGKKGGGGKKGGGG..");
        mip.setPixels("...GGGKKGGGGKKGGG...");
        mip.setPixels(".....GGGGGGGGGG.....");
        mip.setPixels(".......GGGGGG.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 4: // Kite
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels(".........Y..........");
        mip.setPixels("........YYG.........");
        mip.setPixels(".......YYYGG........");
        mip.setPixels("......YYYYGGG.......");
        mip.setPixels(".....YYYYYGGGG......");
        mip.setPixels("....YYYYYYGGGGG.....");
        mip.setPixels(".....GGGGGYYYY......");
        mip.setPixels("......GGGGYYY.......");
        mip.setPixels(".......GGGYY........");
        mip.setPixels("........GGY.........");
        mip.setPixels(".........K..........");
        mip.setPixels("..........K.........");
        mip.setPixels("...........K........");
        mip.setPixels("............K.......");
        mip.setPixels("............K.......");
        mip.setPixels("............K.......");
        mip.setPixels("...........K........");
        mip.setPixels(".........KK.........");
        mip.setPixels("........K...........");
        break;

      case 5: // Balloon
        mip.clearImage();
        mip.setPixels("........RRR.........");
        mip.setPixels("......RRRRRRR.......");
        mip.setPixels("....RRRWRRRRRRR.....");
        mip.setPixels("...RRRWWRRRRRRRR....");
        mip.setPixels("...RRRWRRRRRRRRR....");
        mip.setPixels("...RRRRRRRRRRRRR....");
        mip.setPixels("...RRRRRRRRRRRRR....");
        mip.setPixels("....RRRRRRRRRRR.....");
        mip.setPixels("......RRRRRRR.......");
        mip.setPixels("........RRR.........");
        mip.setPixels(".......R.K.R........");
        mip.setPixels(".........K..........");
        mip.setPixels("........K...........");
        mip.setPixels(".......K............");
        mip.setPixels("......K.............");
        mip.setPixels("......K.............");
        mip.setPixels("......K.............");
        mip.setPixels(".......K............");
        mip.setPixels("........KK..........");
        mip.setPixels("..........K.........");
        break;

      case 6: // First Aid
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("..RRRRRRRRRRRRRRRR..");
        mip.setPixels("..RRRRRRRRRRRRRRRR..");
        mip.setPixels("..RRRRRRRRRRRRRRRR..");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("........RRRR........");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 7: // Pac Man
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......YYYYYY.......");
        mip.setPixels(".....YYYYYYYYYY.....");
        mip.setPixels("...YYYYKKYYYYYYY....");
        mip.setPixels("..YYYYYKKYYYYYY.....");
        mip.setPixels(".YYYYYYYYYYY........");
        mip.setPixels(".YYYYYYYY...........");
        mip.setPixels(".YYYYYYY............");
        mip.setPixels(".YYYYYYYY...........");
        mip.setPixels(".YYYYYYYYYYY........");
        mip.setPixels("..YYYYYYYYYYYYYY....");
        mip.setPixels("...YYYYYYYYYYYYYY...");
        mip.setPixels(".....YYYYYYYYYY.....");
        mip.setPixels(".......YYYYYY.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 8: // Ghost
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("......CCCCCCC.......");
        mip.setPixels("....CCCCCCCCCCC.....");
        mip.setPixels("..CCCCCCCCCCCCCCC...");
        mip.setPixels(".CCCWWWCCCCCWWWCCC..");
        mip.setPixels(".CCCWBWCCCCCWBWCCC..");
        mip.setPixels(".CCCWBBCCCCCWBBCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CCCCCCCCCCCCCCCCC..");
        mip.setPixels(".CC.CCC.CCC.CCC.CC..");
        mip.setPixels(".C...C...C...C...C..");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 9: // Candlestick
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels(".........Y..........");
        mip.setPixels("..........Y.........");
        mip.setPixels(".........YYY........");
        mip.setPixels(".........YYYY.......");
        mip.setPixels("..........YY........");
        mip.setPixels("........WW.d........");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels("........WWWWW.......");
        mip.setPixels(".KKK....WWWWW.......");
        mip.setPixels("KK.KK...WWWWW.......");
        mip.setPixels(".KKK....WWWWW.......");
        mip.setPixels("...KK...WWWWW....KK.");
        mip.setPixels("....KKKKKKKKKKKKKK..");
        mip.setPixels(".....KKKKKKKKKKKK...");
        break;

      case 10: // YinYang
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......WWKKKK.......");
        mip.setPixels(".....WWWWKKKKKK.....");
        mip.setPixels("...WWWWWWWKKKKKKK...");
        mip.setPixels("..WWWKKWWWKKKKKKKK..");
        mip.setPixels(".WWWWKKWWWWKKKKKKKK.");
        mip.setPixels(".WWWWWWWWWWKKKKKKKK.");
        mip.setPixels(".WWWWWWWWKKKKKKKKKK.");
        mip.setPixels(".WWWWWWWWKKKKWWKKKK.");
        mip.setPixels("..WWWWWWWKKKKWWKKK..");
        mip.setPixels("...WWWWWWWKKKKKKK...");
        mip.setPixels(".....WWWWWWKKKK.....");
        mip.setPixels(".......WWWWKK.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 11: // Postal Letter
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".WWWWWWWWWWWWWWWWWW.");
        mip.setPixels(".WWWWWWWWWWWWWWRRWW.");
        mip.setPixels(".WWWWWWWWWWWWWWRRWW.");
        mip.setPixels(".WWWBBBBBBBBBBWWWWW.");
        mip.setPixels(".WWWWWWWWWWWWWWWWWW.");
        mip.setPixels(".WWWBBBBBBBBBBBWWWW.");
        mip.setPixels(".WWWWWWWWWWWWWWWWWW.");
        mip.setPixels(".WWWBBBBBBBWBBBBWWW.");
        mip.setPixels(".WWWWWWWWWWWWWWWWWW.");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 12: // Hat
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KdKKKKKKKK.....");
        mip.setPixels(".....KddKKKKKKK.....");
        mip.setPixels(".....KddKKKKKKK.....");
        mip.setPixels(".....KddKKKKKKK.....");
        mip.setPixels(".....KKdKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels(".KKKKKKKKKKKKKKKKKK.");
        mip.setPixels(".KKKKKKKKKKKKKKKKKK.");
        mip.setPixels("....................");
        break;

      case 13: // Double Diamond
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".........BB.........");
        mip.setPixels(".......BB..BB.......");
        mip.setPixels(".....BB..BB..BB.....");
        mip.setPixels("...BB..BB..BB..BB...");
        mip.setPixels(".....BB..BB..BB.....");
        mip.setPixels(".......BB..BB.......");
        mip.setPixels(".........BB.........");
        mip.setPixels(".........BB.........");
        mip.setPixels(".......BB..BB.......");
        mip.setPixels(".....BB..BB..BB.....");
        mip.setPixels("...BB..BB..BB..BB...");
        mip.setPixels(".....BB..BB..BB.....");
        mip.setPixels(".......BB..BB.......");
        mip.setPixels(".........BB.........");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 14: // Multi Diamond
        mip.clearImage();
        mip.setPixels("...C................");
        mip.setPixels("..CCC..........Y....");
        mip.setPixels(".CCCCC..R.....YYY...");
        mip.setPixels("..CCC..RRR...YYYYY..");
        mip.setPixels("...C..RRRRR...YYY...");
        mip.setPixels(".......RRR.....Y....");
        mip.setPixels("........R...........");
        mip.setPixels("............G.......");
        mip.setPixels("...........GGG......");
        mip.setPixels("....P.....GGGGG.....");
        mip.setPixels("...PPP.....GGG......");
        mip.setPixels("..PPPPP.....G.......");
        mip.setPixels("...PPP..........B...");
        mip.setPixels("....P....W.....BBB..");
        mip.setPixels("........WWW...BBBBB.");
        mip.setPixels("..M....WWWWW...BBB..");
        mip.setPixels(".MMM....WWW.....B...");
        mip.setPixels("MMMMM....W..........");
        mip.setPixels(".MMM................");
        mip.setPixels("..M.................");
        break;

      case 15: // Baseball
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".....WWWWWWWWWW.....");
        mip.setPixels("...RRWWWWWWWWWWRR...");
        mip.setPixels("..WWWRRWWWWWWRRWWW..");
        mip.setPixels(".WWWWWRRWWWWRRWWWWW.");
        mip.setPixels(".WWWWWRRWWWWRRWWWWW.");
        mip.setPixels(".WWWWWRRWWWWRRWWWWW.");
        mip.setPixels(".WWWWWRRWWWWRRWWWWW.");
        mip.setPixels("..WWWRRWWWWWWRRWWW..");
        mip.setPixels("...RRWWWWWWWWWWRR...");
        mip.setPixels(".....WWWWWWWWWW.....");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 16: // Tennis ball
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels(".......GGGGGG.......");
        mip.setPixels(".....GGGGGGGGGG.....");
        mip.setPixels("...DDGGGGGGGGGGDD...");
        mip.setPixels("..GGGDDGGGGGGDDGGG..");
        mip.setPixels(".GGGGGGDDDDDDGGGGGG.");
        mip.setPixels(".GGGGGGGGGGGGGGGGGG.");
        mip.setPixels(".GGGGGGGGGGGGGGGGGG.");
        mip.setPixels(".GGGGGGDDDDDDGGGGGG.");
        mip.setPixels("..GGGDDGGGGGGDDGGG..");
        mip.setPixels("...DDGGGGGGGGGGDD...");
        mip.setPixels(".....GGGGGGGGGG.....");
        mip.setPixels(".......GGGGGG.......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 17: // Stop light
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("........KKKK........");
        mip.setPixels(".....KKKKKKKKKK.....");
        mip.setPixels("...KKKKKKKKKKKKKK...");
        mip.setPixels("...KKKKKRRRRKKKKK...");
        mip.setPixels("...KKKRRRRRRRRKKK...");
        mip.setPixels("...KKKRRRRRRRRKKK...");
        mip.setPixels("...KKKKKRRRRKKKKK...");
        mip.setPixels("...KKKKKKKKKKKKKK...");
        mip.setPixels("...KKKKKYYYYKKKKK...");
        mip.setPixels("...KKKYYYYYYYYKKK...");
        mip.setPixels("...KKKYYYYYYYYKKK...");
        mip.setPixels("...KKKKKYYYYKKKKK...");
        mip.setPixels("...KKKKKKKKKKKKKK...");
        mip.setPixels("...KKKKKGGGGKKKKK...");
        mip.setPixels("...KKKGGGGGGGGKKK...");
        mip.setPixels("...KKKGGGGGGGGKKK...");
        mip.setPixels("...KKKKKGGGGKKKKK...");
        mip.setPixels("...KKKKKKKKKKKKKK...");
        mip.setPixels(".KKKKKKKKKKKKKKKKKK.");
        break;

      case 18: // Rainbow
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("MMMMMMMMMMM.........");
        mip.setPixels("BBBBBBBBBBMMM.......");
        mip.setPixels("GGGGGGGGGBBBMMM.....");
        mip.setPixels("YYYYYYYYGGGBBBMM....");
        mip.setPixels("OOOOOOOYYYGGGBBMM...");
        mip.setPixels("RRRRRROOOYYYGGBBMM..");
        mip.setPixels(".....RRROOOYYGGBBMM.");
        mip.setPixels(".......RRROOYYGGBBM.");
        mip.setPixels(".........RROOYYGGBM.");
        mip.setPixels("..........RROOYYGBM.");
        mip.setPixels("...........RROOYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        mip.setPixels("............RROYGBM.");
        break;

      case 19: // Space Needle
        mip.clearImage();
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".......dddddd.......");
        mip.setPixels("...dddddddddddddd...");
        mip.setPixels(".dBBddBBdddBBddBBdd.");
        mip.setPixels("ddBBddBBdddBBddBBddd");
        mip.setPixels("..dddddddddddddddd..");
        mip.setPixels(".......dddddd.......");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".........dd.........");
        mip.setPixels(".......dddddd.......");
        mip.setPixels(".....dddddddddd.....");
        break;

      case 20: // Rocket
        mip.clearImage();
        mip.setPixels(".........WW.........");
        mip.setPixels("........WWWW........");
        mip.setPixels(".......WWBBWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels(".......WWWWWW.......");
        mip.setPixels("......WWWWWWWW......");
        mip.setPixels(".....WWWWWWWWWW.....");
        mip.setPixels("....WWWWWWWWWWWW....");
        mip.setPixels("...WWWWWWWWWWWWWW...");
        mip.setPixels("..WWWWWWWWWWWWWWWW..");
        mip.setPixels("..WWWWWWWWWWWWWWWW..");
        mip.setPixels("......KK....KK......");
        mip.setPixels(".....KKKK..KKKK.....");
        mip.setPixels("......OY....YO......");
        mip.setPixels(".....ROYR..RYOR.....");
        mip.setPixels("....RRROY..YORRR....");
        break;

      case 21: // Pencil
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("...............RRRR.");
        mip.setPixels("..............RRRR..");
        mip.setPixels("..............dddd..");
        mip.setPixels(".............YYYY...");
        mip.setPixels(".............YYYY...");
        mip.setPixels("............YYYY....");
        mip.setPixels("............YYYY....");
        mip.setPixels("...........YYYY.....");
        mip.setPixels("...........YYYY.....");
        mip.setPixels("..........YYYY......");
        mip.setPixels("..........YYYY......");
        mip.setPixels(".........YYYY.......");
        mip.setPixels(".........YYYY.......");
        mip.setPixels("........YYYY........");
        mip.setPixels("........YYYY........");
        mip.setPixels(".......YYYY.........");
        mip.setPixels(".......OOO..........");
        mip.setPixels(".......OO...........");
        mip.setPixels(".......K............");
        break;

      case 22: // Loops
        mip.clearImage();
        mip.setPixels("...GGGG.............");
        mip.setPixels("..G....G............");
        mip.setPixels(".G......G...........");
        mip.setPixels(".G....BBGB..........");
        mip.setPixels("..G..B.G..B.........");
        mip.setPixels("...GGGG....B........");
        mip.setPixels("....B......B........");
        mip.setPixels("...YYYY...B..OOOO...");
        mip.setPixels("..Y...BYBB..O....O..");
        mip.setPixels(".Y......Y..O......O.");
        mip.setPixels(".Y....RRYR.O......O.");
        mip.setPixels("..Y..R.Y..R.O....O..");
        mip.setPixels("...YYYY...WRWOOOO...");
        mip.setPixels("....R....W.R..W.....");
        mip.setPixels(".....R..W.R....W....");
        mip.setPixels("......RRRR.....W....");
        mip.setPixels(".........W....W.....");
        mip.setPixels("..........WWWW......");
        mip.setPixels("....................");
        mip.setPixels("....................");
        break;

      case 23: // Anchor
        mip.clearImage();
        mip.setPixels("....................");
        mip.setPixels("........KKKK........");
        mip.setPixels("......KK....KK......");
        mip.setPixels("......KK....KK......");
        mip.setPixels("........KKKK........");
        mip.setPixels(".........KK.........");
        mip.setPixels(".........KK.........");
        mip.setPixels(".........KK.........");
        mip.setPixels(".........KK.........");
        mip.setPixels(".........KK.........");
        mip.setPixels("K........KK........K");
        mip.setPixels("K.......KKKK.......K");
        mip.setPixels("KK......KKKK......KK");
        mip.setPixels("KKK.....KKKK.....KKK");
        mip.setPixels(".KK.....KKKK.....KK.");
        mip.setPixels("..KK....KKKK....KK..");
        mip.setPixels("...KKK..KKKK..KKK...");
        mip.setPixels("....KKKKKKKKKKKK....");
        mip.setPixels("......KKKKKKKK......");
        mip.setPixels("....................");
        break;
    }

    return(mip.createImage());
  }

  public static final int IMAGES = 24;
}

/*
images:
anchor
train
duck
sun
moon
star
tree
car
truck
circle
diamond
stick figure
alpha letters
apple

        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");
        mip.setPixels("....................");

*/
