package org.qw3rtrun.aub.engine.scene;

import javafx.beans.property.*;
import org.qw3rtrun.aub.engine.mixin.*;
import org.qw3rtrun.aub.engine.property.matrix.Matrix4fBinding;
import org.qw3rtrun.aub.engine.property.quaternion.QuaternionBinding;
import org.qw3rtrun.aub.engine.property.transform.Scale;
import org.qw3rtrun.aub.engine.property.transform.Translate;
import org.qw3rtrun.aub.engine.property.vector.Vector4fBinding;
import org.qw3rtrun.aub.engine.property.vector.Vector4fProperty;

import java.util.ArrayList;

import static javafx.collections.FXCollections.observableList;
import static org.qw3rtrun.aub.engine.vectmath.Vector4f.*;

public class Object implements Node, Shaped, Tangible {

    private final ObjectProperty<Object> parent = new SimpleObjectProperty<>();
    private final ListProperty<Object> childs = new SimpleListProperty<>(observableList(new ArrayList<>()));
    //.concat(ori)
    private final QuaternionBinding invertOrientation = new QuaternionBinding(
            () -> orientation.get().withA(-orientation.getA()),
            orientation
    );
    private StringProperty name = new SimpleStringProperty(super.toString());
    private final Vector4fProperty scale = new Vector4fProperty(XYZ) {
        @Override
        public java.lang.Object getBean() {
            return Object.this;
        }

        @Override
        public String getName() {
            return "ScaleBinding of " + name.get();
        }
    };
    private final Vector4fProperty rotation = new Vector4fProperty(ZERO) {
        @Override
        public java.lang.Object getBean() {
            return Object.this;
        }

        @Override
        public String getName() {
            return "Rotation of " + name.get();
        }
    };
    private final QuaternionBinding orientation = QuaternionBinding.orientation(rotation);
    private final Vector4fProperty translation = new Vector4fProperty(ZERO) {
        @Override
        public String getName() {
            return "Translation of " + name.get();
        }

        @Override
        public java.lang.Object getBean() {
            return Object.this;
        }
    };
    private final Matrix4fBinding localToAbsolute = new Translate(translation).asMatrix()
            .concat(orientation.rotationNormMatrix())
            .concat(new Scale(scale).asMatrix());
    private final Vector4fBinding invertTranslation = new Vector4fBinding(
            () -> translation.getValue().inverse(),
            translation
    );
    private final Matrix4fBinding absoluteToLocal = new Scale(scale).invert().asMatrix()
            .concat(invertOrientation.rotationNormMatrix())
            .concat(new Translate(translation).invert().asMatrix());
    private Vector4fBinding inverseScale = new Vector4fBinding(
            () -> vect(1 / scale.getValue().x, 1 / scale.getValue().y, 1 / scale.getValue().z, 2),
            scale
    );

    public StringProperty name() {
        return name;
    }

    @Override
    public ObjectProperty<Object> parent() {
        return parent;
    }

    @Override
    public ListProperty<Object> childs() {
        return childs;
    }

    @Override
    public Vector4fProperty translation() {
        return translation;
    }

    @Override
    public Vector4fProperty rotation() {
        return rotation;
    }

    @Override
    public Vector4fProperty scale() {
        return scale;
    }

    @Override
    public Matrix4fBinding localToAbsolute() {
        return localToAbsolute;
    }

    @Override
    public Matrix4fBinding absoluteToLocal() {
        return absoluteToLocal;
    }

    void pushToContext() {
        mesh().ifPresent(Mesh::push);
        material().ifPresent(Material::push);
    }

    void popFromContext() {
        mesh().ifPresent(Mesh::pop);
        material().ifPresent(Material::pop);
    }

    public void render() {
    }
}


@@ -696,16 +696,107 @@
 ible %7B%0A%0A
+    private final QuaternionBinding orientation = QuaternionBinding.orientation(rotation);%0A
     priv
@@ -984,194 +984,764 @@
     
-//.concat(ori)%0A    private final QuaternionBinding invertOrientation = new QuaternionBinding(%0A            () -%3E orientation.get().withA(-orientation.getA()),%0A            orientation%0A    
+private final Matrix4fBinding localToAbsolute = new Translate(translation).asMatrix()%0A            .concat(orientation.rotationNormMatrix())%0A            .concat(new Scale(scale).asMatrix());%0A    //.concat(ori)%0A    private final QuaternionBinding invertOrientation = new QuaternionBinding(%0A            () -%3E orientation.get().withA(-orientation.getA()),%0A            orientation%0A    );%0A    private final Vector4fBinding invertTranslation = new Vector4fBinding(%0A            () -%3E translation.getValue().inverse(),%0A            translation%0A    );%0A    private final Matrix4fBinding absoluteToLocal = new Scale(scale).invert().asMatrix()%0A            .concat(invertOrientation.rotationNormMatrix())%0A            .concat(new Translate(translation).invert().asMatrix()
 );%0A 
@@ -2415,99 +2415,8 @@
  %7D;%0A
-    private final QuaternionBinding orientation = QuaternionBinding.orientation(rotation);%0A
     
@@ -2718,578 +2718,8 @@
  %7D;%0A
-    private final Matrix4fBinding localToAbsolute = new Translate(translation).asMatrix()%0A            .concat(orientation.rotationNormMatrix())%0A            .concat(new Scale(scale).asMatrix());%0A    private final Vector4fBinding invertTranslation = new Vector4fBinding(%0A            () -%3E translation.getValue().inverse(),%0A            translation%0A    );%0A    private final Matrix4fBinding absoluteToLocal = new Scale(scale).invert().asMatrix()%0A            .concat(invertOrientation.rotationNormMatrix())%0A            .concat(new Translate(translation).invert().asMatrix());%0A
     

remove natives