package mosaicapplet;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.awt.image.*;
import javax.swing.event.*;
import com.borland.jbcl.layout.*;

public class Mosaic extends Applet {

  MediaTracker tracker;
  Image picard;
  int selectionStyle=0;
  final int NUMSTYLES=7;

  private boolean isStandalone = false;
  String filename;
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel drawingPanel = new JPanel();
  JPanel controlPanel = new JPanel();
  JSlider mosaicSlider = new JSlider();
  JPanel jPanel1 = new JPanel();
  BorderLayout borderLayout2 = new BorderLayout();
  JLabel fileLabel = new JLabel();
  BorderLayout borderLayout3 = new BorderLayout();
  JPanel buttonPanel = new JPanel();
  JPanel sliderPanel = new JPanel();
  BorderLayout borderLayout4 = new BorderLayout();
  JLabel widthLabel = new JLabel();
  JButton stepUpButton = new JButton();
  JButton stepDownButton = new JButton();
  ButtonGroup buttonGroup1 = new ButtonGroup();
  BorderLayout borderLayout5 = new BorderLayout();
  JPanel jPanel2 = new JPanel();
  VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
  JRadioButton avgRadio = new JRadioButton();
  JRadioButton upperLeftRadio = new JRadioButton();
  JRadioButton lowRadio = new JRadioButton();
  JRadioButton highRadio = new JRadioButton();
  JRadioButton redRadio = new JRadioButton();
  JRadioButton greenRadio = new JRadioButton();
  JRadioButton blueButton = new JRadioButton();
  JLabel jLabel1 = new JLabel();
  //Get a parameter value
  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
      (getParameter(key) != null ? getParameter(key) : def);
  }

  //Construct the applet
  public Mosaic() {
  }
  //Initialize the applet
  public void init() {
    try {
      filename = this.getParameter("param0", "seanlucsmil.jpg");
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  //Component initialization
  private void jbInit() throws Exception {

    tracker = new MediaTracker(this);

    if(filename==null)
      filename="seanlucsmil.jpg";
    if(filename=="")
      filename="seanlucsmil.jpg";

    fileLabel.setText("File: "+filename);

    picard = Toolkit.getDefaultToolkit().createImage(Mosaic.class.getResource(filename));
    tracker.addImage(picard, 1);
    tracker.waitForAll();

    this.setLayout(borderLayout1);
    jPanel1.setLayout(borderLayout2);
    controlPanel.setLayout(borderLayout3);
    sliderPanel.setLayout(borderLayout4);
    widthLabel.setText("Tile Width: 1");
    stepUpButton.setText("Step Size Up");
    stepUpButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        stepUpButton_actionPerformed(e);
      }
    });
    stepDownButton.setActionCommand("stepDownButton");
    stepDownButton.setText("Step Size Down");
    stepDownButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        stepDownButton_actionPerformed(e);
      }
    });
    mosaicSlider.setMinimum(1);
    drawingPanel.setLayout(borderLayout5);
    jPanel2.setLayout(verticalFlowLayout1);
    jPanel2.setRequestFocusEnabled(false);
    avgRadio.setText("Average");
    avgRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        avgRadio_actionPerformed(e);
      }
    });
    upperLeftRadio.setSelected(true);
    upperLeftRadio.setText("Upper Left");
    upperLeftRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        upperLeftRadio_actionPerformed(e);
      }
    });
    lowRadio.setText("Lowest");
    lowRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        lowRadio_actionPerformed(e);
      }
    });
    highRadio.setText("Highest");
    highRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        highRadio_actionPerformed(e);
      }
    });
    redRadio.setText("Most Red");
    redRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        redRadio_actionPerformed(e);
      }
    });
    greenRadio.setText("Most Green");
    greenRadio.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        greenRadio_actionPerformed(e);
      }
    });
    blueButton.setText("Most Blue");
    blueButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        blueButton_actionPerformed(e);
      }
    });
    jLabel1.setText("Tile Selction Method");
    jPanel2.add(jLabel1, null);
    this.add(drawingPanel, BorderLayout.CENTER);
    drawingPanel.add(jPanel2, BorderLayout.EAST);
    jPanel2.add(avgRadio, null);
    this.add(controlPanel, BorderLayout.SOUTH);
    this.add(jPanel1, BorderLayout.NORTH);
    jPanel1.add(fileLabel, BorderLayout.WEST);
    controlPanel.add(buttonPanel, BorderLayout.SOUTH);
    controlPanel.add(sliderPanel, BorderLayout.NORTH);
    mosaicSlider.setValue(1);
    mosaicSlider.addChangeListener(new ChangeListener(){
      public void stateChanged(ChangeEvent e){
        drawMosaic();
        widthLabel.setText("Tile Width: " +mosaicSlider.getValue());
      }
    });

    sliderPanel.add(mosaicSlider, BorderLayout.CENTER);
    sliderPanel.add(widthLabel, BorderLayout.NORTH);
    buttonPanel.add(stepDownButton, null);
    buttonPanel.add(stepUpButton, null);
    jPanel2.add(upperLeftRadio, null);
    jPanel2.add(lowRadio, null);
    jPanel2.add(highRadio, null);
    jPanel2.add(redRadio, null);
    jPanel2.add(greenRadio, null);
    jPanel2.add(blueButton, null);
    buttonGroup1.add(upperLeftRadio);
    buttonGroup1.add(lowRadio);
    buttonGroup1.add(highRadio);
    buttonGroup1.add(redRadio);
    buttonGroup1.add(greenRadio);
    buttonGroup1.add(blueButton);
    buttonGroup1.add(avgRadio);
  }

  private void drawMosaic(){
    if(selectionStyle==0){
      drawUpperLeft();
    }
    else if(selectionStyle==1){
      drawMin();
    }
    else if(selectionStyle==2){
      drawMax();
    }
    else if(selectionStyle==3){
      drawAvg();
    }
    else if(selectionStyle==4){
      drawRed();
    }
    else if(selectionStyle==5){
      drawGreen();
    }
    else if(selectionStyle==6){
      drawBlue();
    }

  }

  private void drawAvg(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),picard.getHeight(null),BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),picard.getHeight(null),BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard,0,0,null);

    int count=0;
    int red = 0;
    int green = 0;
    int blue = 0;
    int alpha = 255;

    int avg;
    int rgba;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              red += (rgba >> 16) & 0xff;
              green += (rgba >> 8) & 0xff;
              blue += rgba & 0xff;
              count++;
            }
        avg = ( (alpha << 24) | ( (red / count) << 16) | ( (green / count) << 8) |
               (blue / count));

        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, avg);
            }

        count = 0;
        red = 0;
        green = 0;
        blue = 0;

      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }

  private void drawUpperLeft(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),picard.getHeight(null),BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),picard.getHeight(null),BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard,0,0,null);

    for(int i=0;i<picard.getWidth(null);i+=mosaicSlider.getValue())
      for(int j=0;j<picard.getHeight(null);j+=mosaicSlider.getValue())
        for(int l=0;l<=mosaicSlider.getValue();l++)
          for(int m=0;m<=mosaicSlider.getValue();m++)
            if(i+l<picard.getWidth(null)&&j+m<picard.getHeight(null))
              copy.setRGB(i+l,j+m,copy2.getRGB(i,j));

    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }

  void drawMin(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),
                                           picard.getHeight(null),
                                           BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),
                                            picard.getHeight(null),
                                            BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard, 0, 0, null);

    int lowguy = ( (255 << 24) | (255 << 16) | (255 << 8) | 255);
    int temp;
    int rgba = lowguy;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              if ( ( ( (rgba >> 16) & 0xff) + ( (rgba >> 8) & 0xff) +
                    (rgba & 0xff)) <
                  ( ( (lowguy >> 16) & 0xff) + ( (lowguy >> 8) & 0xff) +
                   (lowguy & 0xff)))
                lowguy = rgba;
            }
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, lowguy);
            }
        lowguy = ( (255 << 24) | (255 << 16) | (255 << 8) | 255);
      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }

  void drawMax(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),
                                           picard.getHeight(null),
                                           BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),
                                            picard.getHeight(null),
                                            BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard, 0, 0, null);

    int highguy = ( (0 << 24) | (0 << 16) | (0 << 8) | 0);
    int temp;
    int rgba = highguy;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              if ( ( ( (rgba >> 16) & 0xff) + ( (rgba >> 8) & 0xff) +
                    (rgba & 0xff)) >
                  ( ( (highguy >> 16) & 0xff) + ( (highguy >> 8) & 0xff) +
                   (highguy & 0xff)))
                highguy = rgba;
            }
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, highguy);
            }
        highguy = ( (0 << 24) | (0 << 16) | (0 << 8) | 0);
      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }


  void drawRed(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),
                                           picard.getHeight(null),
                                           BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),
                                            picard.getHeight(null),
                                            BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard, 0, 0, null);

    int highguy = ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
    int temp;
    int rgba = highguy;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              if(highguy == ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255))
                highguy = rgba;
              if ( ( ( (rgba >> 16) & 0xff) - ( (rgba >> 8) & 0xff) -
                    (rgba & 0xff)) >
                  ( ( (highguy >> 16) & 0xff) - ( (highguy >> 8) & 0xff) -
                    (highguy & 0xff)))
                highguy = rgba;
            }
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, highguy);
            }
        highguy = ( (-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }


  void drawGreen(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),
                                           picard.getHeight(null),
                                           BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),
                                            picard.getHeight(null),
                                            BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard, 0, 0, null);

    int highguy = ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
    int temp;
    int rgba = highguy;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              if(highguy == ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255))
                highguy = rgba;
              if ( ( ( -(rgba >> 16) & 0xff) + ( (rgba >> 8) & 0xff) -
                    (rgba & 0xff)) >
                  ( ( -(highguy >> 16) & 0xff) + ( (highguy >> 8) & 0xff) -
                    (highguy & 0xff)))
                highguy = rgba;
            }
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, highguy);
            }
        highguy = ( (-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }


  void drawBlue(){
    Graphics draw;
    draw = drawingPanel.getGraphics();

    BufferedImage copy = new BufferedImage(picard.getWidth(null),
                                           picard.getHeight(null),
                                           BufferedImage.TYPE_INT_RGB);
    BufferedImage copy2 = new BufferedImage(picard.getWidth(null),
                                            picard.getHeight(null),
                                            BufferedImage.TYPE_INT_RGB);
    copy2.getGraphics().drawImage(picard, 0, 0, null);

    int highguy = ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
    int temp;
    int rgba = highguy;

    for (int i = 0; i < picard.getWidth(null); i += mosaicSlider.getValue())
      for (int j = 0; j < picard.getHeight(null); j += mosaicSlider.getValue()) {
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              rgba = copy2.getRGB(i + l, j + m);
              if(highguy == ((-255 << 24) | (-255 << 16) | (-255 << 8) | -255))
                highguy = rgba;
              if ( ( ( -(rgba >> 16) & 0xff) - ( (rgba >> 8) & 0xff) +
                    (rgba & 0xff)) >
                  ( ( -(highguy >> 16) & 0xff) - ( (highguy >> 8) & 0xff) +
                    (highguy & 0xff)))
                highguy = rgba;
            }
        for (int l = 0; l <= mosaicSlider.getValue(); l++)
          for (int m = 0; m <= mosaicSlider.getValue(); m++)
            if (i + l < picard.getWidth(null) && j + m < picard.getHeight(null)) {
              copy.setRGB(i + l, j + m, highguy);
            }
        highguy = ( (-255 << 24) | (-255 << 16) | (-255 << 8) | -255);
      }
    drawingPanel.getGraphics().drawImage(copy,0,0,null);
  }


  public void paint(Graphics g){
    super.paint(g);
    drawMosaic();
  }


  //Start the applet
  public void start() {
    drawMosaic();
  }
  //Stop the applet
  public void stop() {
  }
  //Destroy the applet
  public void destroy() {
  }
  //Get Applet information
  public String getAppletInfo() {
    return "Applet Information";
  }
  //Get parameter info
  public String[][] getParameterInfo() {
    String[][] pinfo =
      {
      {"param0", "String", ""},
      };
    return pinfo;
  }

  void stepUpButton_actionPerformed(ActionEvent e) {
    mosaicSlider.setValue(mosaicSlider.getValue()+1);
    drawMosaic();
  }

  void stepDownButton_actionPerformed(ActionEvent e) {
    mosaicSlider.setValue(mosaicSlider.getValue()-1);
    drawMosaic();
  }

  void styleButton_actionPerformed(ActionEvent e) {
    selectionStyle++;
    if(selectionStyle>=NUMSTYLES)
      selectionStyle=0;
    drawMosaic();
  }

  void avgRadio_actionPerformed(ActionEvent e) {
    selectionStyle=3;
    drawMosaic();
  }

  void upperLeftRadio_actionPerformed(ActionEvent e) {
    selectionStyle=0;
    drawMosaic();

  }

  void lowRadio_actionPerformed(ActionEvent e) {
    selectionStyle=1;
    drawMosaic();

  }

  void highRadio_actionPerformed(ActionEvent e) {
    selectionStyle=2;
    drawMosaic();

  }

  void redRadio_actionPerformed(ActionEvent e) {
    selectionStyle=4;
    drawMosaic();

  }

  void greenRadio_actionPerformed(ActionEvent e) {
    selectionStyle=5;
    drawMosaic();

  }

  void blueButton_actionPerformed(ActionEvent e) {
    selectionStyle=6;
    drawMosaic();

  }
}