/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package coords;

/**
 *
 * @author Alexander The 1st
 */
public class DCoords extends Coords {

    protected Coords origin;//Used to determine the "tail" of the vector.
    //This lets us determine where the "head" of the vector is in "global" space
    //Basically just the original coords, just that rotation and such can be 
    //Based around transitioned areas, like if the vector points on a ship 
    //need to rotate around it.

    public DCoords(int x1, int y1)//If only using x, y values - for 2-D use, by general
    {
        super(x1, y1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(int x1, int y1, int z1)//If only using x, y, z values - for 3-D use, by general
    {
        super(x1, y1, z1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(int x1, int y1, int z1, int h1) {
        super(x1, y1, z1, h1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(double x1, double y1)//If only using x, y values - for 2-D use, by general
    {
        super(x1, y1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(double x1, double y1, double z1)//If only using x, y, z values - for 3-D use, by general
    {
        super(x1, y1, z1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(double x1, double y1, double z1, double h1) {
        super(x1, y1, z1);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(int[] cords)//If only using x, y values - for 2-D use, by general
    {
        super(cords);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(double[] cords)//If only using x, y values - for 2-D use, by general
    {
        super(cords);
        origin = new Coords(0, 0, 0, 1);
    }

    public DCoords(Coords coo) {
        super(coo);
        origin = new Coords(0, 0, 0, 1);
    }//End of overloading constructors
    //Well no - not quite:
    //We need a set for specifying the origin
    //For breviety sake, we're going to assume 
    //you won't need to specify each value separately 
    //for the origin - if you do, write your own constructors.

    public DCoords(int x1, int y1, Coords origin1)//If only using x, y values - for 2-D use, by general
    {
        super(x1, y1);
        origin = origin1;
    }

    public DCoords(int x1, int y1, int z1, Coords origin1)//If only using x, y, z values - for 3-D use, by general
    {
        super(x1, y1, z1);
        origin = origin1;
    }

    public DCoords(int x1, int y1, int z1, int h1, Coords origin1) {
        super(x1, y1, z1, h1);
        origin = origin1;
    }

    public DCoords(double x1, double y1, Coords origin1)//If only using x, y values - for 2-D use, by general
    {
        super(x1, y1);
        origin = origin1;
    }

    public DCoords(double x1, double y1, double z1, Coords origin1)//If only using x, y, z values - for 3-D use, by general
    {
        super(x1, y1, z1);
        origin = origin1;
    }

    public DCoords(double x1, double y1, double z1, double h1, Coords origin1) {
        super(x1, y1, z1);
        origin = origin1;
    }

    public DCoords(int[] cords, Coords origin1)//If only using x, y values - for 2-D use, by general
    {
        super(cords);
        origin = origin1;
    }

    public DCoords(double[] cords, Coords origin1)//If only using x, y values - for 2-D use, by general
    {
        super(cords);
        origin = origin1;
    }

    public DCoords(Coords coo, Coords origin1) {
        super(coo);
        origin = origin1;
    }

    /**
     * This allows you to just swap out the origin, but will leave all values as
     * if they were actually based on the origin of the new location.
     *
     * See @function transplantOrigin for the ability to reassign all values so
     * that this coordinate stays in the same global space, but with values
     * adjusted to new origin.
     *
     *
     */
    public void changeOrign(Coords origin2) {
        origin.changeAll(origin2);
    }

    /**
     * This allows you to just swap out the origin, but will leave all values as
     * if they were actually based on the origin of the new location.
     *
     * See @function changeOrigin for the ability to reassign all values so that
     * this coordinate stays in the same global space, but with values adjusted
     * to new origin.
     *
     *
     */
    public void transplantOrignLocal(Coords origin2) {
        double newX = flatten().getX();
        double newY = flatten().getY();
        double newZ = flatten().getZ();
        newX -= origin2.flatten().getX();
        newY -= origin2.flatten().getY();
        newZ -= origin2.flatten().getZ();
        this.changeAll(new Coords(newX, newY, newZ, 1));
        origin.changeAll(origin2);
    }

    /**
     * This allows you to just swap out the origin, but will leave all values as
     * if they were actually based on the origin of the new location.
     *
     * See @function changeOrigin for the ability to reassign all values so that
     * this coordinate stays in the same global space, but with values adjusted
     * to new origin.
     *
     *
     */
    public void transplantOrignGlobal(Coords origin2) {
        double newX = flattenGlobal().getX();
        double newY = flattenGlobal().getY();
        double newZ = flattenGlobal().getZ();
        newX -= origin2.flattenGlobal().getX();
        newY -= origin2.flattenGlobal().getY();
        newZ -= origin2.flattenGlobal().getZ();
        this.changeAll(new Coords(newX, newY, newZ, 1));
        origin.changeAll(origin2);
    }

    public void addToOrigin(double x1, double y1, double z1, double h1) {
        origin.addToPart(x1, "x");
        origin.addToPart(y1, "y");
        origin.addToPart(z1, "z");
        origin.addToPart(h1, "h");
    }

    public Coords flatten() {
        Coords flattened = new Coords(this.x, this.y, this.z, this.h);
        //After determining the original coords
        //We then just assume that origin is good enough as is to 
        //determine what these values are
        flattened.addToPart(origin.x, "x");
        flattened.addToPart(origin.y, "y");
        flattened.addToPart(origin.z, "z");

        return flattened;
    }

    public Coords flattenGlobal() {
        Coords flattened = new Coords(this.x, this.y, this.z, this.h);
        //After determining the original coords
        Coords originFlattened = origin.flattenGlobal();
        //We *don't* assume that the origin is good enough - we recursively 
        //flatten them until we get to the last Coords object.
        //Gets true position from (0, 0) in swing java JPanel class location
        //That is, top-left of window to location.
        flattened.addToPart(originFlattened.x, "x");
        flattened.addToPart(originFlattened.y, "y");
        flattened.addToPart(originFlattened.z, "z");

        return flattened;
    }
    
    /**
     * Lets us get the Origin of a DCoords if needing to determine 
     * the offsets based on the origin the DCoords is using.
     * Most useful for DCoords manipulation - overrides Coords.
     * 
     */
    public Coords getOrigin(){
        return this.origin;
    }
}
