# A-Frame & VWF simple scene
# Copyright 2017 Krestianstvo.org project
---
extends: http://vwf.example.com/aframe/ascene.vwf
properties:
    assets: "assets.json"
children:
    skySun:
        extends: http://vwf.example.com/aframe/aentity.vwf
        children:
            sun:
                extends: http://vwf.example.com/aframe/app-sun-component.vwf
    newSky:
        extends: http://vwf.example.com/aframe/aentity.vwf
        children:
            skyshader:
                extends: http://vwf.example.com/aframe/app-skyshader-component.vwf
    groundPlane:
        extends: http://vwf.example.com/aframe/aplane.vwf
        properties:
            height: 50
            width: 50
            repeat: "10 10"
            rotation: [-90, 0, 0]
            wireframe: false
            src: "#bg2"
    turtle:
        extends: http://vwf.example.com/aframe/asphere.vwf
        properties:
            position: [1, 1.25, -4]
            color: "#e0e014"
            radius: 0.2
            wireframe: true
            angleInRadians: 0
            iteration: 3
            angle: 60  
            stepLength: 0.5  
            rule: 'F++F++F'
            axiomF: 'F-F++F-F'
            axiomG: ''
            lsys: ''
            readyForDraw: true
        children:
            drawNode:
                extends: http://vwf.example.com/aframe/aentity.vwf
                children:
                    linepath:
                        extends: http://vwf.example.com/aframe/linepath.vwf
                        properties:
                            color: "#445447"
                            path: []
                            width: 0.02
            lsysLang:
                extends: http://vwf.example.com/ohm/node.vwf
                properties:
                    grammar:
                    semantics:
                    ohmLang: |
                        LSys { Gen<x> 
                                = ReadRule+ 
                                ReadRule 
                                = letters | symbols
                                letters  = "F" | "G" 
                                symbols  = "-" | "+" }
                methods:
                    initLang:
                        body: |
                            console.log("add operations to semantics")
                            this.addOperationLang();
                    addOperationLang:
                        body: |
                            this.semantics.addOperation('gen(x)', {
                                Gen: function(e)
                                {
                                    return e.gen(this.args.x);
                                },
                                ReadRule: function(e)
                                {
                                    return e.gen(this.args.x);
                                },
                                letters: function(_)
                                {
                                    for (var propName in this.args.x)
                                    {
                                        if (propName == this.sourceString)
                                            return this.args.x[propName]
                                    }
                                    return this.sourceString
                                },
                                symbols: function(_)
                                {
                                    return this.sourceString;
                                }
                            });
            turtleLang:
                extends: http://vwf.example.com/ohm/node.vwf
                properties:
                    grammar:
                    semantics:
                    ohmLang: |
                        Turtle {
                        Draw<x, y> 
                            = (drawLetter | turn)+ 
                        drawLetter 
                            = letter
                        turn 
                            = "+" | "-" }
                methods:
                    initLang:
                        body: |
                            console.log("add operations to semantics")
                            this.addOperationLang();
                    addOperationLang:
                        body: |
                            var turtleID = this.parent.id;
                            var self = this;
                            this.semantics.addOperation('draw(x,y)', {
                                Draw: function(e)
                                {
                                    e.draw(this.args.x, this.args.y);
                                },
                                drawLetter: function(e)
                                {
                                    //vwf_view.kernel.callMethod(turtleID, 'goForward', [this.args.x]);
                                    self.parent.goForward(this.args.x);
                                },
                                turn: function(e)
                                {
                                    if (this.sourceString == "+")
                                        //vwf_view.kernel.callMethod(turtleID, 'turn', [this.args.y]);
                                        self.parent.turn(this.args.y);
                                    if (this.sourceString == "-")
                                        //vwf_view.kernel.callMethod(turtleID, 'turn', [-1 * this.args.y]);
                                        self.parent.turn(-1*this.args.y);
                                    }
                            });
        methods:
            parseLSys: |
                var str = this.rule;
                var axioms = {"F": this.axiomF, "G": this.axiomG};
                for (var i = 1; i < this.iteration; i++)
                {
                    var match = this.lsysLang.grammar.match(str, 'Gen<"y">');
                    if (match.succeeded()){
                    var res = this.lsysLang.semantics(match).gen(axioms);
                    str = res.join("");
                    }
                }
                console.log(str);
                this.lsys = str;
            makeLSys: |
                if (this.readyForDraw){
                this.drawNode.position = [0, 0, 0]
                this.angleInRadians = 0;
                this.drawNode.linepath.path = [];
                this.parseLSys();
                this.drawLSys();
                this.drawNode.position = [0, 0, 0]
                }
            drawLSys: |
                var match = this.turtleLang.grammar.match(this.lsys, 'Draw<"1","1">');
                if (match.succeeded()){
                    var res = this.turtleLang.semantics(match).draw(this.stepLength, this.angle);
                }
            turn:
                parameters:
                    - angle
                body: |
                    var angle0 = this.angleInRadians;
                    var targetAngle = angle * Math.PI / 180.0;
                    this.angleInRadians = angle0 + targetAngle;
            goForward:
                parameters:
                    - step
                body: |
                    let pos = Object.assign({}, this.drawNode.position);
                    var x0 = pos.x;
                    var y0 = pos.y;
                    var xx = Math.sin(this.angleInRadians);
                    var yy = Math.cos(this.angleInRadians);
                    let startPosition = Object.assign({}, this.drawNode.position);
                    let endPosition = {x: x0 + step * xx, y: y0 + step * yy, z: pos.z};
                    var drawPath = this.drawNode.linepath.path;
                    drawPath.push(startPosition);
                    drawPath.push(endPosition);
                    vwf_view.kernel.setProperty(this.drawNode.linepath.id, 'path', drawPath);
                    this.drawNode.position = endPosition;
            setTurtleParams:
                parameters:
                    - val
                body: |
                    this.readyForDraw = false;
                    val.forEach(el => {
                        this[el[0]] = el[1]
                    })
                    this.readyForDraw = true;
                    this.makeLSys();
            initialize:
                body: |
                    //this.redrawEvent = function(){this.makeLSys()}
                    vwf_view.kernel.callMethod(this.id, "makeLSys");
                    console.log("initialising turtle");
methods:
  initialize:
    body: |
        console.log("initialising scene");
  drawLSys1: |
    this.turtle.makeLSys()
  testTurtle: |
    this.turtle.goForward(1);
    this.turtle.goForward(1);
    this.turtle.turn(45);
    this.turtle.goForward(1);
    this.turtle.goForward(1);
    this.turtle.turn(45);
    this.turtle.goForward(1);