package de.thdeg.greiner.superpangworld.graphics.base;

import java.util.Objects;

/**
 * Die Position eines Objekts auf einem Fenster anhand zweidimensionaler Koordinaten.
 */
public class Position implements Cloneable, Comparable<Position>{

    /** Die x-Koordinate */
    public double x;
    /** Die y-Koordinate */
    public double y;

    /**
     * Erzeugt eine Position mit den übergebenen Koordinaten.
     *
     * @param x die x-Koordinate des Objekts
     * @param y die y-Koordinate des Objekts
     */
    public Position(double x, double y) {
        this.x = x;
        this.y = y;
    }

    /**
     * Erzeugt eine Standardposition für die Koordinaten (0, 0).
     */
    public Position(){
        this(0,0);
    }

    /**
     * Veränderung der Position um einen Pixel nach links.
     */
    public void left() {
        x--;
    }

    /**
     * Veränderung der Position nach links.
     * @param pixel die Anzahl der Pixel
     */
    public void left(double pixel){
        x -= pixel;
    }

    /**
     * Veränderung der Position um einen Pixel nach rechts.
     */
    public void right() {
        x++;
    }

    /**
     * Veränderung der Position nach rechts.
     * @param pixel die Anzahl der Pixel
     */
    public void right(double pixel){
        x += pixel;
    }

    /**
     * Veränderung der Position um einen Pixel nach oben.
     */
    public void up() {
        y--;
    }

    /**
     * Veränderung der Position nach oben.
     * @param pixel die Anzahl der Pixel
     */
    public void up(double pixel){
        y -= pixel;
    }

    /**
     * Veränderung der Position um einen Pixel nach unten.
     */
    public void down() {
        y++;
    }

    /**
     * Veränderung der Position nach unten.
     * @param pixel die Anzahl der Pixel
     */
    public void down(double pixel){
        y += pixel;
    }

    /**
     * Set the position to given x and y coordinates.
     * @param x the x coordinate
     * @param y the y coordinate
     */
    public void setTo(double x, double y){
        this.x = x;
        this.y = y;
    }

    /**
     * Calculates the distance to any other position.
     *
     * @param other Position to calculate the distance to.
     * @return The distance.
     */
    public double distance(Position other) {
        return Math.sqrt(Math.pow((x - other.x), 2) + Math.pow((y - other.y), 2));
    }

    @Override
    public String toString() {
        return "Position(" + (int) Math.round(x) + ", " + (int) Math.round(y) + ')';
    }

    @Override
    public Position clone() {
        Position other = null;
        try{
            other = (Position) super.clone();
        }catch(CloneNotSupportedException ignored){
        }
        return other;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Position position = (Position) o;
        return Double.compare(position.x, x) == 0 && Double.compare(position.y, y) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }

    @Override
    public int compareTo(Position o) {
        Position p0 = new Position(0,0);
        return (int)Math.signum(this.distance(p0)-o.distance(p0));
    }
}
