
/**
 *  Applet Bodove jasove transformacie
 *
 *  projekt na predmet Webowska grafika
 *
 *  V metode init sa na nastavia jednotlive komponenty.
 *  Dolezite su najma triedy MyCanvas a MyHistogram.
 *
 * MyCanvas - trieda nacita na vstupe obrazok. Pomocou metody getRGB() dostane
 * z obrazka obrazove body ulozene v poli. Metoda zmenJas() ziska z kazde
 * obrazoveho bodu jednotlive zlozky farby (red, green, blue) a k nim pripocita
 * resp. odpocita konstantu a vrati pixel do pola. Nasledne sa z pola vytvori
 * BufferedImage metodou setRGB(). Metoda zmenKotrast funguje podobne ako metoda
 * zmenJas(), ale namiesto pripocitavania konstatny k jednotlivym zlozkam farby
 * ich nasobi konstantou.
 *
 * MyHistogram - trieda na vstupe dostane pole obrazovych bodov. Metoda doHistogram
 * spocita rovnake jasove hodnoty a ulozi ich do pola. V metode paint() sa pole
 * vykresli.
 *
 */


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


/**
 *
 * @author Lukas Blaho
 */

public class bjt extends JApplet implements ChangeListener {
   
    JSlider jas, kontrast;
    JLabel lJas, lKontrast;
    JPanel panel, controlPanel;
    MyCanvas platno;
    MyHistogram myHistogram;
    
    public void init() {

        // nastav okno appletu
        this.setSize(514, 300);
        this.setEnabled(true);
        this.setVisible(true);
        this.setLayout(new GridLayout(1, 2));

        // nastav komponenty
        panel = new JPanel();
        panel.setSize(300,450);
        panel.setLayout(new BorderLayout());
        panel.setBackground(Color.white);
        panel.setEnabled(true);
        panel.setVisible(true);

        controlPanel = new JPanel();
        controlPanel.setLayout(new GridLayout(2, 2, 0, 10));
        controlPanel.setSize(300, 50);
        controlPanel.setBackground(Color.white);
        controlPanel.setEnabled(true);
        controlPanel.setVisible(true);

        lJas = new JLabel("  Jas");
        lJas.setVisible(true);
        lJas.setEnabled(true);
        

        jas = new JSlider(-255, 255, 0);
        jas.setSize(10, 10);
        jas.setPaintLabels(true);
        jas.setName("jas");
        jas.setToolTipText("Jas");
        jas.addChangeListener(this);
        jas.setBackground(Color.white);

        lKontrast = new JLabel("  Kontrast");
        lKontrast.setEnabled(true);
        lKontrast.setVisible(true);        

        kontrast = new JSlider(0, 20, 10);
        kontrast.setSize(10, 10);
        kontrast.setPaintLabels(true);
        kontrast.addChangeListener(this);
        kontrast.setName("kontrast");
        kontrast.setToolTipText("Kontrast");
        kontrast.setBackground(Color.white);

        platno = new MyCanvas(loadBufferedImage("images.jpg"));
        platno.setEnabled(true);
        platno.setVisible(true);

        myHistogram = new MyHistogram(platno.orgImage.getRGB(0, 0, platno.orgImage.getWidth(), platno.orgImage.getHeight(), null, 0, platno.orgImage.getWidth()));
        myHistogram.setSize(257, 200);
        myHistogram.setEnabled(true);
        myHistogram.setVisible(true);
        myHistogram.setForeground(Color.white);

        // pridaj vsetky komponenty
        controlPanel.add(lJas);
        controlPanel.add(jas);
        controlPanel.add(lKontrast);
        controlPanel.add(kontrast);

        panel.add("North", controlPanel);
        panel.add("Center",  platno);

        add(panel);
        add(myHistogram);
        
    }

    public void stateChanged(ChangeEvent e) {
        JSlider slider = (JSlider) e.getSource();
        
        if (slider.getName() == "jas")
            platno.zmenJas(slider.getValue());
        else if (slider.getName() == "kontrast")
            platno.zmenKontrast(slider.getValue());

        myHistogram.doHistogram(platno.getPixelArray());
        
    }
    
    /**
     * 
     * @param loadBufferedImage   
     * 
     * Nacita obrazok "nazov"
     *    
     * @return BufferedImage
     */

    public BufferedImage loadBufferedImage(String nazov){
        BufferedImage img = null;
        try {
             URL url = new URL(getCodeBase(), nazov);    
             img = ImageIO.read(url);
         } catch (IOException e) {
             e.getMessage();
         }
        
        return img;
    } 

}

/**
 *
 * @author Lukas Blaho
 *
 * Koponent, ktory zobrazi obrazok
 *
 */

class MyCanvas extends Component {
       
    public BufferedImage orgImage;
    private BufferedImage img;
    private int[] orgPixels;
    private int[] actualPixels;
    private int width;
    private int height;
    
    MyCanvas(BufferedImage obr) {
        orgImage = obr;
        width = orgImage.getWidth();
        height = orgImage.getHeight();
        orgPixels = orgImage.getRGB(0, 0, width, height, null, 0, width);
        
        img = new BufferedImage(orgImage.getWidth(), orgImage.getHeight(), BufferedImage.TYPE_INT_RGB);        
        img.setRGB(0, 0, width, height, orgPixels, 0, width);

        actualPixels = img.getRGB(0, 0, width, height, null, 0, width);
    }

    /**
     * Metoda na zmenu jasu
     *
     */
    
     public void zmenJas(int c) {
         
       int[] pixels = new int[orgPixels.length];
       for (int i = 0; i<orgPixels.length; i++) {
               pixels[i] = orgPixels[i];
       }
        
        for (int i = 0; i<pixels.length; i++){
            Color pixelColor = new Color(pixels[i]);
            
            int red = 0;
            if (pixelColor.getRed() + c > 255) red = 255;
            else if (pixelColor.getRed() + c < 0) red = 0;
            else red = pixelColor.getRed() + c;
            
            int green = 0;
            if (pixelColor.getGreen() + c > 255) green = 255;
            else if (pixelColor.getGreen() + c < 0) green = 0;
            else green = pixelColor.getGreen() + c;
            
            int blue = 0;
            if (pixelColor.getBlue() + c > 255) blue = 255;
            else if (pixelColor.getBlue() + c < 0) blue = 0;
            else blue = pixelColor.getBlue() + c;
            
            Color newPixelColor = new Color(red, green, blue);
            pixels[i] = newPixelColor.getRGB();            
        }


        
        img.setRGB(0, 0, width, height, pixels, 0, width);  
        setPixelsOfActualImage();
        
        repaint();
       
    }

     /**
      *  Metoda na zmenu kontrastu
      */


     public void zmenKontrast(int c) {

       int[] pixels = new int[orgPixels.length];
       for (int i = 0; i<actualPixels.length; i++) {
               pixels[i] = actualPixels[i];
       }

        for (int i = 0; i<pixels.length; i++){
            Color pixelColor = new Color(pixels[i]);

            int red = 0;
            if (pixelColor.getRed() * c/10 > 255) red = 255;
            else if (pixelColor.getRed()  * c/10 < 0) red = 0;
            else red = pixelColor.getRed() * c/10;

            int green = 0;
            if (pixelColor.getGreen()  * c/10 > 255) green = 255;
            else if (pixelColor.getGreen()  * c/10 < 0) green = 0;
            else green = pixelColor.getGreen() * c/10;

            int blue = 0;
            if (pixelColor.getBlue()  * c/10 > 255) blue = 255;
            else if (pixelColor.getBlue()  * c/10 < 0) blue = 0;
            else blue = pixelColor.getBlue() * c/10;

            Color newPixelColor = new Color(red, green, blue);
            pixels[i] = newPixelColor.getRGB();
        }

        img.setRGB(0, 0, width, height, pixels, 0, width);

        repaint();

    }

     /**
      * Ulozi aktualny obrazok do pola po pixloch
      */

     private void setPixelsOfActualImage(){
         actualPixels = img.getRGB(0, 0, width, height, null, 0, width);
     }

     /**
      * Metoda vtrati pole pixelov aktualne zmeneneho obrazku
      * @return int[] - pole pixelov
      */

     public int[] getPixelArray()  {
           return img.getRGB(0, 0, width, height, null, 0, width);
     }
    
    public void paint(Graphics g) {             
        g.drawImage(img, 137 - width/2  , 20, null);
        //g.drawImage(img, 0  , 20, null);
        //g.drawImage(orgImage, 150, 20, null);
    }
}

/**
 *
 * @author Lukas Blaho
 *
 * Komponent na vykreslenie histogramu
 */
class MyHistogram extends Component {

    int[] redColorArray;
    int[] greenColorArray;
    int[] blueColorArray;


    MyHistogram(int[] pixelArray) {
        redColorArray = new int[256];
        vynulujPole(redColorArray);
        for (int i = 0; i<pixelArray.length; i++){
            Color pixelColor = new Color(pixelArray[i]);

            int red = pixelColor.getRed();
            redColorArray[red] = redColorArray[red] + 1;
        }

        greenColorArray = new int[256];
        for (int i = 0; i<greenColorArray.length; i++)
            greenColorArray[i] = 0;

        blueColorArray = new int[256];
        for (int i = 0; i<blueColorArray.length; i++)
            blueColorArray[i] = 0;

    }

    /**
     * Prejde vtupne pole a spocita pocet pixelov, ktore maju rovnakehy jas
     * @param pixelArray - int[]
     */

    public void doHistogram(int[] pixelArray) {
        vynulujPole(redColorArray);
        for (int i = 0; i<pixelArray.length; i++){
            Color pixelColor = new Color(pixelArray[i]);

            int red = pixelColor.getRed();
            redColorArray[red] = redColorArray[red] + 1;

            int green = pixelColor.getGreen();
            greenColorArray[green] = greenColorArray[green] + 1;

            int blue = pixelColor.getGreen();
            blueColorArray[blue] = blueColorArray[blue] + 1;

        }
        repaint();
    }

    /**
     * Vynuluje dane pole tak, ze do kazdeho policka vlozi nulu
     *
     * @param pole int[]
     */

    private void vynulujPole(int[] pole) {
        for (int i = 0; i<pole.length; i++)
            pole[i] = 0;
    }

    public void paint(Graphics g) {
        g.setColor(Color.orange);
        g.fillRect(0, 0, 256, 300);
        Color c;
        for (int i = 0; i<redColorArray.length; i++){
            c = new Color(i, i, i);
            g.setColor(c);
            //g.fillRect(i, 256, 1, 10);
            g.fillRect(i, this.getHeight() - (redColorArray[i]/8), 1, redColorArray[i]/5);
        }

    }
}
