/*--- formatted by Jindent 2.1, (www.c-lab.de/~jindent) ---*/

/*
 * JIGL--Java Imaging and Graphics Library
 * Copyright (C)1999 Brigham Young University
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * A copy of the GNU Library General Public Licence is contained in
 * /jigl/licence.txt
 */

package jm.jigl; // Modifizierte Paketstruktur [JM]

import jm.jigl.*;


/**
 * Shifts an image
 * @version 1.3, Modifikation der urspruenglichen jigl Paketstruktur durch Jens Martin
 * @see jigl.image.utils.Shift
 */
public class Shift {

	private final int NOWRAP = 0;


	/**
	 * Set the shift not to wrap
	 */
	private final int WRAP = 1;


	/**
	 * Sets the shift to wrap
	 */
	private int				xoffset = 0;
	private int				yoffset = 0;
	private boolean		wrap = false;


	/**
	 * Constructs a shift
	 * @param x shift along the x axis
	 * @param y shift along the y axis
	 * @wrapp NOWRAP= no wrap WRAP=wrap.
	 */
	public Shift(int x, int y, int wrapp) {
		xoffset = x;
		yoffset = y;
		if (wrapp == 1) {
			wrap = true;

		}
	}


	/**
	 * Method declaration
	 *
	 *
	 * @param image
	 *
	 * @return
	 *
	 * @see
	 */
	private GrayImage apply(GrayImage image) {
		int				X = image.X();
		int				Y = image.Y();

		// Convert to the appropriate type
		GrayImage temp = new GrayImage(X, Y);

		for (int y = 0; y < Y; y++) {
			for (int x = 0; x < X; x++) {
				if (xoffset > 0 && yoffset > 0) {
					temp.set((x + xoffset) % X, (y + yoffset) % Y, image.get(x, y));
				} else if (xoffset > 0) {
					temp.set((x + xoffset) % X, (Y + yoffset + y) % Y, image.get(x, y));
				} else if (yoffset > 0) {
					temp.set((X + xoffset + x) % X, (y + yoffset) % Y, image.get(x, y));
				} else {
					temp.set((X + xoffset + x) % X, (y + yoffset + Y) % Y, image.get(x, y));
				}
			}
		}
		return temp;
	}


	/**
	 * Method declaration
	 *
	 *
	 * @param image
	 *
	 * @return
	 *
	 * @see
	 */
	private GrayImage applynw(GrayImage image) {
		int				X = image.X();
		int				Y = image.Y();

		// Convert to the appropriate type
		GrayImage temp = new GrayImage(X, Y);

		for (int y = 0; y < Y; y++) {
			for (int x = 0; x < X; x++) {
				if ((x + xoffset >= 0) && (x + xoffset < X) && (y + yoffset >= 0) && (y + yoffset < Y)) {
					temp.set(x, y, image.get(x + xoffset, y + yoffset));
				} else {
					temp.set(x, y, 0);
				}
			}
		}
		return temp;
	}


	/**
	 * Method declaration
	 *
	 *
	 * @param image
	 *
	 * @return
	 *
	 * @see
	 */
	private RealGrayImage apply(RealGrayImage image) {
		int						X = image.X();
		int						Y = image.Y();

		// Convert to the appropriate type
		RealGrayImage temp = new RealGrayImage(X, Y);

		for (int y = 0; y < Y; y++) {
			for (int x = 0; x < X; x++) {
				if (xoffset > 0 && yoffset > 0) {
					temp.set((x + xoffset) % X, (y + yoffset) % Y, image.get(x, y));
				} else if (xoffset > 0) {
					temp.set((x + xoffset) % X, (Y + yoffset + y) % Y, image.get(x, y));
				} else if (yoffset > 0) {
					temp.set((X + xoffset + x) % X, (y + yoffset) % Y, image.get(x, y));
				} else {
					temp.set((X + xoffset + x) % X, (y + yoffset + Y) % Y, image.get(x, y));
				}
			}
		}
		return temp;
	}


	/**
	 * Method declaration
	 *
	 *
	 * @param image
	 *
	 * @return
	 *
	 * @see
	 */
	private RealGrayImage applynw(RealGrayImage image) {
		int						X = image.X();
		int						Y = image.Y();

		// Convert to the appropriate type
		RealGrayImage temp = new RealGrayImage(X, Y);

		for (int y = 0; y < Y; y++) {
			for (int x = 0; x < X; x++) {
				if ((x + xoffset >= 0) && (x + xoffset < X) && (y + yoffset >= 0) && (y + yoffset < Y)) {
					temp.set(x, y, image.get(x + xoffset, y + yoffset));
				} else {
					temp.set(x, y, 0);
				}
			}
		}
		return temp;
	}

	/*
	 * private ColorImage apply(ColorImage image){
	 * ColorImage temp=new ColorImage(image.X(), image.Y());
	 * temp.setPlane(0, apply(image.plane(0)));
	 * temp.setPlane(1, apply(image.plane(1)));
	 * temp.setPlane(2, apply(image.plane(2)));
	 * return temp;
	 *
	 * }
	 *
	 * private RealColorImage apply(RealColorImage image){
	 * RealColorImage temp=new RealColorImage(image.X(), image.Y());
	 * temp.setPlane(0, apply(image.plane(0)));
	 * temp.setPlane(1, apply(image.plane(1)));
	 * temp.setPlane(2, apply(image.plane(2)));
	 * return temp;
	 *
	 * }
	 * private ColorImage applynw(ColorImage image){
	 * ColorImage temp=new ColorImage(image.X(), image.Y());
	 * temp.setPlane(0, applynw(image.plane(0)));
	 * temp.setPlane(1, applynw(image.plane(1)));
	 * temp.setPlane(2, applynw(image.plane(2)));
	 * return temp;
	 *
	 * }
	 *
	 *
	 * private RealColorImage applynw(RealColorImage image){
	 * RealColorImage temp=new RealColorImage(image.X(), image.Y());
	 * temp.setPlane(0, applynw(image.plane(0)));
	 * temp.setPlane(1, applynw(image.plane(1)));
	 * temp.setPlane(2, applynw(image.plane(2)));
	 * return temp;
	 *
	 * }
	 */


	/**
	 * Applies  the shift to this image
	 */
	public Image apply(Image image) {
		if (wrap == true) {
			if (image instanceof GrayImage) {
				return apply((GrayImage) image);
			} else if (image instanceof RealGrayImage) {
				return apply((RealGrayImage) image);

				// else if (image instanceof ColorImage) return apply((ColorImage)image);
				// else if (image instanceof RealColorImage) return apply((RealColorImage)image);
			}
		} else {
			if (image instanceof GrayImage) {
				return applynw((GrayImage) image);
			} else if (image instanceof RealGrayImage) {
				return applynw((RealGrayImage) image);

				// else if (image instanceof ColorImage) return applynw((ColorImage)image);
				// else if (image instanceof RealColorImage) return applynw((RealColorImage)image);
			}
		}
		return null;
	}




}



/*--- formatting done in "My Own Convention" style on 08-08-2000 ---*/

