import imp.*;
import java.awt.Color;

/**
 * Write a description of class GeometrischeOperationen2 here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class GeometrischeBildoperationen2
{
    public Color naechsterNachbar(Color[][] pixel, double x, double y) {

        int x1 = (int) Math.round(x);
        int y1 = (int) Math.round(y);

        return pixel[x1][y1];
    }

    public Color bilineareInterpolation( Color[][] pixel, double x, double y) {

        int x1 = (int) x;
        int y1 = (int) y;

        int x2 = x1+1;
        int y2 = y1+1;

        double dx = x - x1;
        double dy = y - y1;

        double g11 = (1-dx)*(1-dy);
        double g12 = (1-dx)*(dy);
        double g21 = (dx)  *(1-dy);
        double g22 = (dx)  *(dy);

        if (x1 <0) x1 = 0;
        if (y1 <0) y1 = 0;
        if (x1>=pixel.length)    x1 = pixel.length-1;
        if (y1>=pixel[0].length) y1 = pixel[0].length-1;
        if (x2 <0) x2 = 0;
        if (y2 <0) y2 = 0;
        if (x2>=pixel.length)    x2 = pixel.length-1;
        if (y2>=pixel[0].length) y2 = pixel[0].length-1;

        int rot = (int) (pixel[x1][y1].getRed()    *g11
                +pixel[x1][y2].getRed()    *g12
                +pixel[x2][y1].getRed()    *g21
                +pixel[x2][y2].getRed()    *g22);
        int gruen = (int) (pixel[x1][y1].getGreen()*g11
                +pixel[x1][y2].getGreen()*g12
                +pixel[x2][y1].getGreen()*g21
                +pixel[x2][y2].getGreen()*g22);
        int blau = (int) (pixel[x1][y1].getBlue()  *g11
                +pixel[x1][y2].getBlue()  *g12
                +pixel[x2][y1].getBlue()  *g21
                +pixel[x2][y2].getBlue()  *g22);

        return new Color(rot, gruen, blau);
    }

    public Picture groesseAendern(Picture originalbild, int neueBreite, int neueHoehe) {
        int alteBreite = originalbild.getWidth();
        int alteHoehe  = originalbild.getHeight();

        Color[][] pixel = originalbild.getPixelArray();
        Color[][] pixelNeu = new Color[neueBreite][neueHoehe];

        for (int x = 0; x < neueBreite ; x++){ 
            for (int y = 0; y < neueHoehe ; y++) 
            { 
                double altX = (double) x/ (neueBreite-1) * (alteBreite-1);
                double altY = (double) y/ (neueHoehe-1)  * (alteHoehe-1);
                pixelNeu[x][y] = naechsterNachbar(pixel,altX,altY);
            } 
        }
        Picture neuesBild = new Picture();
        neuesBild.setPixelArray(pixelNeu);
        return neuesBild;
    }    

    // Nur für das Interesse, ohne Anleitung
    
    public Picture dreheBild(Picture originalbild, double winkel) {
        int breite = originalbild.getWidth();
        int hoehe  = originalbild.getHeight();

        Color[][] pixel = originalbild.getPixelArray();
        Color[][] pixelNeu = new Color[breite][hoehe];

        for (int x = 0; x < breite ; x++){ 
            for (int y = 0; y < hoehe ; y++) 
            { 
                double altX =  Math.cos(winkel)*(x-breite/2.0)+Math.sin(winkel)*(y-hoehe/2.0)+breite/2.0;
                double altY = -Math.sin(winkel)*(x-breite/2.0)+Math.cos(winkel)*(y-hoehe/2.0)+hoehe/2.0;
                pixelNeu[x][y] = bilineareInterpolation(pixel,altX,altY);
            } 
        }
        Picture neuesBild = new Picture();
        neuesBild.setPixelArray(pixelNeu);
        return neuesBild;
    }    

    public Picture wirbel(Picture originalbild, double winkel) {
        int breite = originalbild.getWidth();
        int hoehe  = originalbild.getHeight();

        Color[][] pixel = originalbild.getPixelArray();
        Color[][] pixelNeu = new Color[breite][hoehe];

        for (int x = 0; x < breite ; x++){ 
            for (int y = 0; y < hoehe ; y++) 
            { 
                double winkel1 = Math.sqrt(Math.pow(y-hoehe/2.0,2)+Math.pow(x-breite/2.0,2))/(hoehe/2.0)*winkel;
                double altX = Math.cos(winkel1)*(x-breite/2.0)+Math.sin(winkel1)*(y-hoehe/2.0)+breite/2.0;
                double altY = -Math.sin(winkel1)*(x-breite/2.0)+Math.cos(winkel1)*(y-hoehe/2.0)+hoehe/2.0;
                pixelNeu[x][y] = bilineareInterpolation(pixel,altX,altY);
            } 
        }
        Picture neuesBild = new Picture();
        neuesBild.setPixelArray(pixelNeu);
        return neuesBild;
    }    
}
